├── .gitignore ├── Job Queue System.excalidraw ├── LICENSE ├── docker-compose.yml ├── package-lock.json ├── package.json ├── src ├── index.ts └── job-queue │ ├── queue.ts │ ├── redis-adapter.ts │ ├── types.ts │ └── worker.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /Job Queue System.excalidraw: -------------------------------------------------------------------------------- 1 | { 2 | "type": "excalidraw", 3 | "version": 2, 4 | "source": "https://excalidraw.com", 5 | "elements": [ 6 | { 7 | "id": "i9Xjx6UBH_RSvC8R2zNsa", 8 | "type": "rectangle", 9 | "x": 778.7380634876225, 10 | "y": -24959.94965454321, 11 | "width": 148.1946876835549, 12 | "height": 498.9221222677734, 13 | "angle": 0, 14 | "strokeColor": "#1e1e1e", 15 | "backgroundColor": "#ffffff", 16 | "fillStyle": "solid", 17 | "strokeWidth": 1, 18 | "strokeStyle": "solid", 19 | "roughness": 0, 20 | "opacity": 100, 21 | "groupIds": [], 22 | "frameId": null, 23 | "index": "a0", 24 | "roundness": { 25 | "type": 3 26 | }, 27 | "seed": 253927363, 28 | "version": 227, 29 | "versionNonce": 1339270421, 30 | "isDeleted": false, 31 | "boundElements": [ 32 | { 33 | "id": "piDtF-ZVX-GCg8TXbwwXV", 34 | "type": "arrow" 35 | }, 36 | { 37 | "id": "klw1pQs7B0t1ULadFCyxH", 38 | "type": "arrow" 39 | }, 40 | { 41 | "id": "aFu4VA0xw6Xlo6hzRs3my", 42 | "type": "arrow" 43 | } 44 | ], 45 | "updated": 1744314194453, 46 | "link": null, 47 | "locked": false 48 | }, 49 | { 50 | "id": "4sZrhwwXRWP-iy2YkiYY5", 51 | "type": "ellipse", 52 | "x": 1088.7118388288177, 53 | "y": -24803.110279100307, 54 | "width": 190.1832013711578, 55 | "height": 142.01990903007027, 56 | "angle": 0, 57 | "strokeColor": "#1e1e1e", 58 | "backgroundColor": "#ffffff", 59 | "fillStyle": "solid", 60 | "strokeWidth": 1, 61 | "strokeStyle": "solid", 62 | "roughness": 0, 63 | "opacity": 100, 64 | "groupIds": [], 65 | "frameId": null, 66 | "index": "aA", 67 | "roundness": { 68 | "type": 2 69 | }, 70 | "seed": 1700016227, 71 | "version": 139, 72 | "versionNonce": 335714197, 73 | "isDeleted": false, 74 | "boundElements": [ 75 | { 76 | "type": "text", 77 | "id": "GEi4q0LdlKDX-g1UkjxxM" 78 | }, 79 | { 80 | "id": "piDtF-ZVX-GCg8TXbwwXV", 81 | "type": "arrow" 82 | } 83 | ], 84 | "updated": 1744314194453, 85 | "link": null, 86 | "locked": false 87 | }, 88 | { 89 | "id": "GEi4q0LdlKDX-g1UkjxxM", 90 | "type": "text", 91 | "x": 1151.6156078048566, 92 | "y": -24744.811944954603, 93 | "width": 63.89583206176758, 94 | "height": 25, 95 | "angle": 0, 96 | "strokeColor": "#1e1e1e", 97 | "backgroundColor": "#ffffff", 98 | "fillStyle": "solid", 99 | "strokeWidth": 1, 100 | "strokeStyle": "solid", 101 | "roughness": 0, 102 | "opacity": 100, 103 | "groupIds": [], 104 | "frameId": null, 105 | "index": "aB", 106 | "roundness": null, 107 | "seed": 472109827, 108 | "version": 99, 109 | "versionNonce": 188080067, 110 | "isDeleted": false, 111 | "boundElements": [], 112 | "updated": 1743706935595, 113 | "link": null, 114 | "locked": false, 115 | "text": "Worker", 116 | "fontSize": 20, 117 | "fontFamily": 1, 118 | "textAlign": "center", 119 | "verticalAlign": "middle", 120 | "containerId": "4sZrhwwXRWP-iy2YkiYY5", 121 | "originalText": "Worker", 122 | "autoResize": true, 123 | "lineHeight": 1.25 124 | }, 125 | { 126 | "id": "k2nvF-mFt5gOqM3s_rmKm", 127 | "type": "text", 128 | "x": 779.3711425395553, 129 | "y": -25016.86012245199, 130 | "width": 128.9166717529297, 131 | "height": 25, 132 | "angle": 0, 133 | "strokeColor": "#1e1e1e", 134 | "backgroundColor": "#ffffff", 135 | "fillStyle": "solid", 136 | "strokeWidth": 1, 137 | "strokeStyle": "solid", 138 | "roughness": 0, 139 | "opacity": 100, 140 | "groupIds": [], 141 | "frameId": null, 142 | "index": "aC", 143 | "roundness": null, 144 | "seed": 267760451, 145 | "version": 157, 146 | "versionNonce": 631303107, 147 | "isDeleted": false, 148 | "boundElements": [ 149 | { 150 | "id": "klw1pQs7B0t1ULadFCyxH", 151 | "type": "arrow" 152 | } 153 | ], 154 | "updated": 1743707235187, 155 | "link": null, 156 | "locked": false, 157 | "text": "Active Queue", 158 | "fontSize": 20, 159 | "fontFamily": 1, 160 | "textAlign": "left", 161 | "verticalAlign": "top", 162 | "containerId": null, 163 | "originalText": "Active Queue", 164 | "autoResize": true, 165 | "lineHeight": 1.25 166 | }, 167 | { 168 | "id": "ShSvfykLRNJLQJG0NLdhr", 169 | "type": "rectangle", 170 | "x": -29.92238416325671, 171 | "y": -24946.25828675931, 172 | "width": 148.1946876835549, 173 | "height": 498.9221222677734, 174 | "angle": 0, 175 | "strokeColor": "#1e1e1e", 176 | "backgroundColor": "#ffffff", 177 | "fillStyle": "solid", 178 | "strokeWidth": 1, 179 | "strokeStyle": "solid", 180 | "roughness": 0, 181 | "opacity": 100, 182 | "groupIds": [], 183 | "frameId": null, 184 | "index": "aD", 185 | "roundness": { 186 | "type": 3 187 | }, 188 | "seed": 582836557, 189 | "version": 544, 190 | "versionNonce": 1835605531, 191 | "isDeleted": false, 192 | "boundElements": [ 193 | { 194 | "id": "n-BkhaViuUQSc2vLzzxAu", 195 | "type": "arrow" 196 | }, 197 | { 198 | "id": "aFu4VA0xw6Xlo6hzRs3my", 199 | "type": "arrow" 200 | } 201 | ], 202 | "updated": 1744314194453, 203 | "link": null, 204 | "locked": false 205 | }, 206 | { 207 | "id": "UQ__f-A1vtlHLq7Lw1cpb", 208 | "type": "text", 209 | "x": -20.283470417588944, 210 | "y": -24989.01471747205, 211 | "width": 125.3125, 212 | "height": 25, 213 | "angle": 0, 214 | "strokeColor": "#1e1e1e", 215 | "backgroundColor": "#ffffff", 216 | "fillStyle": "solid", 217 | "strokeWidth": 1, 218 | "strokeStyle": "solid", 219 | "roughness": 0, 220 | "opacity": 100, 221 | "groupIds": [], 222 | "frameId": null, 223 | "index": "aE", 224 | "roundness": null, 225 | "seed": 1023133037, 226 | "version": 268, 227 | "versionNonce": 139794093, 228 | "isDeleted": false, 229 | "boundElements": [], 230 | "updated": 1743707259963, 231 | "link": null, 232 | "locked": false, 233 | "text": "Delayed List", 234 | "fontSize": 20, 235 | "fontFamily": 1, 236 | "textAlign": "left", 237 | "verticalAlign": "top", 238 | "containerId": null, 239 | "originalText": "Delayed List", 240 | "autoResize": true, 241 | "lineHeight": 1.25 242 | }, 243 | { 244 | "id": "l_qc6ooJ61Jqp3F4Sc144", 245 | "type": "rectangle", 246 | "x": 802.2022412147815, 247 | "y": -24520.922878147772, 248 | "width": 104.353768665801, 249 | "height": 35, 250 | "angle": 0, 251 | "strokeColor": "#1e1e1e", 252 | "backgroundColor": "#ffffff", 253 | "fillStyle": "solid", 254 | "strokeWidth": 1, 255 | "strokeStyle": "solid", 256 | "roughness": 0, 257 | "opacity": 100, 258 | "groupIds": [], 259 | "frameId": null, 260 | "index": "aF", 261 | "roundness": { 262 | "type": 3 263 | }, 264 | "seed": 1957368611, 265 | "version": 249, 266 | "versionNonce": 1861527797, 267 | "isDeleted": false, 268 | "boundElements": [ 269 | { 270 | "type": "text", 271 | "id": "6rApY4NvazZhxLm1T56bv" 272 | } 273 | ], 274 | "updated": 1744314155120, 275 | "link": null, 276 | "locked": false 277 | }, 278 | { 279 | "id": "6rApY4NvazZhxLm1T56bv", 280 | "type": "text", 281 | "x": 837.410375547682, 282 | "y": -24515.922878147772, 283 | "width": 33.9375, 284 | "height": 25, 285 | "angle": 0, 286 | "strokeColor": "#1e1e1e", 287 | "backgroundColor": "#ffffff", 288 | "fillStyle": "solid", 289 | "strokeWidth": 1, 290 | "strokeStyle": "solid", 291 | "roughness": 0, 292 | "opacity": 100, 293 | "groupIds": [], 294 | "frameId": null, 295 | "index": "aG", 296 | "roundness": null, 297 | "seed": 1792015373, 298 | "version": 221, 299 | "versionNonce": 650005723, 300 | "isDeleted": false, 301 | "boundElements": [], 302 | "updated": 1744314155120, 303 | "link": null, 304 | "locked": false, 305 | "text": "Job", 306 | "fontSize": 20, 307 | "fontFamily": 1, 308 | "textAlign": "center", 309 | "verticalAlign": "middle", 310 | "containerId": "l_qc6ooJ61Jqp3F4Sc144", 311 | "originalText": "Job", 312 | "autoResize": true, 313 | "lineHeight": 1.25 314 | }, 315 | { 316 | "id": "rDx-WXMNwQ8tKY7mLPjXV", 317 | "type": "rectangle", 318 | "x": 798.806117666349, 319 | "y": -24569.91428696838, 320 | "width": 104.353768665801, 321 | "height": 35, 322 | "angle": 0, 323 | "strokeColor": "#1e1e1e", 324 | "backgroundColor": "#ffffff", 325 | "fillStyle": "solid", 326 | "strokeWidth": 1, 327 | "strokeStyle": "solid", 328 | "roughness": 0, 329 | "opacity": 100, 330 | "groupIds": [], 331 | "frameId": null, 332 | "index": "aH", 333 | "roundness": { 334 | "type": 3 335 | }, 336 | "seed": 968965763, 337 | "version": 97, 338 | "versionNonce": 850352963, 339 | "isDeleted": false, 340 | "boundElements": [ 341 | { 342 | "type": "text", 343 | "id": "BgW4xPzRYcVtBdJ5Ja8HI" 344 | } 345 | ], 346 | "updated": 1743706992926, 347 | "link": null, 348 | "locked": false 349 | }, 350 | { 351 | "id": "BgW4xPzRYcVtBdJ5Ja8HI", 352 | "type": "text", 353 | "x": 834.0142519992495, 354 | "y": -24564.91428696838, 355 | "width": 33.9375, 356 | "height": 25, 357 | "angle": 0, 358 | "strokeColor": "#1e1e1e", 359 | "backgroundColor": "#ffffff", 360 | "fillStyle": "solid", 361 | "strokeWidth": 1, 362 | "strokeStyle": "solid", 363 | "roughness": 0, 364 | "opacity": 100, 365 | "groupIds": [], 366 | "frameId": null, 367 | "index": "aI", 368 | "roundness": null, 369 | "seed": 1018983971, 370 | "version": 69, 371 | "versionNonce": 1397291747, 372 | "isDeleted": false, 373 | "boundElements": [], 374 | "updated": 1743706992926, 375 | "link": null, 376 | "locked": false, 377 | "text": "Job", 378 | "fontSize": 20, 379 | "fontFamily": 1, 380 | "textAlign": "center", 381 | "verticalAlign": "middle", 382 | "containerId": "rDx-WXMNwQ8tKY7mLPjXV", 383 | "originalText": "Job", 384 | "autoResize": true, 385 | "lineHeight": 1.25 386 | }, 387 | { 388 | "id": "CBrr8ePAVspK3IeUfkEhu", 389 | "type": "rectangle", 390 | "x": 798.806117666349, 391 | "y": -24619.929984639624, 392 | "width": 104.353768665801, 393 | "height": 35, 394 | "angle": 0, 395 | "strokeColor": "#1e1e1e", 396 | "backgroundColor": "#ffffff", 397 | "fillStyle": "solid", 398 | "strokeWidth": 1, 399 | "strokeStyle": "solid", 400 | "roughness": 0, 401 | "opacity": 100, 402 | "groupIds": [], 403 | "frameId": null, 404 | "index": "aJ", 405 | "roundness": { 406 | "type": 3 407 | }, 408 | "seed": 617793933, 409 | "version": 132, 410 | "versionNonce": 1972544077, 411 | "isDeleted": false, 412 | "boundElements": [ 413 | { 414 | "type": "text", 415 | "id": "yxQ3bU8NgBeAwPV3vD04m" 416 | } 417 | ], 418 | "updated": 1743706994877, 419 | "link": null, 420 | "locked": false 421 | }, 422 | { 423 | "id": "yxQ3bU8NgBeAwPV3vD04m", 424 | "type": "text", 425 | "x": 834.0142519992495, 426 | "y": -24614.929984639624, 427 | "width": 33.9375, 428 | "height": 25, 429 | "angle": 0, 430 | "strokeColor": "#1e1e1e", 431 | "backgroundColor": "#ffffff", 432 | "fillStyle": "solid", 433 | "strokeWidth": 1, 434 | "strokeStyle": "solid", 435 | "roughness": 0, 436 | "opacity": 100, 437 | "groupIds": [], 438 | "frameId": null, 439 | "index": "aK", 440 | "roundness": null, 441 | "seed": 1882984429, 442 | "version": 104, 443 | "versionNonce": 1963118765, 444 | "isDeleted": false, 445 | "boundElements": [], 446 | "updated": 1743706994877, 447 | "link": null, 448 | "locked": false, 449 | "text": "Job", 450 | "fontSize": 20, 451 | "fontFamily": 1, 452 | "textAlign": "center", 453 | "verticalAlign": "middle", 454 | "containerId": "CBrr8ePAVspK3IeUfkEhu", 455 | "originalText": "Job", 456 | "autoResize": true, 457 | "lineHeight": 1.25 458 | }, 459 | { 460 | "id": "sERbui3eSxS1UiJd26jRl", 461 | "type": "rectangle", 462 | "x": 796.9536652263755, 463 | "y": -24670.563197864067, 464 | "width": 104.353768665801, 465 | "height": 35, 466 | "angle": 0, 467 | "strokeColor": "#1e1e1e", 468 | "backgroundColor": "#ffffff", 469 | "fillStyle": "solid", 470 | "strokeWidth": 1, 471 | "strokeStyle": "solid", 472 | "roughness": 0, 473 | "opacity": 100, 474 | "groupIds": [], 475 | "frameId": null, 476 | "index": "aL", 477 | "roundness": { 478 | "type": 3 479 | }, 480 | "seed": 1734086723, 481 | "version": 196, 482 | "versionNonce": 2126794971, 483 | "isDeleted": false, 484 | "boundElements": [ 485 | { 486 | "type": "text", 487 | "id": "jqFKamgUsqHZ0URhEsnBc" 488 | } 489 | ], 490 | "updated": 1744314199112, 491 | "link": null, 492 | "locked": false 493 | }, 494 | { 495 | "id": "jqFKamgUsqHZ0URhEsnBc", 496 | "type": "text", 497 | "x": 832.161799559276, 498 | "y": -24665.563197864067, 499 | "width": 33.9375, 500 | "height": 25, 501 | "angle": 0, 502 | "strokeColor": "#1e1e1e", 503 | "backgroundColor": "#ffffff", 504 | "fillStyle": "solid", 505 | "strokeWidth": 1, 506 | "strokeStyle": "solid", 507 | "roughness": 0, 508 | "opacity": 100, 509 | "groupIds": [], 510 | "frameId": null, 511 | "index": "aM", 512 | "roundness": null, 513 | "seed": 446107619, 514 | "version": 168, 515 | "versionNonce": 2064252501, 516 | "isDeleted": false, 517 | "boundElements": [], 518 | "updated": 1744314199112, 519 | "link": null, 520 | "locked": false, 521 | "text": "Job", 522 | "fontSize": 20, 523 | "fontFamily": 1, 524 | "textAlign": "center", 525 | "verticalAlign": "middle", 526 | "containerId": "sERbui3eSxS1UiJd26jRl", 527 | "originalText": "Job", 528 | "autoResize": true, 529 | "lineHeight": 1.25 530 | }, 531 | { 532 | "id": "h8RQpLB06u6kOAn-LIfLv", 533 | "type": "rectangle", 534 | "x": 798.1886021131428, 535 | "y": -24718.72644309533, 536 | "width": 104.353768665801, 537 | "height": 35, 538 | "angle": 0, 539 | "strokeColor": "#1e1e1e", 540 | "backgroundColor": "#ffffff", 541 | "fillStyle": "solid", 542 | "strokeWidth": 1, 543 | "strokeStyle": "solid", 544 | "roughness": 0, 545 | "opacity": 100, 546 | "groupIds": [], 547 | "frameId": null, 548 | "index": "aN", 549 | "roundness": { 550 | "type": 3 551 | }, 552 | "seed": 1452500845, 553 | "version": 230, 554 | "versionNonce": 1648454581, 555 | "isDeleted": false, 556 | "boundElements": [ 557 | { 558 | "type": "text", 559 | "id": "hj7Ro0dYxm_jcIkfmb5fN" 560 | } 561 | ], 562 | "updated": 1744314199269, 563 | "link": null, 564 | "locked": false 565 | }, 566 | { 567 | "id": "hj7Ro0dYxm_jcIkfmb5fN", 568 | "type": "text", 569 | "x": 833.3967364460433, 570 | "y": -24713.72644309533, 571 | "width": 33.9375, 572 | "height": 25, 573 | "angle": 0, 574 | "strokeColor": "#1e1e1e", 575 | "backgroundColor": "#ffffff", 576 | "fillStyle": "solid", 577 | "strokeWidth": 1, 578 | "strokeStyle": "solid", 579 | "roughness": 0, 580 | "opacity": 100, 581 | "groupIds": [], 582 | "frameId": null, 583 | "index": "aO", 584 | "roundness": null, 585 | "seed": 1072558541, 586 | "version": 202, 587 | "versionNonce": 1839470107, 588 | "isDeleted": false, 589 | "boundElements": [], 590 | "updated": 1744314199269, 591 | "link": null, 592 | "locked": false, 593 | "text": "Job", 594 | "fontSize": 20, 595 | "fontFamily": 1, 596 | "textAlign": "center", 597 | "verticalAlign": "middle", 598 | "containerId": "h8RQpLB06u6kOAn-LIfLv", 599 | "originalText": "Job", 600 | "autoResize": true, 601 | "lineHeight": 1.25 602 | }, 603 | { 604 | "id": "T4SSXmRvtplCTR6TXD0WC", 605 | "type": "rectangle", 606 | "x": 797.5711336697591, 607 | "y": -24772.44704564651, 608 | "width": 104.353768665801, 609 | "height": 35, 610 | "angle": 0, 611 | "strokeColor": "#1e1e1e", 612 | "backgroundColor": "#ffffff", 613 | "fillStyle": "solid", 614 | "strokeWidth": 1, 615 | "strokeStyle": "solid", 616 | "roughness": 0, 617 | "opacity": 100, 618 | "groupIds": [], 619 | "frameId": null, 620 | "index": "aP", 621 | "roundness": { 622 | "type": 3 623 | }, 624 | "seed": 964871683, 625 | "version": 268, 626 | "versionNonce": 848337595, 627 | "isDeleted": false, 628 | "boundElements": [ 629 | { 630 | "type": "text", 631 | "id": "Z8UzkLpW-VTjaC2cHHNz9" 632 | } 633 | ], 634 | "updated": 1744314199425, 635 | "link": null, 636 | "locked": false 637 | }, 638 | { 639 | "id": "Z8UzkLpW-VTjaC2cHHNz9", 640 | "type": "text", 641 | "x": 832.7792680026596, 642 | "y": -24767.44704564651, 643 | "width": 33.9375, 644 | "height": 25, 645 | "angle": 0, 646 | "strokeColor": "#1e1e1e", 647 | "backgroundColor": "#ffffff", 648 | "fillStyle": "solid", 649 | "strokeWidth": 1, 650 | "strokeStyle": "solid", 651 | "roughness": 0, 652 | "opacity": 100, 653 | "groupIds": [], 654 | "frameId": null, 655 | "index": "aQ", 656 | "roundness": null, 657 | "seed": 1776356771, 658 | "version": 240, 659 | "versionNonce": 1885848181, 660 | "isDeleted": false, 661 | "boundElements": [], 662 | "updated": 1744314199425, 663 | "link": null, 664 | "locked": false, 665 | "text": "Job", 666 | "fontSize": 20, 667 | "fontFamily": 1, 668 | "textAlign": "center", 669 | "verticalAlign": "middle", 670 | "containerId": "T4SSXmRvtplCTR6TXD0WC", 671 | "originalText": "Job", 672 | "autoResize": true, 673 | "lineHeight": 1.25 674 | }, 675 | { 676 | "id": "piDtF-ZVX-GCg8TXbwwXV", 677 | "type": "arrow", 678 | "x": 877.2154907165395, 679 | "y": -24456.02753227543, 680 | "width": 306.48794879785714, 681 | "height": 235.06287705975046, 682 | "angle": 0, 683 | "strokeColor": "#1e1e1e", 684 | "backgroundColor": "#ffffff", 685 | "fillStyle": "solid", 686 | "strokeWidth": 1, 687 | "strokeStyle": "solid", 688 | "roughness": 0, 689 | "opacity": 100, 690 | "groupIds": [], 691 | "frameId": null, 692 | "index": "aR", 693 | "roundness": null, 694 | "seed": 1485794349, 695 | "version": 523, 696 | "versionNonce": 2029642037, 697 | "isDeleted": false, 698 | "boundElements": [ 699 | { 700 | "type": "text", 701 | "id": "fJvMGVGaTz0Kj2SxFWWFK" 702 | } 703 | ], 704 | "updated": 1744314194454, 705 | "link": null, 706 | "locked": false, 707 | "points": [ 708 | [ 709 | 0, 710 | 0 711 | ], 712 | [ 713 | 0, 714 | 34.99999999999636 715 | ], 716 | [ 717 | 306.48794879785714, 718 | 34.99999999999636 719 | ], 720 | [ 721 | 306.48794879785714, 722 | -200.0628770597541 723 | ] 724 | ], 725 | "lastCommittedPoint": null, 726 | "startBinding": { 727 | "elementId": "i9Xjx6UBH_RSvC8R2zNsa", 728 | "focus": 0.8119002872294115, 729 | "gap": 4.322337990925007, 730 | "fixedPoint": [ 731 | 0.6645138821655954, 732 | 1.0100216041278685 733 | ] 734 | }, 735 | "endBinding": { 736 | "elementId": "4sZrhwwXRWP-iy2YkiYY5", 737 | "focus": 0.001051617590582116, 738 | "gap": 4.999998516511315, 739 | "fixedPoint": [ 740 | 0.4994741912046966, 741 | 1.0352060550467774 742 | ] 743 | }, 744 | "startArrowhead": null, 745 | "endArrowhead": "arrow", 746 | "elbowed": true, 747 | "fixedSegments": null, 748 | "startIsSpecial": null, 749 | "endIsSpecial": null 750 | }, 751 | { 752 | "id": "fJvMGVGaTz0Kj2SxFWWFK", 753 | "type": "text", 754 | "x": 966.146965115468, 755 | "y": -24433.527532275435, 756 | "width": 128.625, 757 | "height": 25, 758 | "angle": 0, 759 | "strokeColor": "#1e1e1e", 760 | "backgroundColor": "#ffffff", 761 | "fillStyle": "solid", 762 | "strokeWidth": 1, 763 | "strokeStyle": "solid", 764 | "roughness": 0, 765 | "opacity": 100, 766 | "groupIds": [], 767 | "frameId": null, 768 | "index": "aRV", 769 | "roundness": null, 770 | "seed": 1257433869, 771 | "version": 14, 772 | "versionNonce": 672178253, 773 | "isDeleted": false, 774 | "boundElements": [], 775 | "updated": 1743707382724, 776 | "link": null, 777 | "locked": false, 778 | "text": "Get next job", 779 | "fontSize": 20, 780 | "fontFamily": 1, 781 | "textAlign": "center", 782 | "verticalAlign": "middle", 783 | "containerId": "piDtF-ZVX-GCg8TXbwwXV", 784 | "originalText": "Get next job", 785 | "autoResize": true, 786 | "lineHeight": 1.25 787 | }, 788 | { 789 | "id": "-p8_3tAaAqGLJWACmUzBc", 790 | "type": "rectangle", 791 | "x": -13.25050064278554, 792 | "y": -24524.520938881145, 793 | "width": 112.38099975925604, 794 | "height": 60, 795 | "angle": 0, 796 | "strokeColor": "#1e1e1e", 797 | "backgroundColor": "#ffffff", 798 | "fillStyle": "solid", 799 | "strokeWidth": 1, 800 | "strokeStyle": "solid", 801 | "roughness": 0, 802 | "opacity": 100, 803 | "groupIds": [], 804 | "frameId": null, 805 | "index": "aS", 806 | "roundness": { 807 | "type": 3 808 | }, 809 | "seed": 1091963661, 810 | "version": 215, 811 | "versionNonce": 70760717, 812 | "isDeleted": false, 813 | "boundElements": [ 814 | { 815 | "type": "text", 816 | "id": "sPPCNEiP2iFXSy06O7IQF" 817 | } 818 | ], 819 | "updated": 1743707259963, 820 | "link": null, 821 | "locked": false 822 | }, 823 | { 824 | "id": "sPPCNEiP2iFXSy06O7IQF", 825 | "type": "text", 826 | "x": 14.83583320595875, 827 | "y": -24519.520938881145, 828 | "width": 56.20833206176758, 829 | "height": 50, 830 | "angle": 0, 831 | "strokeColor": "#1e1e1e", 832 | "backgroundColor": "#ffffff", 833 | "fillStyle": "solid", 834 | "strokeWidth": 1, 835 | "strokeStyle": "solid", 836 | "roughness": 0, 837 | "opacity": 100, 838 | "groupIds": [], 839 | "frameId": null, 840 | "index": "aT", 841 | "roundness": null, 842 | "seed": 787753581, 843 | "version": 180, 844 | "versionNonce": 72814445, 845 | "isDeleted": false, 846 | "boundElements": [], 847 | "updated": 1743707259963, 848 | "link": null, 849 | "locked": false, 850 | "text": "Date\nJobId", 851 | "fontSize": 20, 852 | "fontFamily": 1, 853 | "textAlign": "center", 854 | "verticalAlign": "middle", 855 | "containerId": "-p8_3tAaAqGLJWACmUzBc", 856 | "originalText": "Date\nJobId", 857 | "autoResize": true, 858 | "lineHeight": 1.25 859 | }, 860 | { 861 | "id": "owQQodC5ugpVnC1Kbsyv3", 862 | "type": "rectangle", 863 | "x": -14.485413974641745, 864 | "y": -24599.596841895487, 865 | "width": 112.38099975925604, 866 | "height": 60, 867 | "angle": 0, 868 | "strokeColor": "#1e1e1e", 869 | "backgroundColor": "#ffffff", 870 | "fillStyle": "solid", 871 | "strokeWidth": 1, 872 | "strokeStyle": "solid", 873 | "roughness": 0, 874 | "opacity": 100, 875 | "groupIds": [], 876 | "frameId": null, 877 | "index": "aU", 878 | "roundness": { 879 | "type": 3 880 | }, 881 | "seed": 1086820269, 882 | "version": 284, 883 | "versionNonce": 1190959565, 884 | "isDeleted": false, 885 | "boundElements": [ 886 | { 887 | "type": "text", 888 | "id": "WMOfrcdFFmjuau0xJseyG" 889 | } 890 | ], 891 | "updated": 1743707259963, 892 | "link": null, 893 | "locked": false 894 | }, 895 | { 896 | "id": "WMOfrcdFFmjuau0xJseyG", 897 | "type": "text", 898 | "x": 13.60091987410243, 899 | "y": -24594.596841895487, 900 | "width": 56.20833206176758, 901 | "height": 50, 902 | "angle": 0, 903 | "strokeColor": "#1e1e1e", 904 | "backgroundColor": "#ffffff", 905 | "fillStyle": "solid", 906 | "strokeWidth": 1, 907 | "strokeStyle": "solid", 908 | "roughness": 0, 909 | "opacity": 100, 910 | "groupIds": [], 911 | "frameId": null, 912 | "index": "aV", 913 | "roundness": null, 914 | "seed": 1509102093, 915 | "version": 250, 916 | "versionNonce": 88201261, 917 | "isDeleted": false, 918 | "boundElements": [], 919 | "updated": 1743707259963, 920 | "link": null, 921 | "locked": false, 922 | "text": "Date\nJobId", 923 | "fontSize": 20, 924 | "fontFamily": 1, 925 | "textAlign": "center", 926 | "verticalAlign": "middle", 927 | "containerId": "owQQodC5ugpVnC1Kbsyv3", 928 | "originalText": "Date\nJobId", 929 | "autoResize": true, 930 | "lineHeight": 1.25 931 | }, 932 | { 933 | "id": "i97FEBh6Nx373IgriyTpY", 934 | "type": "rectangle", 935 | "x": -13.86794553125793, 936 | "y": -24673.694138627445, 937 | "width": 112.38099975925604, 938 | "height": 60, 939 | "angle": 0, 940 | "strokeColor": "#1e1e1e", 941 | "backgroundColor": "#ffffff", 942 | "fillStyle": "solid", 943 | "strokeWidth": 1, 944 | "strokeStyle": "solid", 945 | "roughness": 0, 946 | "opacity": 100, 947 | "groupIds": [], 948 | "frameId": null, 949 | "index": "aW", 950 | "roundness": { 951 | "type": 3 952 | }, 953 | "seed": 757267939, 954 | "version": 335, 955 | "versionNonce": 420498061, 956 | "isDeleted": false, 957 | "boundElements": [ 958 | { 959 | "type": "text", 960 | "id": "78iV3T0s7ByaHb5xxMZiv" 961 | } 962 | ], 963 | "updated": 1743707259963, 964 | "link": null, 965 | "locked": false 966 | }, 967 | { 968 | "id": "78iV3T0s7ByaHb5xxMZiv", 969 | "type": "text", 970 | "x": 14.218388317486244, 971 | "y": -24668.694138627445, 972 | "width": 56.20833206176758, 973 | "height": 50, 974 | "angle": 0, 975 | "strokeColor": "#1e1e1e", 976 | "backgroundColor": "#ffffff", 977 | "fillStyle": "solid", 978 | "strokeWidth": 1, 979 | "strokeStyle": "solid", 980 | "roughness": 0, 981 | "opacity": 100, 982 | "groupIds": [], 983 | "frameId": null, 984 | "index": "aX", 985 | "roundness": null, 986 | "seed": 275728771, 987 | "version": 302, 988 | "versionNonce": 1663135981, 989 | "isDeleted": false, 990 | "boundElements": [], 991 | "updated": 1743707259963, 992 | "link": null, 993 | "locked": false, 994 | "text": "Date\nJobId", 995 | "fontSize": 20, 996 | "fontFamily": 1, 997 | "textAlign": "center", 998 | "verticalAlign": "middle", 999 | "containerId": "i97FEBh6Nx373IgriyTpY", 1000 | "originalText": "Date\nJobId", 1001 | "autoResize": true, 1002 | "lineHeight": 1.25 1003 | }, 1004 | { 1005 | "id": "pUVgtk82pdH0sP6l3GmX8", 1006 | "type": "rectangle", 1007 | "x": -15.720397971231307, 1008 | "y": -24747.79148246922, 1009 | "width": 112.38099975925604, 1010 | "height": 60, 1011 | "angle": 0, 1012 | "strokeColor": "#1e1e1e", 1013 | "backgroundColor": "#ffffff", 1014 | "fillStyle": "solid", 1015 | "strokeWidth": 1, 1016 | "strokeStyle": "solid", 1017 | "roughness": 0, 1018 | "opacity": 100, 1019 | "groupIds": [], 1020 | "frameId": null, 1021 | "index": "aY", 1022 | "roundness": { 1023 | "type": 3 1024 | }, 1025 | "seed": 133147661, 1026 | "version": 391, 1027 | "versionNonce": 1793290555, 1028 | "isDeleted": false, 1029 | "boundElements": [ 1030 | { 1031 | "id": "sy7Bg36rKbVGqkT5S9Awq", 1032 | "type": "text" 1033 | } 1034 | ], 1035 | "updated": 1744314592984, 1036 | "link": null, 1037 | "locked": false 1038 | }, 1039 | { 1040 | "id": "sy7Bg36rKbVGqkT5S9Awq", 1041 | "type": "text", 1042 | "x": 12.365935877512925, 1043 | "y": -24742.79148246922, 1044 | "width": 56.20833206176758, 1045 | "height": 50, 1046 | "angle": 0, 1047 | "strokeColor": "#1e1e1e", 1048 | "backgroundColor": "#ffffff", 1049 | "fillStyle": "solid", 1050 | "strokeWidth": 1, 1051 | "strokeStyle": "solid", 1052 | "roughness": 0, 1053 | "opacity": 100, 1054 | "groupIds": [], 1055 | "frameId": null, 1056 | "index": "aZ", 1057 | "roundness": null, 1058 | "seed": 1385734765, 1059 | "version": 361, 1060 | "versionNonce": 24613339, 1061 | "isDeleted": false, 1062 | "boundElements": [], 1063 | "updated": 1744314592984, 1064 | "link": null, 1065 | "locked": false, 1066 | "text": "Date\nJobId", 1067 | "fontSize": 20, 1068 | "fontFamily": 1, 1069 | "textAlign": "center", 1070 | "verticalAlign": "middle", 1071 | "containerId": "pUVgtk82pdH0sP6l3GmX8", 1072 | "originalText": "Date\nJobId", 1073 | "autoResize": true, 1074 | "lineHeight": 1.25 1075 | }, 1076 | { 1077 | "id": "Kwagl9zKiAM5CMjJ3TqR0", 1078 | "type": "rectangle", 1079 | "x": 172.3747714498507, 1080 | "y": -24955.009800999043, 1081 | "width": 148.1946876835549, 1082 | "height": 498.9221222677734, 1083 | "angle": 0, 1084 | "strokeColor": "#1e1e1e", 1085 | "backgroundColor": "#ffffff", 1086 | "fillStyle": "solid", 1087 | "strokeWidth": 1, 1088 | "strokeStyle": "solid", 1089 | "roughness": 0, 1090 | "opacity": 100, 1091 | "groupIds": [], 1092 | "frameId": null, 1093 | "index": "aa", 1094 | "roundness": { 1095 | "type": 3 1096 | }, 1097 | "seed": 235850509, 1098 | "version": 424, 1099 | "versionNonce": 2104278755, 1100 | "isDeleted": false, 1101 | "boundElements": [ 1102 | { 1103 | "id": "7sLd37hyPl8lBkDDWukrs", 1104 | "type": "arrow" 1105 | }, 1106 | { 1107 | "id": "n-BkhaViuUQSc2vLzzxAu", 1108 | "type": "arrow" 1109 | } 1110 | ], 1111 | "updated": 1743707268272, 1112 | "link": null, 1113 | "locked": false 1114 | }, 1115 | { 1116 | "id": "QrdQPEp3QbYHJjmvojQ26", 1117 | "type": "text", 1118 | "x": 170.52236611970017, 1119 | "y": -24998.233263350903, 1120 | "width": 153.875, 1121 | "height": 25, 1122 | "angle": 0, 1123 | "strokeColor": "#1e1e1e", 1124 | "backgroundColor": "#ffffff", 1125 | "fillStyle": "solid", 1126 | "strokeWidth": 1, 1127 | "strokeStyle": "solid", 1128 | "roughness": 0, 1129 | "opacity": 100, 1130 | "groupIds": [], 1131 | "frameId": null, 1132 | "index": "ab", 1133 | "roundness": null, 1134 | "seed": 628875629, 1135 | "version": 323, 1136 | "versionNonce": 572247725, 1137 | "isDeleted": false, 1138 | "boundElements": [], 1139 | "updated": 1743707156614, 1140 | "link": null, 1141 | "locked": false, 1142 | "text": "Delayed JobIds", 1143 | "fontSize": 20, 1144 | "fontFamily": 1, 1145 | "textAlign": "left", 1146 | "verticalAlign": "top", 1147 | "containerId": null, 1148 | "originalText": "Delayed JobIds", 1149 | "autoResize": true, 1150 | "lineHeight": 1.25 1151 | }, 1152 | { 1153 | "id": "zYsIx8QdTOH4pFW5JVVm3", 1154 | "type": "rectangle", 1155 | "x": 195.8389491770095, 1156 | "y": -24515.98302460361, 1157 | "width": 104.353768665801, 1158 | "height": 35, 1159 | "angle": 0, 1160 | "strokeColor": "#1e1e1e", 1161 | "backgroundColor": "#ffffff", 1162 | "fillStyle": "solid", 1163 | "strokeWidth": 1, 1164 | "strokeStyle": "solid", 1165 | "roughness": 0, 1166 | "opacity": 100, 1167 | "groupIds": [], 1168 | "frameId": null, 1169 | "index": "ac", 1170 | "roundness": { 1171 | "type": 3 1172 | }, 1173 | "seed": 1337404365, 1174 | "version": 309, 1175 | "versionNonce": 610758925, 1176 | "isDeleted": false, 1177 | "boundElements": [ 1178 | { 1179 | "type": "text", 1180 | "id": "EyaHHAEFNQJw1qcCzF7px" 1181 | } 1182 | ], 1183 | "updated": 1743707156614, 1184 | "link": null, 1185 | "locked": false 1186 | }, 1187 | { 1188 | "id": "EyaHHAEFNQJw1qcCzF7px", 1189 | "type": "text", 1190 | "x": 219.91166747902622, 1191 | "y": -24510.98302460361, 1192 | "width": 56.20833206176758, 1193 | "height": 25, 1194 | "angle": 0, 1195 | "strokeColor": "#1e1e1e", 1196 | "backgroundColor": "#ffffff", 1197 | "fillStyle": "solid", 1198 | "strokeWidth": 1, 1199 | "strokeStyle": "solid", 1200 | "roughness": 0, 1201 | "opacity": 100, 1202 | "groupIds": [], 1203 | "frameId": null, 1204 | "index": "ad", 1205 | "roundness": null, 1206 | "seed": 2094672429, 1207 | "version": 282, 1208 | "versionNonce": 1976551277, 1209 | "isDeleted": false, 1210 | "boundElements": [], 1211 | "updated": 1743707156614, 1212 | "link": null, 1213 | "locked": false, 1214 | "text": "JobId", 1215 | "fontSize": 20, 1216 | "fontFamily": 1, 1217 | "textAlign": "center", 1218 | "verticalAlign": "middle", 1219 | "containerId": "zYsIx8QdTOH4pFW5JVVm3", 1220 | "originalText": "JobId", 1221 | "autoResize": true, 1222 | "lineHeight": 1.25 1223 | }, 1224 | { 1225 | "id": "zUSRvAElDEiMqGqzLD7g5", 1226 | "type": "rectangle", 1227 | "x": 192.44282562857717, 1228 | "y": -24564.974433424217, 1229 | "width": 104.353768665801, 1230 | "height": 35, 1231 | "angle": 0, 1232 | "strokeColor": "#1e1e1e", 1233 | "backgroundColor": "#ffffff", 1234 | "fillStyle": "solid", 1235 | "strokeWidth": 1, 1236 | "strokeStyle": "solid", 1237 | "roughness": 0, 1238 | "opacity": 100, 1239 | "groupIds": [], 1240 | "frameId": null, 1241 | "index": "ae", 1242 | "roundness": { 1243 | "type": 3 1244 | }, 1245 | "seed": 1573805197, 1246 | "version": 342, 1247 | "versionNonce": 2023641549, 1248 | "isDeleted": false, 1249 | "boundElements": [ 1250 | { 1251 | "type": "text", 1252 | "id": "6VghLwu22UI_V3zotYh2x" 1253 | } 1254 | ], 1255 | "updated": 1743707156614, 1256 | "link": null, 1257 | "locked": false 1258 | }, 1259 | { 1260 | "id": "6VghLwu22UI_V3zotYh2x", 1261 | "type": "text", 1262 | "x": 216.51554393059388, 1263 | "y": -24559.974433424217, 1264 | "width": 56.20833206176758, 1265 | "height": 25, 1266 | "angle": 0, 1267 | "strokeColor": "#1e1e1e", 1268 | "backgroundColor": "#ffffff", 1269 | "fillStyle": "solid", 1270 | "strokeWidth": 1, 1271 | "strokeStyle": "solid", 1272 | "roughness": 0, 1273 | "opacity": 100, 1274 | "groupIds": [], 1275 | "frameId": null, 1276 | "index": "af", 1277 | "roundness": null, 1278 | "seed": 1246577389, 1279 | "version": 315, 1280 | "versionNonce": 166498349, 1281 | "isDeleted": false, 1282 | "boundElements": [], 1283 | "updated": 1743707156614, 1284 | "link": null, 1285 | "locked": false, 1286 | "text": "JobId", 1287 | "fontSize": 20, 1288 | "fontFamily": 1, 1289 | "textAlign": "center", 1290 | "verticalAlign": "middle", 1291 | "containerId": "zUSRvAElDEiMqGqzLD7g5", 1292 | "originalText": "JobId", 1293 | "autoResize": true, 1294 | "lineHeight": 1.25 1295 | }, 1296 | { 1297 | "id": "Yg3tsDWw_K_LcI1sUFIlS", 1298 | "type": "rectangle", 1299 | "x": 192.44282562857717, 1300 | "y": -24614.990131095463, 1301 | "width": 104.353768665801, 1302 | "height": 35, 1303 | "angle": 0, 1304 | "strokeColor": "#1e1e1e", 1305 | "backgroundColor": "#ffffff", 1306 | "fillStyle": "solid", 1307 | "strokeWidth": 1, 1308 | "strokeStyle": "solid", 1309 | "roughness": 0, 1310 | "opacity": 100, 1311 | "groupIds": [], 1312 | "frameId": null, 1313 | "index": "ag", 1314 | "roundness": { 1315 | "type": 3 1316 | }, 1317 | "seed": 1725979981, 1318 | "version": 377, 1319 | "versionNonce": 665059981, 1320 | "isDeleted": false, 1321 | "boundElements": [ 1322 | { 1323 | "type": "text", 1324 | "id": "1AoM6dRwvDALxfRHp7U49" 1325 | } 1326 | ], 1327 | "updated": 1743707156614, 1328 | "link": null, 1329 | "locked": false 1330 | }, 1331 | { 1332 | "id": "1AoM6dRwvDALxfRHp7U49", 1333 | "type": "text", 1334 | "x": 216.51554393059388, 1335 | "y": -24609.990131095463, 1336 | "width": 56.20833206176758, 1337 | "height": 25, 1338 | "angle": 0, 1339 | "strokeColor": "#1e1e1e", 1340 | "backgroundColor": "#ffffff", 1341 | "fillStyle": "solid", 1342 | "strokeWidth": 1, 1343 | "strokeStyle": "solid", 1344 | "roughness": 0, 1345 | "opacity": 100, 1346 | "groupIds": [], 1347 | "frameId": null, 1348 | "index": "ah", 1349 | "roundness": null, 1350 | "seed": 182528941, 1351 | "version": 350, 1352 | "versionNonce": 1451108589, 1353 | "isDeleted": false, 1354 | "boundElements": [], 1355 | "updated": 1743707156614, 1356 | "link": null, 1357 | "locked": false, 1358 | "text": "JobId", 1359 | "fontSize": 20, 1360 | "fontFamily": 1, 1361 | "textAlign": "center", 1362 | "verticalAlign": "middle", 1363 | "containerId": "Yg3tsDWw_K_LcI1sUFIlS", 1364 | "originalText": "JobId", 1365 | "autoResize": true, 1366 | "lineHeight": 1.25 1367 | }, 1368 | { 1369 | "id": "z9FNpeTBNH6eNKzchFZM6", 1370 | "type": "rectangle", 1371 | "x": 190.59037318860356, 1372 | "y": -24665.623344319905, 1373 | "width": 104.353768665801, 1374 | "height": 35, 1375 | "angle": 0, 1376 | "strokeColor": "#1e1e1e", 1377 | "backgroundColor": "#ffffff", 1378 | "fillStyle": "solid", 1379 | "strokeWidth": 1, 1380 | "strokeStyle": "solid", 1381 | "roughness": 0, 1382 | "opacity": 100, 1383 | "groupIds": [], 1384 | "frameId": null, 1385 | "index": "ai", 1386 | "roundness": { 1387 | "type": 3 1388 | }, 1389 | "seed": 1719217677, 1390 | "version": 417, 1391 | "versionNonce": 1208255309, 1392 | "isDeleted": false, 1393 | "boundElements": [ 1394 | { 1395 | "type": "text", 1396 | "id": "RgKs-Les2qNWKtllR6qaY" 1397 | } 1398 | ], 1399 | "updated": 1743707156614, 1400 | "link": null, 1401 | "locked": false 1402 | }, 1403 | { 1404 | "id": "RgKs-Les2qNWKtllR6qaY", 1405 | "type": "text", 1406 | "x": 214.66309149062027, 1407 | "y": -24660.623344319905, 1408 | "width": 56.20833206176758, 1409 | "height": 25, 1410 | "angle": 0, 1411 | "strokeColor": "#1e1e1e", 1412 | "backgroundColor": "#ffffff", 1413 | "fillStyle": "solid", 1414 | "strokeWidth": 1, 1415 | "strokeStyle": "solid", 1416 | "roughness": 0, 1417 | "opacity": 100, 1418 | "groupIds": [], 1419 | "frameId": null, 1420 | "index": "aj", 1421 | "roundness": null, 1422 | "seed": 1755440237, 1423 | "version": 390, 1424 | "versionNonce": 1083216301, 1425 | "isDeleted": false, 1426 | "boundElements": [], 1427 | "updated": 1743707156614, 1428 | "link": null, 1429 | "locked": false, 1430 | "text": "JobId", 1431 | "fontSize": 20, 1432 | "fontFamily": 1, 1433 | "textAlign": "center", 1434 | "verticalAlign": "middle", 1435 | "containerId": "z9FNpeTBNH6eNKzchFZM6", 1436 | "originalText": "JobId", 1437 | "autoResize": true, 1438 | "lineHeight": 1.25 1439 | }, 1440 | { 1441 | "id": "b9SNTjWpUK_1J3Vb8_oLJ", 1442 | "type": "rectangle", 1443 | "x": 387.5044148230971, 1444 | "y": -24959.33217432238, 1445 | "width": 148.1946876835549, 1446 | "height": 498.9221222677734, 1447 | "angle": 0, 1448 | "strokeColor": "#1e1e1e", 1449 | "backgroundColor": "#ffffff", 1450 | "fillStyle": "solid", 1451 | "strokeWidth": 1, 1452 | "strokeStyle": "solid", 1453 | "roughness": 0, 1454 | "opacity": 100, 1455 | "groupIds": [], 1456 | "frameId": null, 1457 | "index": "ao", 1458 | "roundness": { 1459 | "type": 3 1460 | }, 1461 | "seed": 1867060909, 1462 | "version": 648, 1463 | "versionNonce": 380328155, 1464 | "isDeleted": false, 1465 | "boundElements": [ 1466 | { 1467 | "id": "7sLd37hyPl8lBkDDWukrs", 1468 | "type": "arrow" 1469 | }, 1470 | { 1471 | "id": "klw1pQs7B0t1ULadFCyxH", 1472 | "type": "arrow" 1473 | } 1474 | ], 1475 | "updated": 1744314194453, 1476 | "link": null, 1477 | "locked": false 1478 | }, 1479 | { 1480 | "id": "LXTRcbL_PY04hzkHKDVL5", 1481 | "type": "text", 1482 | "x": 373.91987351954475, 1483 | "y": -24999.468259124955, 1484 | "width": 195.1666717529297, 1485 | "height": 25, 1486 | "angle": 0, 1487 | "strokeColor": "#1e1e1e", 1488 | "backgroundColor": "#ffffff", 1489 | "fillStyle": "solid", 1490 | "strokeWidth": 1, 1491 | "strokeStyle": "solid", 1492 | "roughness": 0, 1493 | "opacity": 100, 1494 | "groupIds": [], 1495 | "frameId": null, 1496 | "index": "ap", 1497 | "roundness": null, 1498 | "seed": 1823193357, 1499 | "version": 575, 1500 | "versionNonce": 417663981, 1501 | "isDeleted": false, 1502 | "boundElements": [], 1503 | "updated": 1743707166197, 1504 | "link": null, 1505 | "locked": false, 1506 | "text": "Delayed Jobs Data", 1507 | "fontSize": 20, 1508 | "fontFamily": 1, 1509 | "textAlign": "left", 1510 | "verticalAlign": "top", 1511 | "containerId": null, 1512 | "originalText": "Delayed Jobs Data", 1513 | "autoResize": true, 1514 | "lineHeight": 1.25 1515 | }, 1516 | { 1517 | "id": "WkzZFkSO0ICKqk5OIKRSI", 1518 | "type": "rectangle", 1519 | "x": 410.9685925502559, 1520 | "y": -24520.305397926946, 1521 | "width": 104.353768665801, 1522 | "height": 35, 1523 | "angle": 0, 1524 | "strokeColor": "#1e1e1e", 1525 | "backgroundColor": "#ffffff", 1526 | "fillStyle": "solid", 1527 | "strokeWidth": 1, 1528 | "strokeStyle": "solid", 1529 | "roughness": 0, 1530 | "opacity": 100, 1531 | "groupIds": [], 1532 | "frameId": null, 1533 | "index": "aq", 1534 | "roundness": { 1535 | "type": 3 1536 | }, 1537 | "seed": 1045106541, 1538 | "version": 529, 1539 | "versionNonce": 1342252845, 1540 | "isDeleted": false, 1541 | "boundElements": [ 1542 | { 1543 | "type": "text", 1544 | "id": "Db-aW2SGvWiESZuIYQZ2C" 1545 | } 1546 | ], 1547 | "updated": 1743707165197, 1548 | "link": null, 1549 | "locked": false 1550 | }, 1551 | { 1552 | "id": "Db-aW2SGvWiESZuIYQZ2C", 1553 | "type": "text", 1554 | "x": 446.1767268831564, 1555 | "y": -24515.305397926946, 1556 | "width": 33.9375, 1557 | "height": 25, 1558 | "angle": 0, 1559 | "strokeColor": "#1e1e1e", 1560 | "backgroundColor": "#ffffff", 1561 | "fillStyle": "solid", 1562 | "strokeWidth": 1, 1563 | "strokeStyle": "solid", 1564 | "roughness": 0, 1565 | "opacity": 100, 1566 | "groupIds": [], 1567 | "frameId": null, 1568 | "index": "ar", 1569 | "roundness": null, 1570 | "seed": 577804749, 1571 | "version": 503, 1572 | "versionNonce": 219003277, 1573 | "isDeleted": false, 1574 | "boundElements": [], 1575 | "updated": 1743707165197, 1576 | "link": null, 1577 | "locked": false, 1578 | "text": "Job", 1579 | "fontSize": 20, 1580 | "fontFamily": 1, 1581 | "textAlign": "center", 1582 | "verticalAlign": "middle", 1583 | "containerId": "WkzZFkSO0ICKqk5OIKRSI", 1584 | "originalText": "Job", 1585 | "autoResize": true, 1586 | "lineHeight": 1.25 1587 | }, 1588 | { 1589 | "id": "_CzNLJ8y3XBICdE9ogRqM", 1590 | "type": "rectangle", 1591 | "x": 407.57246900182355, 1592 | "y": -24569.296806747552, 1593 | "width": 104.353768665801, 1594 | "height": 35, 1595 | "angle": 0, 1596 | "strokeColor": "#1e1e1e", 1597 | "backgroundColor": "#ffffff", 1598 | "fillStyle": "solid", 1599 | "strokeWidth": 1, 1600 | "strokeStyle": "solid", 1601 | "roughness": 0, 1602 | "opacity": 100, 1603 | "groupIds": [], 1604 | "frameId": null, 1605 | "index": "as", 1606 | "roundness": { 1607 | "type": 3 1608 | }, 1609 | "seed": 1379260461, 1610 | "version": 562, 1611 | "versionNonce": 1939406829, 1612 | "isDeleted": false, 1613 | "boundElements": [ 1614 | { 1615 | "type": "text", 1616 | "id": "_oibrAmrChn-fkHEkEHNC" 1617 | } 1618 | ], 1619 | "updated": 1743707165197, 1620 | "link": null, 1621 | "locked": false 1622 | }, 1623 | { 1624 | "id": "_oibrAmrChn-fkHEkEHNC", 1625 | "type": "text", 1626 | "x": 442.78060333472405, 1627 | "y": -24564.296806747552, 1628 | "width": 33.9375, 1629 | "height": 25, 1630 | "angle": 0, 1631 | "strokeColor": "#1e1e1e", 1632 | "backgroundColor": "#ffffff", 1633 | "fillStyle": "solid", 1634 | "strokeWidth": 1, 1635 | "strokeStyle": "solid", 1636 | "roughness": 0, 1637 | "opacity": 100, 1638 | "groupIds": [], 1639 | "frameId": null, 1640 | "index": "at", 1641 | "roundness": null, 1642 | "seed": 662981261, 1643 | "version": 536, 1644 | "versionNonce": 1236040269, 1645 | "isDeleted": false, 1646 | "boundElements": [], 1647 | "updated": 1743707165197, 1648 | "link": null, 1649 | "locked": false, 1650 | "text": "Job", 1651 | "fontSize": 20, 1652 | "fontFamily": 1, 1653 | "textAlign": "center", 1654 | "verticalAlign": "middle", 1655 | "containerId": "_CzNLJ8y3XBICdE9ogRqM", 1656 | "originalText": "Job", 1657 | "autoResize": true, 1658 | "lineHeight": 1.25 1659 | }, 1660 | { 1661 | "id": "RWrlrVAr0Vx5R153jUH2u", 1662 | "type": "rectangle", 1663 | "x": 407.57246900182355, 1664 | "y": -24619.3125044188, 1665 | "width": 104.353768665801, 1666 | "height": 35, 1667 | "angle": 0, 1668 | "strokeColor": "#1e1e1e", 1669 | "backgroundColor": "#ffffff", 1670 | "fillStyle": "solid", 1671 | "strokeWidth": 1, 1672 | "strokeStyle": "solid", 1673 | "roughness": 0, 1674 | "opacity": 100, 1675 | "groupIds": [], 1676 | "frameId": null, 1677 | "index": "au", 1678 | "roundness": { 1679 | "type": 3 1680 | }, 1681 | "seed": 51736813, 1682 | "version": 597, 1683 | "versionNonce": 1478600877, 1684 | "isDeleted": false, 1685 | "boundElements": [ 1686 | { 1687 | "type": "text", 1688 | "id": "wrfXiQZA7dnRJF9kZUr-n" 1689 | } 1690 | ], 1691 | "updated": 1743707165197, 1692 | "link": null, 1693 | "locked": false 1694 | }, 1695 | { 1696 | "id": "wrfXiQZA7dnRJF9kZUr-n", 1697 | "type": "text", 1698 | "x": 442.78060333472405, 1699 | "y": -24614.3125044188, 1700 | "width": 33.9375, 1701 | "height": 25, 1702 | "angle": 0, 1703 | "strokeColor": "#1e1e1e", 1704 | "backgroundColor": "#ffffff", 1705 | "fillStyle": "solid", 1706 | "strokeWidth": 1, 1707 | "strokeStyle": "solid", 1708 | "roughness": 0, 1709 | "opacity": 100, 1710 | "groupIds": [], 1711 | "frameId": null, 1712 | "index": "av", 1713 | "roundness": null, 1714 | "seed": 1920125773, 1715 | "version": 571, 1716 | "versionNonce": 279055117, 1717 | "isDeleted": false, 1718 | "boundElements": [], 1719 | "updated": 1743707165197, 1720 | "link": null, 1721 | "locked": false, 1722 | "text": "Job", 1723 | "fontSize": 20, 1724 | "fontFamily": 1, 1725 | "textAlign": "center", 1726 | "verticalAlign": "middle", 1727 | "containerId": "RWrlrVAr0Vx5R153jUH2u", 1728 | "originalText": "Job", 1729 | "autoResize": true, 1730 | "lineHeight": 1.25 1731 | }, 1732 | { 1733 | "id": "48XHaPT5RjB6ttieFesm4", 1734 | "type": "rectangle", 1735 | "x": 405.72001656184995, 1736 | "y": -24669.94571764324, 1737 | "width": 104.353768665801, 1738 | "height": 35, 1739 | "angle": 0, 1740 | "strokeColor": "#1e1e1e", 1741 | "backgroundColor": "#ffffff", 1742 | "fillStyle": "solid", 1743 | "strokeWidth": 1, 1744 | "strokeStyle": "solid", 1745 | "roughness": 0, 1746 | "opacity": 100, 1747 | "groupIds": [], 1748 | "frameId": null, 1749 | "index": "aw", 1750 | "roundness": { 1751 | "type": 3 1752 | }, 1753 | "seed": 368433581, 1754 | "version": 637, 1755 | "versionNonce": 1940332909, 1756 | "isDeleted": false, 1757 | "boundElements": [ 1758 | { 1759 | "type": "text", 1760 | "id": "-QBYgEAhqcVv0PXXwHXQ1" 1761 | } 1762 | ], 1763 | "updated": 1743707165197, 1764 | "link": null, 1765 | "locked": false 1766 | }, 1767 | { 1768 | "id": "-QBYgEAhqcVv0PXXwHXQ1", 1769 | "type": "text", 1770 | "x": 440.92815089475044, 1771 | "y": -24664.94571764324, 1772 | "width": 33.9375, 1773 | "height": 25, 1774 | "angle": 0, 1775 | "strokeColor": "#1e1e1e", 1776 | "backgroundColor": "#ffffff", 1777 | "fillStyle": "solid", 1778 | "strokeWidth": 1, 1779 | "strokeStyle": "solid", 1780 | "roughness": 0, 1781 | "opacity": 100, 1782 | "groupIds": [], 1783 | "frameId": null, 1784 | "index": "ax", 1785 | "roundness": null, 1786 | "seed": 1187519501, 1787 | "version": 612, 1788 | "versionNonce": 913992653, 1789 | "isDeleted": false, 1790 | "boundElements": [], 1791 | "updated": 1743707165197, 1792 | "link": null, 1793 | "locked": false, 1794 | "text": "Job", 1795 | "fontSize": 20, 1796 | "fontFamily": 1, 1797 | "textAlign": "center", 1798 | "verticalAlign": "middle", 1799 | "containerId": "48XHaPT5RjB6ttieFesm4", 1800 | "originalText": "Job", 1801 | "autoResize": true, 1802 | "lineHeight": 1.25 1803 | }, 1804 | { 1805 | "id": "7sLd37hyPl8lBkDDWukrs", 1806 | "type": "arrow", 1807 | "x": 248.72213886022885, 1808 | "y": -24451.087678731266, 1809 | "width": 207.19232922338753, 1810 | "height": 47.408622235318035, 1811 | "angle": 0, 1812 | "strokeColor": "#1e1e1e", 1813 | "backgroundColor": "#ffffff", 1814 | "fillStyle": "solid", 1815 | "strokeWidth": 1, 1816 | "strokeStyle": "solid", 1817 | "roughness": 0, 1818 | "opacity": 100, 1819 | "groupIds": [], 1820 | "frameId": null, 1821 | "index": "ay", 1822 | "roundness": null, 1823 | "seed": 1274876163, 1824 | "version": 336, 1825 | "versionNonce": 608955707, 1826 | "isDeleted": false, 1827 | "boundElements": [ 1828 | { 1829 | "type": "text", 1830 | "id": "GyRzO4Q1QaV5ola2IxmcQ" 1831 | } 1832 | ], 1833 | "updated": 1744314194454, 1834 | "link": null, 1835 | "locked": false, 1836 | "points": [ 1837 | [ 1838 | 0, 1839 | 0 1840 | ], 1841 | [ 1842 | 0, 1843 | 43.08624891198269 1844 | ], 1845 | [ 1846 | 207.19232922338753, 1847 | 43.08624891198269 1848 | ], 1849 | [ 1850 | 207.19232922338753, 1851 | -4.322373323335341 1852 | ] 1853 | ], 1854 | "lastCommittedPoint": null, 1855 | "startBinding": { 1856 | "elementId": "Kwagl9zKiAM5CMjJ3TqR0", 1857 | "focus": 0.8253427552672834, 1858 | "gap": 3.7048224377103907, 1859 | "fixedPoint": [ 1860 | 0.5151828895068443, 1861 | 1.0100216041278685 1862 | ] 1863 | }, 1864 | "endBinding": { 1865 | "elementId": "b9SNTjWpUK_1J3Vb8_oLJ", 1866 | "focus": -0.778291577153903, 1867 | "gap": 2.469885550945037, 1868 | "fixedPoint": [ 1869 | 0.4616228444476876, 1870 | 1.0100216041278685 1871 | ] 1872 | }, 1873 | "startArrowhead": null, 1874 | "endArrowhead": "arrow", 1875 | "elbowed": true, 1876 | "fixedSegments": [ 1877 | { 1878 | "index": 2, 1879 | "start": [ 1880 | 0, 1881 | 43.08624891198269 1882 | ], 1883 | "end": [ 1884 | 207.19232922338753, 1885 | 43.08624891198269 1886 | ] 1887 | } 1888 | ], 1889 | "startIsSpecial": false, 1890 | "endIsSpecial": false 1891 | }, 1892 | { 1893 | "id": "GyRzO4Q1QaV5ola2IxmcQ", 1894 | "type": "text", 1895 | "x": 314.56438060408976, 1896 | "y": -24395.25828135833, 1897 | "width": 89.8125, 1898 | "height": 50, 1899 | "angle": 0, 1900 | "strokeColor": "#1e1e1e", 1901 | "backgroundColor": "#ffffff", 1902 | "fillStyle": "solid", 1903 | "strokeWidth": 1, 1904 | "strokeStyle": "solid", 1905 | "roughness": 0, 1906 | "opacity": 100, 1907 | "groupIds": [], 1908 | "frameId": null, 1909 | "index": "az", 1910 | "roundness": null, 1911 | "seed": 1083397699, 1912 | "version": 27, 1913 | "versionNonce": 217389421, 1914 | "isDeleted": false, 1915 | "boundElements": [], 1916 | "updated": 1743707255598, 1917 | "link": null, 1918 | "locked": false, 1919 | "text": "On expire\nget job", 1920 | "fontSize": 20, 1921 | "fontFamily": 1, 1922 | "textAlign": "center", 1923 | "verticalAlign": "middle", 1924 | "containerId": "7sLd37hyPl8lBkDDWukrs", 1925 | "originalText": "On expire\nget job", 1926 | "autoResize": true, 1927 | "lineHeight": 1.25 1928 | }, 1929 | { 1930 | "id": "klw1pQs7B0t1ULadFCyxH", 1931 | "type": "arrow", 1932 | "x": 506.5605728444751, 1933 | "y": -24455.477051057806, 1934 | "width": 335.8828456824478, 1935 | "height": 715.1982095128951, 1936 | "angle": 0, 1937 | "strokeColor": "#1e1e1e", 1938 | "backgroundColor": "#ffffff", 1939 | "fillStyle": "solid", 1940 | "strokeWidth": 1, 1941 | "strokeStyle": "solid", 1942 | "roughness": 0, 1943 | "opacity": 100, 1944 | "groupIds": [], 1945 | "frameId": null, 1946 | "index": "b00", 1947 | "roundness": null, 1948 | "seed": 270502029, 1949 | "version": 1095, 1950 | "versionNonce": 144758773, 1951 | "isDeleted": false, 1952 | "boundElements": [ 1953 | { 1954 | "type": "text", 1955 | "id": "Wgo_ifISPclugcDRAFsxZ" 1956 | } 1957 | ], 1958 | "updated": 1744314194454, 1959 | "link": null, 1960 | "locked": false, 1961 | "points": [ 1962 | [ 1963 | 0, 1964 | 0 1965 | ], 1966 | [ 1967 | 0, 1968 | 40 1969 | ], 1970 | [ 1971 | 132.0796151752283, 1972 | 40 1973 | ], 1974 | [ 1975 | 132.0796151752283, 1976 | -675.1982095128951 1977 | ], 1978 | [ 1979 | 335.8828456824478, 1980 | -675.1982095128951 1981 | ], 1982 | [ 1983 | 335.8828456824478, 1984 | -509.4726034853993 1985 | ] 1986 | ], 1987 | "lastCommittedPoint": null, 1988 | "startBinding": { 1989 | "elementId": "b9SNTjWpUK_1J3Vb8_oLJ", 1990 | "focus": 0.7463307829894725, 1991 | "gap": 1, 1992 | "fixedPoint": [ 1993 | 0.8033766923926627, 1994 | 1.0098873166304545 1995 | ] 1996 | }, 1997 | "endBinding": { 1998 | "elementId": "i9Xjx6UBH_RSvC8R2zNsa", 1999 | "focus": -0.14024779113091151, 2000 | "gap": 4.999999999996362, 2001 | "fixedPoint": [ 2002 | 0.4298761044345431, 2003 | -0.010021604127853932 2004 | ] 2005 | }, 2006 | "startArrowhead": null, 2007 | "endArrowhead": "arrow", 2008 | "elbowed": true, 2009 | "fixedSegments": [ 2010 | { 2011 | "index": 3, 2012 | "start": [ 2013 | 132.0796151752283, 2014 | 40 2015 | ], 2016 | "end": [ 2017 | 132.0796151752283, 2018 | -675.1982095128951 2019 | ] 2020 | }, 2021 | { 2022 | "index": 4, 2023 | "start": [ 2024 | 132.0796151752283, 2025 | -675.1982095128951 2026 | ], 2027 | "end": [ 2028 | 335.8828456824478, 2029 | -675.1982095128951 2030 | ] 2031 | } 2032 | ], 2033 | "startIsSpecial": false, 2034 | "endIsSpecial": false 2035 | }, 2036 | { 2037 | "id": "Wgo_ifISPclugcDRAFsxZ", 2038 | "type": "text", 2039 | "x": 575.6714380197034, 2040 | "y": -24798.076155814255, 2041 | "width": 125.9375, 2042 | "height": 50, 2043 | "angle": 0, 2044 | "strokeColor": "#1e1e1e", 2045 | "backgroundColor": "#ffffff", 2046 | "fillStyle": "solid", 2047 | "strokeWidth": 1, 2048 | "strokeStyle": "solid", 2049 | "roughness": 0, 2050 | "opacity": 100, 2051 | "groupIds": [], 2052 | "frameId": null, 2053 | "index": "b00V", 2054 | "roundness": null, 2055 | "seed": 883306979, 2056 | "version": 39, 2057 | "versionNonce": 74752699, 2058 | "isDeleted": false, 2059 | "boundElements": [], 2060 | "updated": 1744314194453, 2061 | "link": null, 2062 | "locked": false, 2063 | "text": "Add to\nactive queue", 2064 | "fontSize": 20, 2065 | "fontFamily": 1, 2066 | "textAlign": "center", 2067 | "verticalAlign": "middle", 2068 | "containerId": "klw1pQs7B0t1ULadFCyxH", 2069 | "originalText": "Add to\nactive queue", 2070 | "autoResize": true, 2071 | "lineHeight": 1.25 2072 | }, 2073 | { 2074 | "id": "n-BkhaViuUQSc2vLzzxAu", 2075 | "type": "arrow", 2076 | "x": 233.50488357829502, 2077 | "y": -24451.087678731266, 2078 | "width": 189.42992389977428, 2079 | "height": 108.78386514286467, 2080 | "angle": 0, 2081 | "strokeColor": "#1e1e1e", 2082 | "backgroundColor": "#ffffff", 2083 | "fillStyle": "solid", 2084 | "strokeWidth": 1, 2085 | "strokeStyle": "solid", 2086 | "roughness": 0, 2087 | "opacity": 100, 2088 | "groupIds": [], 2089 | "frameId": null, 2090 | "index": "b02", 2091 | "roundness": null, 2092 | "seed": 1995379309, 2093 | "version": 178, 2094 | "versionNonce": 1551374971, 2095 | "isDeleted": false, 2096 | "boundElements": [ 2097 | { 2098 | "type": "text", 2099 | "id": "1_a0IrTmB3dVPxr0ARX1U" 2100 | } 2101 | ], 2102 | "updated": 1744314194454, 2103 | "link": null, 2104 | "locked": false, 2105 | "points": [ 2106 | [ 2107 | 0, 2108 | 0 2109 | ], 2110 | [ 2111 | 0, 2112 | 108.78386514286467 2113 | ], 2114 | [ 2115 | -189.42992389977428, 2116 | 108.78386514286467 2117 | ], 2118 | [ 2119 | -189.42992389977428, 2120 | 8.751514239731478 2121 | ] 2122 | ], 2123 | "lastCommittedPoint": null, 2124 | "startBinding": { 2125 | "elementId": "Kwagl9zKiAM5CMjJ3TqR0", 2126 | "focus": 0.1750026524705425, 2127 | "gap": 5.000000000003638, 2128 | "fixedPoint": [ 2129 | 0.41249867376472704, 2130 | 1.0100216041278685 2131 | ] 2132 | }, 2133 | "endBinding": { 2134 | "elementId": "ShSvfykLRNJLQJG0NLdhr", 2135 | "focus": 1.0200432082557087, 2136 | "gap": 5, 2137 | "fixedPoint": [ 2138 | 0.4993252119791667, 2139 | 1.0100216041278611 2140 | ] 2141 | }, 2142 | "startArrowhead": null, 2143 | "endArrowhead": "arrow", 2144 | "elbowed": true, 2145 | "fixedSegments": [ 2146 | { 2147 | "index": 2, 2148 | "start": [ 2149 | 0, 2150 | 108.78386514286467 2151 | ], 2152 | "end": [ 2153 | -189.42992389977428, 2154 | 108.78386514286467 2155 | ] 2156 | } 2157 | ], 2158 | "startIsSpecial": false, 2159 | "endIsSpecial": false 2160 | }, 2161 | { 2162 | "id": "1_a0IrTmB3dVPxr0ARX1U", 2163 | "type": "text", 2164 | "x": 87.53992162840788, 2165 | "y": -24367.3038135884, 2166 | "width": 102.5, 2167 | "height": 50, 2168 | "angle": 0, 2169 | "strokeColor": "#1e1e1e", 2170 | "backgroundColor": "#ffffff", 2171 | "fillStyle": "solid", 2172 | "strokeWidth": 1, 2173 | "strokeStyle": "solid", 2174 | "roughness": 0, 2175 | "opacity": 100, 2176 | "groupIds": [], 2177 | "frameId": null, 2178 | "index": "b03", 2179 | "roundness": null, 2180 | "seed": 469912589, 2181 | "version": 25, 2182 | "versionNonce": 316492653, 2183 | "isDeleted": false, 2184 | "boundElements": [], 2185 | "updated": 1743707285798, 2186 | "link": null, 2187 | "locked": false, 2188 | "text": "On expire\nremove job", 2189 | "fontSize": 20, 2190 | "fontFamily": 1, 2191 | "textAlign": "center", 2192 | "verticalAlign": "middle", 2193 | "containerId": "n-BkhaViuUQSc2vLzzxAu", 2194 | "originalText": "On expire\nremove job", 2195 | "autoResize": true, 2196 | "lineHeight": 1.25 2197 | }, 2198 | { 2199 | "id": "aFu4VA0xw6Xlo6hzRs3my", 2200 | "type": "arrow", 2201 | "x": 11.090938854710544, 2202 | "y": -24442.336164491535, 2203 | "width": 832.1699274186382, 2204 | "height": 796.5836816435622, 2205 | "angle": 0, 2206 | "strokeColor": "#1e1e1e", 2207 | "backgroundColor": "#ffffff", 2208 | "fillStyle": "solid", 2209 | "strokeWidth": 1, 2210 | "strokeStyle": "solid", 2211 | "roughness": 0, 2212 | "opacity": 100, 2213 | "groupIds": [], 2214 | "frameId": null, 2215 | "index": "b04", 2216 | "roundness": null, 2217 | "seed": 159600931, 2218 | "version": 1281, 2219 | "versionNonce": 1518935733, 2220 | "isDeleted": false, 2221 | "boundElements": [ 2222 | { 2223 | "type": "text", 2224 | "id": "-YuYk4th0YMctZ_GDRSQ6" 2225 | } 2226 | ], 2227 | "updated": 1744314194454, 2228 | "link": null, 2229 | "locked": false, 2230 | "points": [ 2231 | [ 2232 | 0, 2233 | 0 2234 | ], 2235 | [ 2236 | 0, 2237 | 172.5735221242976 2238 | ], 2239 | [ 2240 | 707.6181977353406, 2241 | 172.5735221242976 2242 | ], 2243 | [ 2244 | 707.6181977353406, 2245 | -624.0101595192646 2246 | ], 2247 | [ 2248 | 832.1699274186382, 2249 | -624.0101595192646 2250 | ], 2251 | [ 2252 | 832.1699274186382, 2253 | -522.6134900516699 2254 | ] 2255 | ], 2256 | "lastCommittedPoint": null, 2257 | "startBinding": { 2258 | "elementId": "ShSvfykLRNJLQJG0NLdhr", 2259 | "focus": 0.4464940186581536, 2260 | "gap": 5, 2261 | "fixedPoint": [ 2262 | 0.27675299067092324, 2263 | 1.0100216041278611 2264 | ] 2265 | }, 2266 | "endBinding": { 2267 | "elementId": "i9Xjx6UBH_RSvC8R2zNsa", 2268 | "focus": -0.1292157121920041, 2269 | "gap": 4.999999999996362, 2270 | "fixedPoint": [ 2271 | 0.4353921439039968, 2272 | -0.010021604127853932 2273 | ] 2274 | }, 2275 | "startArrowhead": null, 2276 | "endArrowhead": "arrow", 2277 | "elbowed": true, 2278 | "fixedSegments": [ 2279 | { 2280 | "index": 2, 2281 | "start": [ 2282 | 0, 2283 | 172.5735221242976 2284 | ], 2285 | "end": [ 2286 | 707.6181977353406, 2287 | 172.5735221242976 2288 | ] 2289 | }, 2290 | { 2291 | "index": 3, 2292 | "start": [ 2293 | 707.6181977353406, 2294 | 172.5735221242976 2295 | ], 2296 | "end": [ 2297 | 707.6181977353406, 2298 | -624.0101595192646 2299 | ] 2300 | }, 2301 | { 2302 | "index": 4, 2303 | "start": [ 2304 | 707.6181977353406, 2305 | -624.0101595192646 2306 | ], 2307 | "end": [ 2308 | 832.1699274186382, 2309 | -624.0101595192646 2310 | ] 2311 | } 2312 | ], 2313 | "startIsSpecial": false, 2314 | "endIsSpecial": false 2315 | }, 2316 | { 2317 | "id": "-YuYk4th0YMctZ_GDRSQ6", 2318 | "type": "text", 2319 | "x": 668.8549686518187, 2320 | "y": -24730.55448318902, 2321 | "width": 99.70833587646484, 2322 | "height": 125, 2323 | "angle": 0, 2324 | "strokeColor": "#1e1e1e", 2325 | "backgroundColor": "#ffffff", 2326 | "fillStyle": "solid", 2327 | "strokeWidth": 1, 2328 | "strokeStyle": "solid", 2329 | "roughness": 0, 2330 | "opacity": 100, 2331 | "groupIds": [], 2332 | "frameId": null, 2333 | "index": "b04G", 2334 | "roundness": null, 2335 | "seed": 257774403, 2336 | "version": 52, 2337 | "versionNonce": 615004789, 2338 | "isDeleted": false, 2339 | "boundElements": [], 2340 | "updated": 1744314194453, 2341 | "link": null, 2342 | "locked": false, 2343 | "text": "On start\nadd ready\njobs to\nactive\nqueue", 2344 | "fontSize": 20, 2345 | "fontFamily": 1, 2346 | "textAlign": "center", 2347 | "verticalAlign": "middle", 2348 | "containerId": "aFu4VA0xw6Xlo6hzRs3my", 2349 | "originalText": "On start\nadd ready\njobs to\nactive\nqueue", 2350 | "autoResize": true, 2351 | "lineHeight": 1.25 2352 | }, 2353 | { 2354 | "id": "7PGPskS9XCDfHTMyTnJkl", 2355 | "type": "rectangle", 2356 | "x": -1457.936585108539, 2357 | "y": -24960.735992884765, 2358 | "width": 148.1946876835549, 2359 | "height": 498.9221222677734, 2360 | "angle": 0, 2361 | "strokeColor": "#1e1e1e", 2362 | "backgroundColor": "#ffffff", 2363 | "fillStyle": "solid", 2364 | "strokeWidth": 1, 2365 | "strokeStyle": "solid", 2366 | "roughness": 0, 2367 | "opacity": 100, 2368 | "groupIds": [], 2369 | "frameId": null, 2370 | "index": "b08", 2371 | "roundness": { 2372 | "type": 3 2373 | }, 2374 | "seed": 1428513997, 2375 | "version": 333, 2376 | "versionNonce": 1699884589, 2377 | "isDeleted": false, 2378 | "boundElements": [ 2379 | { 2380 | "id": "GzhPij65cNBIFfOV6h9cF", 2381 | "type": "arrow" 2382 | }, 2383 | { 2384 | "id": "W8AHtVFQmCMidlUBb3GpJ", 2385 | "type": "arrow" 2386 | } 2387 | ], 2388 | "updated": 1743709358241, 2389 | "link": null, 2390 | "locked": false 2391 | }, 2392 | { 2393 | "id": "030wLkFO0DV-OgA3dcdba", 2394 | "type": "ellipse", 2395 | "x": -1149.349123853669, 2396 | "y": -24652.78605511477, 2397 | "width": 190.1832013711578, 2398 | "height": 142.01990903007027, 2399 | "angle": 0, 2400 | "strokeColor": "#1e1e1e", 2401 | "backgroundColor": "#ffffff", 2402 | "fillStyle": "solid", 2403 | "strokeWidth": 1, 2404 | "strokeStyle": "solid", 2405 | "roughness": 0, 2406 | "opacity": 100, 2407 | "groupIds": [], 2408 | "frameId": null, 2409 | "index": "b09", 2410 | "roundness": { 2411 | "type": 2 2412 | }, 2413 | "seed": 169427757, 2414 | "version": 323, 2415 | "versionNonce": 346480973, 2416 | "isDeleted": false, 2417 | "boundElements": [ 2418 | { 2419 | "type": "text", 2420 | "id": "A3K25TpcJFR8aQwdVKQH2" 2421 | }, 2422 | { 2423 | "id": "GzhPij65cNBIFfOV6h9cF", 2424 | "type": "arrow" 2425 | } 2426 | ], 2427 | "updated": 1743709358241, 2428 | "link": null, 2429 | "locked": false 2430 | }, 2431 | { 2432 | "id": "A3K25TpcJFR8aQwdVKQH2", 2433 | "type": "text", 2434 | "x": -1086.44535487763, 2435 | "y": -24594.487720969068, 2436 | "width": 63.89583206176758, 2437 | "height": 25, 2438 | "angle": 0, 2439 | "strokeColor": "#1e1e1e", 2440 | "backgroundColor": "#ffffff", 2441 | "fillStyle": "solid", 2442 | "strokeWidth": 1, 2443 | "strokeStyle": "solid", 2444 | "roughness": 0, 2445 | "opacity": 100, 2446 | "groupIds": [], 2447 | "frameId": null, 2448 | "index": "b0A", 2449 | "roundness": null, 2450 | "seed": 96621965, 2451 | "version": 286, 2452 | "versionNonce": 1161244589, 2453 | "isDeleted": false, 2454 | "boundElements": [], 2455 | "updated": 1743709358241, 2456 | "link": null, 2457 | "locked": false, 2458 | "text": "Worker", 2459 | "fontSize": 20, 2460 | "fontFamily": 1, 2461 | "textAlign": "center", 2462 | "verticalAlign": "middle", 2463 | "containerId": "030wLkFO0DV-OgA3dcdba", 2464 | "originalText": "Worker", 2465 | "autoResize": true, 2466 | "lineHeight": 1.25 2467 | }, 2468 | { 2469 | "id": "IjCSDMjvNOTgowTSv2mX_", 2470 | "type": "text", 2471 | "x": -1457.3035060566062, 2472 | "y": -25017.64646079354, 2473 | "width": 128.9166717529297, 2474 | "height": 25, 2475 | "angle": 0, 2476 | "strokeColor": "#1e1e1e", 2477 | "backgroundColor": "#ffffff", 2478 | "fillStyle": "solid", 2479 | "strokeWidth": 1, 2480 | "strokeStyle": "solid", 2481 | "roughness": 0, 2482 | "opacity": 100, 2483 | "groupIds": [], 2484 | "frameId": null, 2485 | "index": "b0B", 2486 | "roundness": null, 2487 | "seed": 593107949, 2488 | "version": 308, 2489 | "versionNonce": 1078388845, 2490 | "isDeleted": false, 2491 | "boundElements": [], 2492 | "updated": 1743709358241, 2493 | "link": null, 2494 | "locked": false, 2495 | "text": "Active Queue", 2496 | "fontSize": 20, 2497 | "fontFamily": 1, 2498 | "textAlign": "left", 2499 | "verticalAlign": "top", 2500 | "containerId": null, 2501 | "originalText": "Active Queue", 2502 | "autoResize": true, 2503 | "lineHeight": 1.25 2504 | }, 2505 | { 2506 | "id": "OYOEWehqukIgdqFlEh9kF", 2507 | "type": "rectangle", 2508 | "x": -1434.4724073813804, 2509 | "y": -24521.709216489326, 2510 | "width": 104.353768665801, 2511 | "height": 35, 2512 | "angle": 0, 2513 | "strokeColor": "#1e1e1e", 2514 | "backgroundColor": "#ffffff", 2515 | "fillStyle": "solid", 2516 | "strokeWidth": 1, 2517 | "strokeStyle": "solid", 2518 | "roughness": 0, 2519 | "opacity": 100, 2520 | "groupIds": [], 2521 | "frameId": null, 2522 | "index": "b0C", 2523 | "roundness": { 2524 | "type": 3 2525 | }, 2526 | "seed": 451548749, 2527 | "version": 722, 2528 | "versionNonce": 523202805, 2529 | "isDeleted": false, 2530 | "boundElements": [ 2531 | { 2532 | "id": "5tIiOND2EJlrG52De3O8e", 2533 | "type": "text" 2534 | } 2535 | ], 2536 | "updated": 1744314594827, 2537 | "link": null, 2538 | "locked": false 2539 | }, 2540 | { 2541 | "id": "5tIiOND2EJlrG52De3O8e", 2542 | "type": "text", 2543 | "x": -1399.26427304848, 2544 | "y": -24516.709216489326, 2545 | "width": 33.9375, 2546 | "height": 25, 2547 | "angle": 0, 2548 | "strokeColor": "#1e1e1e", 2549 | "backgroundColor": "#ffffff", 2550 | "fillStyle": "solid", 2551 | "strokeWidth": 1, 2552 | "strokeStyle": "solid", 2553 | "roughness": 0, 2554 | "opacity": 100, 2555 | "groupIds": [], 2556 | "frameId": null, 2557 | "index": "b0D", 2558 | "roundness": null, 2559 | "seed": 1733018797, 2560 | "version": 695, 2561 | "versionNonce": 1114899675, 2562 | "isDeleted": false, 2563 | "boundElements": [], 2564 | "updated": 1744314594828, 2565 | "link": null, 2566 | "locked": false, 2567 | "text": "Job", 2568 | "fontSize": 20, 2569 | "fontFamily": 1, 2570 | "textAlign": "center", 2571 | "verticalAlign": "middle", 2572 | "containerId": "OYOEWehqukIgdqFlEh9kF", 2573 | "originalText": "Job", 2574 | "autoResize": true, 2575 | "lineHeight": 1.25 2576 | }, 2577 | { 2578 | "id": "L7vuQcO-v6bs4JkmLHLo8", 2579 | "type": "rectangle", 2580 | "x": -1437.8685309298126, 2581 | "y": -24570.70062530993, 2582 | "width": 104.353768665801, 2583 | "height": 35, 2584 | "angle": 0, 2585 | "strokeColor": "#1e1e1e", 2586 | "backgroundColor": "#ffffff", 2587 | "fillStyle": "solid", 2588 | "strokeWidth": 1, 2589 | "strokeStyle": "solid", 2590 | "roughness": 0, 2591 | "opacity": 100, 2592 | "groupIds": [], 2593 | "frameId": null, 2594 | "index": "b0E", 2595 | "roundness": { 2596 | "type": 3 2597 | }, 2598 | "seed": 1814603533, 2599 | "version": 493, 2600 | "versionNonce": 367336571, 2601 | "isDeleted": false, 2602 | "boundElements": [ 2603 | { 2604 | "id": "BMoH0AsJmrXCmldeZqnrt", 2605 | "type": "text" 2606 | } 2607 | ], 2608 | "updated": 1744314594733, 2609 | "link": null, 2610 | "locked": false 2611 | }, 2612 | { 2613 | "id": "BMoH0AsJmrXCmldeZqnrt", 2614 | "type": "text", 2615 | "x": -1402.660396596912, 2616 | "y": -24565.70062530993, 2617 | "width": 33.9375, 2618 | "height": 25, 2619 | "angle": 0, 2620 | "strokeColor": "#1e1e1e", 2621 | "backgroundColor": "#ffffff", 2622 | "fillStyle": "solid", 2623 | "strokeWidth": 1, 2624 | "strokeStyle": "solid", 2625 | "roughness": 0, 2626 | "opacity": 100, 2627 | "groupIds": [], 2628 | "frameId": null, 2629 | "index": "b0F", 2630 | "roundness": null, 2631 | "seed": 1543126381, 2632 | "version": 465, 2633 | "versionNonce": 2078620853, 2634 | "isDeleted": false, 2635 | "boundElements": [], 2636 | "updated": 1744314594733, 2637 | "link": null, 2638 | "locked": false, 2639 | "text": "Job", 2640 | "fontSize": 20, 2641 | "fontFamily": 1, 2642 | "textAlign": "center", 2643 | "verticalAlign": "middle", 2644 | "containerId": "L7vuQcO-v6bs4JkmLHLo8", 2645 | "originalText": "Job", 2646 | "autoResize": true, 2647 | "lineHeight": 1.25 2648 | }, 2649 | { 2650 | "id": "doC1cHSiUDQs1pJQHf7un", 2651 | "type": "rectangle", 2652 | "x": -1437.8685309298126, 2653 | "y": -24620.716322981178, 2654 | "width": 104.353768665801, 2655 | "height": 35, 2656 | "angle": 0, 2657 | "strokeColor": "#1e1e1e", 2658 | "backgroundColor": "#ffffff", 2659 | "fillStyle": "solid", 2660 | "strokeWidth": 1, 2661 | "strokeStyle": "solid", 2662 | "roughness": 0, 2663 | "opacity": 100, 2664 | "groupIds": [], 2665 | "frameId": null, 2666 | "index": "b0G", 2667 | "roundness": { 2668 | "type": 3 2669 | }, 2670 | "seed": 1577715661, 2671 | "version": 1006, 2672 | "versionNonce": 243062107, 2673 | "isDeleted": false, 2674 | "boundElements": [ 2675 | { 2676 | "type": "text", 2677 | "id": "AjgCXlL8gHJW901Mz4zgP" 2678 | } 2679 | ], 2680 | "updated": 1744314594669, 2681 | "link": null, 2682 | "locked": false 2683 | }, 2684 | { 2685 | "id": "AjgCXlL8gHJW901Mz4zgP", 2686 | "type": "text", 2687 | "x": -1402.660396596912, 2688 | "y": -24615.716322981178, 2689 | "width": 33.9375, 2690 | "height": 25, 2691 | "angle": 0, 2692 | "strokeColor": "#1e1e1e", 2693 | "backgroundColor": "#ffffff", 2694 | "fillStyle": "solid", 2695 | "strokeWidth": 1, 2696 | "strokeStyle": "solid", 2697 | "roughness": 0, 2698 | "opacity": 100, 2699 | "groupIds": [], 2700 | "frameId": null, 2701 | "index": "b0H", 2702 | "roundness": null, 2703 | "seed": 1953596973, 2704 | "version": 978, 2705 | "versionNonce": 1147797973, 2706 | "isDeleted": false, 2707 | "boundElements": [], 2708 | "updated": 1744314594669, 2709 | "link": null, 2710 | "locked": false, 2711 | "text": "Job", 2712 | "fontSize": 20, 2713 | "fontFamily": 1, 2714 | "textAlign": "center", 2715 | "verticalAlign": "middle", 2716 | "containerId": "doC1cHSiUDQs1pJQHf7un", 2717 | "originalText": "Job", 2718 | "autoResize": true, 2719 | "lineHeight": 1.25 2720 | }, 2721 | { 2722 | "id": "fKf47JDEStq0VdLOcyEzY", 2723 | "type": "rectangle", 2724 | "x": -1439.7209833697862, 2725 | "y": -24671.34953620562, 2726 | "width": 104.353768665801, 2727 | "height": 35, 2728 | "angle": 0, 2729 | "strokeColor": "#1e1e1e", 2730 | "backgroundColor": "#ffffff", 2731 | "fillStyle": "solid", 2732 | "strokeWidth": 1, 2733 | "strokeStyle": "solid", 2734 | "roughness": 0, 2735 | "opacity": 100, 2736 | "groupIds": [], 2737 | "frameId": null, 2738 | "index": "b0I", 2739 | "roundness": { 2740 | "type": 3 2741 | }, 2742 | "seed": 572143757, 2743 | "version": 369, 2744 | "versionNonce": 1093699451, 2745 | "isDeleted": false, 2746 | "boundElements": [ 2747 | { 2748 | "id": "fWCKzThCO7gi15cJchfpI", 2749 | "type": "text" 2750 | } 2751 | ], 2752 | "updated": 1744314594606, 2753 | "link": null, 2754 | "locked": false 2755 | }, 2756 | { 2757 | "id": "fWCKzThCO7gi15cJchfpI", 2758 | "type": "text", 2759 | "x": -1404.5128490368857, 2760 | "y": -24666.34953620562, 2761 | "width": 33.9375, 2762 | "height": 25, 2763 | "angle": 0, 2764 | "strokeColor": "#1e1e1e", 2765 | "backgroundColor": "#ffffff", 2766 | "fillStyle": "solid", 2767 | "strokeWidth": 1, 2768 | "strokeStyle": "solid", 2769 | "roughness": 0, 2770 | "opacity": 100, 2771 | "groupIds": [], 2772 | "frameId": null, 2773 | "index": "b0J", 2774 | "roundness": null, 2775 | "seed": 1354604269, 2776 | "version": 341, 2777 | "versionNonce": 228196789, 2778 | "isDeleted": false, 2779 | "boundElements": [], 2780 | "updated": 1744314594606, 2781 | "link": null, 2782 | "locked": false, 2783 | "text": "Job", 2784 | "fontSize": 20, 2785 | "fontFamily": 1, 2786 | "textAlign": "center", 2787 | "verticalAlign": "middle", 2788 | "containerId": "fKf47JDEStq0VdLOcyEzY", 2789 | "originalText": "Job", 2790 | "autoResize": true, 2791 | "lineHeight": 1.25 2792 | }, 2793 | { 2794 | "id": "c4cGFouAm6aonYBWOfnFi", 2795 | "type": "rectangle", 2796 | "x": -1438.486046483019, 2797 | "y": -24719.512781436883, 2798 | "width": 104.353768665801, 2799 | "height": 35, 2800 | "angle": 0, 2801 | "strokeColor": "#1e1e1e", 2802 | "backgroundColor": "#ffffff", 2803 | "fillStyle": "solid", 2804 | "strokeWidth": 1, 2805 | "strokeStyle": "solid", 2806 | "roughness": 0, 2807 | "opacity": 100, 2808 | "groupIds": [], 2809 | "frameId": null, 2810 | "index": "b0K", 2811 | "roundness": { 2812 | "type": 3 2813 | }, 2814 | "seed": 1994733901, 2815 | "version": 410, 2816 | "versionNonce": 1384020725, 2817 | "isDeleted": false, 2818 | "boundElements": [ 2819 | { 2820 | "id": "_ARYjVAaKA8up6kYwv-lF", 2821 | "type": "text" 2822 | } 2823 | ], 2824 | "updated": 1744314594093, 2825 | "link": null, 2826 | "locked": false 2827 | }, 2828 | { 2829 | "id": "_ARYjVAaKA8up6kYwv-lF", 2830 | "type": "text", 2831 | "x": -1403.2779121501185, 2832 | "y": -24714.512781436883, 2833 | "width": 33.9375, 2834 | "height": 25, 2835 | "angle": 0, 2836 | "strokeColor": "#1e1e1e", 2837 | "backgroundColor": "#ffffff", 2838 | "fillStyle": "solid", 2839 | "strokeWidth": 1, 2840 | "strokeStyle": "solid", 2841 | "roughness": 0, 2842 | "opacity": 100, 2843 | "groupIds": [], 2844 | "frameId": null, 2845 | "index": "b0L", 2846 | "roundness": null, 2847 | "seed": 2112522157, 2848 | "version": 382, 2849 | "versionNonce": 1995610843, 2850 | "isDeleted": false, 2851 | "boundElements": [], 2852 | "updated": 1744314594093, 2853 | "link": null, 2854 | "locked": false, 2855 | "text": "Job", 2856 | "fontSize": 20, 2857 | "fontFamily": 1, 2858 | "textAlign": "center", 2859 | "verticalAlign": "middle", 2860 | "containerId": "c4cGFouAm6aonYBWOfnFi", 2861 | "originalText": "Job", 2862 | "autoResize": true, 2863 | "lineHeight": 1.25 2864 | }, 2865 | { 2866 | "id": "5K228gHv2rZ6AnUGn7sto", 2867 | "type": "rectangle", 2868 | "x": -1439.1035149264026, 2869 | "y": -24773.233383988067, 2870 | "width": 104.353768665801, 2871 | "height": 35, 2872 | "angle": 0, 2873 | "strokeColor": "#1e1e1e", 2874 | "backgroundColor": "#ffffff", 2875 | "fillStyle": "solid", 2876 | "strokeWidth": 1, 2877 | "strokeStyle": "solid", 2878 | "roughness": 0, 2879 | "opacity": 100, 2880 | "groupIds": [], 2881 | "frameId": null, 2882 | "index": "b0M", 2883 | "roundness": { 2884 | "type": 3 2885 | }, 2886 | "seed": 1744243213, 2887 | "version": 466, 2888 | "versionNonce": 128517531, 2889 | "isDeleted": false, 2890 | "boundElements": [ 2891 | { 2892 | "id": "FtZSlexO3GkXCkNiMqyWQ", 2893 | "type": "text" 2894 | } 2895 | ], 2896 | "updated": 1744314593838, 2897 | "link": null, 2898 | "locked": false 2899 | }, 2900 | { 2901 | "id": "FtZSlexO3GkXCkNiMqyWQ", 2902 | "type": "text", 2903 | "x": -1403.895380593502, 2904 | "y": -24768.233383988067, 2905 | "width": 33.9375, 2906 | "height": 25, 2907 | "angle": 0, 2908 | "strokeColor": "#1e1e1e", 2909 | "backgroundColor": "#ffffff", 2910 | "fillStyle": "solid", 2911 | "strokeWidth": 1, 2912 | "strokeStyle": "solid", 2913 | "roughness": 0, 2914 | "opacity": 100, 2915 | "groupIds": [], 2916 | "frameId": null, 2917 | "index": "b0N", 2918 | "roundness": null, 2919 | "seed": 906248301, 2920 | "version": 438, 2921 | "versionNonce": 1736963477, 2922 | "isDeleted": false, 2923 | "boundElements": [], 2924 | "updated": 1744314593838, 2925 | "link": null, 2926 | "locked": false, 2927 | "text": "Job", 2928 | "fontSize": 20, 2929 | "fontFamily": 1, 2930 | "textAlign": "center", 2931 | "verticalAlign": "middle", 2932 | "containerId": "5K228gHv2rZ6AnUGn7sto", 2933 | "originalText": "Job", 2934 | "autoResize": true, 2935 | "lineHeight": 1.25 2936 | }, 2937 | { 2938 | "id": "GzhPij65cNBIFfOV6h9cF", 2939 | "type": "arrow", 2940 | "x": -1359.4591578796221, 2941 | "y": -24456.81387061699, 2942 | "width": 305.1016347115319, 2943 | "height": 83.95231473265812, 2944 | "angle": 0, 2945 | "strokeColor": "#1e1e1e", 2946 | "backgroundColor": "#ffffff", 2947 | "fillStyle": "solid", 2948 | "strokeWidth": 1, 2949 | "strokeStyle": "solid", 2950 | "roughness": 0, 2951 | "opacity": 100, 2952 | "groupIds": [], 2953 | "frameId": null, 2954 | "index": "b0O", 2955 | "roundness": null, 2956 | "seed": 232499917, 2957 | "version": 959, 2958 | "versionNonce": 479471437, 2959 | "isDeleted": false, 2960 | "boundElements": [ 2961 | { 2962 | "type": "text", 2963 | "id": "3upbhD9An4tD0jSHih6xc" 2964 | } 2965 | ], 2966 | "updated": 1743709358241, 2967 | "link": null, 2968 | "locked": false, 2969 | "points": [ 2970 | [ 2971 | 0, 2972 | 0 2973 | ], 2974 | [ 2975 | 0, 2976 | 34.99999999999636 2977 | ], 2978 | [ 2979 | 305.1016347115319, 2980 | 34.99999999999636 2981 | ], 2982 | [ 2983 | 305.1016347115319, 2984 | -48.95231473266176 2985 | ] 2986 | ], 2987 | "lastCommittedPoint": null, 2988 | "startBinding": { 2989 | "elementId": "7PGPskS9XCDfHTMyTnJkl", 2990 | "focus": 0.8119002872294115, 2991 | "gap": 4.322337990925007, 2992 | "fixedPoint": [ 2993 | 0.6645138821655954, 2994 | 1.0100216041278685 2995 | ] 2996 | }, 2997 | "endBinding": { 2998 | "elementId": "030wLkFO0DV-OgA3dcdba", 2999 | "focus": 0.001051617590582116, 3000 | "gap": 4.999998516511315, 3001 | "fixedPoint": [ 3002 | 0.4994741912046966, 3003 | 1.0352060550467774 3004 | ] 3005 | }, 3006 | "startArrowhead": null, 3007 | "endArrowhead": "arrow", 3008 | "elbowed": true, 3009 | "fixedSegments": null, 3010 | "startIsSpecial": null, 3011 | "endIsSpecial": null 3012 | }, 3013 | { 3014 | "id": "3upbhD9An4tD0jSHih6xc", 3015 | "type": "text", 3016 | "x": 1930.2610963257077, 3017 | "y": -24344.69682696021, 3018 | "width": 128.625, 3019 | "height": 25, 3020 | "angle": 0, 3021 | "strokeColor": "#1e1e1e", 3022 | "backgroundColor": "#ffffff", 3023 | "fillStyle": "solid", 3024 | "strokeWidth": 1, 3025 | "strokeStyle": "solid", 3026 | "roughness": 0, 3027 | "opacity": 100, 3028 | "groupIds": [], 3029 | "frameId": null, 3030 | "index": "b0P", 3031 | "roundness": null, 3032 | "seed": 538364205, 3033 | "version": 18, 3034 | "versionNonce": 1475588003, 3035 | "isDeleted": false, 3036 | "boundElements": [], 3037 | "updated": 1743709274648, 3038 | "link": null, 3039 | "locked": false, 3040 | "text": "Get next job", 3041 | "fontSize": 20, 3042 | "fontFamily": 1, 3043 | "textAlign": "center", 3044 | "verticalAlign": "middle", 3045 | "containerId": "GzhPij65cNBIFfOV6h9cF", 3046 | "originalText": "Get next job", 3047 | "autoResize": true, 3048 | "lineHeight": 1.25 3049 | }, 3050 | { 3051 | "id": "GzNwUmA1K_0cc1HmMbCN2", 3052 | "type": "ellipse", 3053 | "x": -1153.36238156615, 3054 | "y": -24923.527958519237, 3055 | "width": 202.8306669107078, 3056 | "height": 164.86233994614668, 3057 | "angle": 0, 3058 | "strokeColor": "#1e1e1e", 3059 | "backgroundColor": "#ffffff", 3060 | "fillStyle": "solid", 3061 | "strokeWidth": 1, 3062 | "strokeStyle": "solid", 3063 | "roughness": 0, 3064 | "opacity": 100, 3065 | "groupIds": [], 3066 | "frameId": null, 3067 | "index": "b0Q", 3068 | "roundness": { 3069 | "type": 2 3070 | }, 3071 | "seed": 284970605, 3072 | "version": 402, 3073 | "versionNonce": 730576301, 3074 | "isDeleted": false, 3075 | "boundElements": [ 3076 | { 3077 | "type": "text", 3078 | "id": "RuK0viwgmpOmtag-wBnDT" 3079 | }, 3080 | { 3081 | "id": "W8AHtVFQmCMidlUBb3GpJ", 3082 | "type": "arrow" 3083 | } 3084 | ], 3085 | "updated": 1743709358241, 3086 | "link": null, 3087 | "locked": false 3088 | }, 3089 | { 3090 | "id": "RuK0viwgmpOmtag-wBnDT", 3091 | "type": "text", 3092 | "x": -1090.9293501751395, 3093 | "y": -24853.384427815265, 3094 | "width": 77.54166412353516, 3095 | "height": 25, 3096 | "angle": 0, 3097 | "strokeColor": "#1e1e1e", 3098 | "backgroundColor": "#ffffff", 3099 | "fillStyle": "solid", 3100 | "strokeWidth": 1, 3101 | "strokeStyle": "solid", 3102 | "roughness": 0, 3103 | "opacity": 100, 3104 | "groupIds": [], 3105 | "frameId": null, 3106 | "index": "b0R", 3107 | "roundness": null, 3108 | "seed": 1069322893, 3109 | "version": 363, 3110 | "versionNonce": 1698854925, 3111 | "isDeleted": false, 3112 | "boundElements": [], 3113 | "updated": 1743709358241, 3114 | "link": null, 3115 | "locked": false, 3116 | "text": "Program", 3117 | "fontSize": 20, 3118 | "fontFamily": 1, 3119 | "textAlign": "center", 3120 | "verticalAlign": "middle", 3121 | "containerId": "GzNwUmA1K_0cc1HmMbCN2", 3122 | "originalText": "Program", 3123 | "autoResize": true, 3124 | "lineHeight": 1.25 3125 | }, 3126 | { 3127 | "id": "W8AHtVFQmCMidlUBb3GpJ", 3128 | "type": "arrow", 3129 | "x": -1052.047048110796, 3130 | "y": -24928.52791844601, 3131 | "width": 339.9821913068022, 3132 | "height": 55.261925777900615, 3133 | "angle": 0, 3134 | "strokeColor": "#1e1e1e", 3135 | "backgroundColor": "#ffffff", 3136 | "fillStyle": "solid", 3137 | "strokeWidth": 1, 3138 | "strokeStyle": "solid", 3139 | "roughness": 0, 3140 | "opacity": 100, 3141 | "groupIds": [], 3142 | "frameId": null, 3143 | "index": "b0S", 3144 | "roundness": null, 3145 | "seed": 867515363, 3146 | "version": 1008, 3147 | "versionNonce": 94607565, 3148 | "isDeleted": false, 3149 | "boundElements": [ 3150 | { 3151 | "type": "text", 3152 | "id": "3HzTmvOw6GssROhd871Hq" 3153 | } 3154 | ], 3155 | "updated": 1743709358241, 3156 | "link": null, 3157 | "locked": false, 3158 | "points": [ 3159 | [ 3160 | 0, 3161 | 0 3162 | ], 3163 | [ 3164 | 0, 3165 | -55.261925777900615 3166 | ], 3167 | [ 3168 | -339.9821913068022, 3169 | -55.261925777900615 3170 | ], 3171 | [ 3172 | -339.9821913068022, 3173 | -37.20807443876038 3174 | ] 3175 | ], 3176 | "lastCommittedPoint": null, 3177 | "startBinding": { 3178 | "elementId": "GzNwUmA1K_0cc1HmMbCN2", 3179 | "focus": -0.0009860441867194964, 3180 | "gap": 4.999998456007448, 3181 | "fixedPoint": [ 3182 | 0.4995069779066302, 3183 | -0.030328090262490535 3184 | ] 3185 | }, 3186 | "endBinding": { 3187 | "elementId": "7PGPskS9XCDfHTMyTnJkl", 3188 | "focus": -1.0200432082557374, 3189 | "gap": 5.000000000003638, 3190 | "fixedPoint": [ 3191 | 0.4447348735716837, 3192 | -0.010021604127868516 3193 | ] 3194 | }, 3195 | "startArrowhead": null, 3196 | "endArrowhead": "arrow", 3197 | "elbowed": true, 3198 | "fixedSegments": [ 3199 | { 3200 | "index": 2, 3201 | "start": [ 3202 | 0, 3203 | -55.261925777900615 3204 | ], 3205 | "end": [ 3206 | -339.9821913068022, 3207 | -55.261925777900615 3208 | ] 3209 | } 3210 | ], 3211 | "startIsSpecial": false, 3212 | "endIsSpecial": false 3213 | }, 3214 | { 3215 | "id": "3HzTmvOw6GssROhd871Hq", 3216 | "type": "text", 3217 | "x": 1783.8407758384528, 3218 | "y": -25054.613874617375, 3219 | "width": 79.8125, 3220 | "height": 25, 3221 | "angle": 0, 3222 | "strokeColor": "#1e1e1e", 3223 | "backgroundColor": "#ffffff", 3224 | "fillStyle": "solid", 3225 | "strokeWidth": 1, 3226 | "strokeStyle": "solid", 3227 | "roughness": 0, 3228 | "opacity": 100, 3229 | "groupIds": [], 3230 | "frameId": null, 3231 | "index": "b0T", 3232 | "roundness": null, 3233 | "seed": 1964917667, 3234 | "version": 9, 3235 | "versionNonce": 1888363587, 3236 | "isDeleted": false, 3237 | "boundElements": [], 3238 | "updated": 1743709293480, 3239 | "link": null, 3240 | "locked": false, 3241 | "text": "Add Job", 3242 | "fontSize": 20, 3243 | "fontFamily": 1, 3244 | "textAlign": "center", 3245 | "verticalAlign": "middle", 3246 | "containerId": "W8AHtVFQmCMidlUBb3GpJ", 3247 | "originalText": "Add Job", 3248 | "autoResize": true, 3249 | "lineHeight": 1.25 3250 | }, 3251 | { 3252 | "id": "H70LjtCjiTOBzplcYrcSY", 3253 | "type": "rectangle", 3254 | "x": -2386.0080718124586, 3255 | "y": -24893.011090208503, 3256 | "width": 546.3775427389114, 3257 | "height": 35, 3258 | "angle": 0, 3259 | "strokeColor": "#1e1e1e", 3260 | "backgroundColor": "#a5d8ff", 3261 | "fillStyle": "hachure", 3262 | "strokeWidth": 2, 3263 | "strokeStyle": "solid", 3264 | "roughness": 0, 3265 | "opacity": 100, 3266 | "groupIds": [], 3267 | "frameId": null, 3268 | "index": "b0U", 3269 | "roundness": { 3270 | "type": 3 3271 | }, 3272 | "seed": 659041729, 3273 | "version": 890, 3274 | "versionNonce": 1919835739, 3275 | "isDeleted": false, 3276 | "boundElements": [ 3277 | { 3278 | "type": "text", 3279 | "id": "BaipQa9aBZmdPPaazJsjG" 3280 | } 3281 | ], 3282 | "updated": 1744314600351, 3283 | "link": null, 3284 | "locked": false 3285 | }, 3286 | { 3287 | "id": "BaipQa9aBZmdPPaazJsjG", 3288 | "type": "text", 3289 | "x": -2152.7463825047707, 3290 | "y": -24888.011090208503, 3291 | "width": 79.85416412353516, 3292 | "height": 25, 3293 | "angle": 0, 3294 | "strokeColor": "#1e1e1e", 3295 | "backgroundColor": "#a5d8ff", 3296 | "fillStyle": "hachure", 3297 | "strokeWidth": 2, 3298 | "strokeStyle": "solid", 3299 | "roughness": 0, 3300 | "opacity": 100, 3301 | "groupIds": [], 3302 | "frameId": null, 3303 | "index": "b0V", 3304 | "roundness": null, 3305 | "seed": 1228430735, 3306 | "version": 404, 3307 | "versionNonce": 2029095125, 3308 | "isDeleted": false, 3309 | "boundElements": [], 3310 | "updated": 1744314600351, 3311 | "link": null, 3312 | "locked": false, 3313 | "text": "Request", 3314 | "fontSize": 20, 3315 | "fontFamily": 1, 3316 | "textAlign": "center", 3317 | "verticalAlign": "middle", 3318 | "containerId": "H70LjtCjiTOBzplcYrcSY", 3319 | "originalText": "Request", 3320 | "autoResize": true, 3321 | "lineHeight": 1.25 3322 | }, 3323 | { 3324 | "id": "ZTX035Fz4lCASsqhp6TQa", 3325 | "type": "rectangle", 3326 | "x": -2388.3047057003782, 3327 | "y": -24853.783390416786, 3328 | "width": 112.5083140332494, 3329 | "height": 35, 3330 | "angle": 0, 3331 | "strokeColor": "#1e1e1e", 3332 | "backgroundColor": "#b2f2bb", 3333 | "fillStyle": "hachure", 3334 | "strokeWidth": 2, 3335 | "strokeStyle": "solid", 3336 | "roughness": 0, 3337 | "opacity": 100, 3338 | "groupIds": [], 3339 | "frameId": null, 3340 | "index": "b0W", 3341 | "roundness": { 3342 | "type": 3 3343 | }, 3344 | "seed": 324869377, 3345 | "version": 345, 3346 | "versionNonce": 1793766799, 3347 | "isDeleted": false, 3348 | "boundElements": [ 3349 | { 3350 | "type": "text", 3351 | "id": "qY0B0sqaZOerc1Ge4bpa1" 3352 | } 3353 | ], 3354 | "updated": 1744312093947, 3355 | "link": null, 3356 | "locked": false 3357 | }, 3358 | { 3359 | "id": "qY0B0sqaZOerc1Ge4bpa1", 3360 | "type": "text", 3361 | "x": -2375.5713807455213, 3362 | "y": -24848.783390416786, 3363 | "width": 87.04166412353516, 3364 | "height": 25, 3365 | "angle": 0, 3366 | "strokeColor": "#1e1e1e", 3367 | "backgroundColor": "#a5d8ff", 3368 | "fillStyle": "hachure", 3369 | "strokeWidth": 2, 3370 | "strokeStyle": "solid", 3371 | "roughness": 0, 3372 | "opacity": 100, 3373 | "groupIds": [], 3374 | "frameId": null, 3375 | "index": "b0X", 3376 | "roundness": null, 3377 | "seed": 2011367215, 3378 | "version": 80, 3379 | "versionNonce": 432437871, 3380 | "isDeleted": false, 3381 | "boundElements": [], 3382 | "updated": 1744312080513, 3383 | "link": null, 3384 | "locked": false, 3385 | "text": "Save DB", 3386 | "fontSize": 20, 3387 | "fontFamily": 1, 3388 | "textAlign": "center", 3389 | "verticalAlign": "middle", 3390 | "containerId": "ZTX035Fz4lCASsqhp6TQa", 3391 | "originalText": "Save DB", 3392 | "autoResize": true, 3393 | "lineHeight": 1.25 3394 | }, 3395 | { 3396 | "id": "WpuIiR_DIcHD56eobMEyM", 3397 | "type": "rectangle", 3398 | "x": -2271.937753273637, 3399 | "y": -24853.8181865543, 3400 | "width": 165.71618573609152, 3401 | "height": 35, 3402 | "angle": 0, 3403 | "strokeColor": "#1e1e1e", 3404 | "backgroundColor": "#ffc9c9", 3405 | "fillStyle": "hachure", 3406 | "strokeWidth": 2, 3407 | "strokeStyle": "solid", 3408 | "roughness": 0, 3409 | "opacity": 100, 3410 | "groupIds": [], 3411 | "frameId": null, 3412 | "index": "b0Y", 3413 | "roundness": { 3414 | "type": 3 3415 | }, 3416 | "seed": 1713159375, 3417 | "version": 466, 3418 | "versionNonce": 84935457, 3419 | "isDeleted": false, 3420 | "boundElements": [ 3421 | { 3422 | "type": "text", 3423 | "id": "n4mX6D_s-1mt_FiIx7IJe" 3424 | } 3425 | ], 3426 | "updated": 1744312092763, 3427 | "link": null, 3428 | "locked": false 3429 | }, 3430 | { 3431 | "id": "n4mX6D_s-1mt_FiIx7IJe", 3432 | "type": "text", 3433 | "x": -2253.6525745291265, 3434 | "y": -24848.8181865543, 3435 | "width": 129.1458282470703, 3436 | "height": 25, 3437 | "angle": 0, 3438 | "strokeColor": "#1e1e1e", 3439 | "backgroundColor": "#a5d8ff", 3440 | "fillStyle": "hachure", 3441 | "strokeWidth": 2, 3442 | "strokeStyle": "solid", 3443 | "roughness": 0, 3444 | "opacity": 100, 3445 | "groupIds": [], 3446 | "frameId": null, 3447 | "index": "b0Z", 3448 | "roundness": null, 3449 | "seed": 1210731247, 3450 | "version": 215, 3451 | "versionNonce": 1121827631, 3452 | "isDeleted": false, 3453 | "boundElements": [], 3454 | "updated": 1744312090699, 3455 | "link": null, 3456 | "locked": false, 3457 | "text": "Render HTML", 3458 | "fontSize": 20, 3459 | "fontFamily": 1, 3460 | "textAlign": "center", 3461 | "verticalAlign": "middle", 3462 | "containerId": "WpuIiR_DIcHD56eobMEyM", 3463 | "originalText": "Render HTML", 3464 | "autoResize": true, 3465 | "lineHeight": 1.25 3466 | }, 3467 | { 3468 | "id": "rpb2424iDVm9tMT6NXeHS", 3469 | "type": "rectangle", 3470 | "x": -2103.5814742576686, 3471 | "y": -24854.63052413996, 3472 | "width": 264.8210303173066, 3473 | "height": 35, 3474 | "angle": 0, 3475 | "strokeColor": "#1e1e1e", 3476 | "backgroundColor": "#ffc9c9", 3477 | "fillStyle": "hachure", 3478 | "strokeWidth": 2, 3479 | "strokeStyle": "solid", 3480 | "roughness": 0, 3481 | "opacity": 100, 3482 | "groupIds": [], 3483 | "frameId": null, 3484 | "index": "b0a", 3485 | "roundness": { 3486 | "type": 3 3487 | }, 3488 | "seed": 542723055, 3489 | "version": 2073, 3490 | "versionNonce": 1430832027, 3491 | "isDeleted": false, 3492 | "boundElements": [ 3493 | { 3494 | "type": "text", 3495 | "id": "QSeuuWKRse1a1Ij28Amv8" 3496 | } 3497 | ], 3498 | "updated": 1744314600722, 3499 | "link": null, 3500 | "locked": false 3501 | }, 3502 | { 3503 | "id": "QSeuuWKRse1a1Ij28Amv8", 3504 | "type": "text", 3505 | "x": -2022.629291160783, 3506 | "y": -24849.63052413996, 3507 | "width": 102.91666412353516, 3508 | "height": 25, 3509 | "angle": 0, 3510 | "strokeColor": "#1e1e1e", 3511 | "backgroundColor": "#a5d8ff", 3512 | "fillStyle": "hachure", 3513 | "strokeWidth": 2, 3514 | "strokeStyle": "solid", 3515 | "roughness": 0, 3516 | "opacity": 100, 3517 | "groupIds": [], 3518 | "frameId": null, 3519 | "index": "b0b", 3520 | "roundness": null, 3521 | "seed": 642250255, 3522 | "version": 1838, 3523 | "versionNonce": 323688341, 3524 | "isDeleted": false, 3525 | "boundElements": [], 3526 | "updated": 1744314600722, 3527 | "link": null, 3528 | "locked": false, 3529 | "text": "Send Email", 3530 | "fontSize": 20, 3531 | "fontFamily": 1, 3532 | "textAlign": "center", 3533 | "verticalAlign": "middle", 3534 | "containerId": "rpb2424iDVm9tMT6NXeHS", 3535 | "originalText": "Send Email", 3536 | "autoResize": true, 3537 | "lineHeight": 1.25 3538 | } 3539 | ], 3540 | "appState": { 3541 | "gridSize": 20, 3542 | "gridStep": 5, 3543 | "gridModeEnabled": false, 3544 | "viewBackgroundColor": "#ffffff" 3545 | }, 3546 | "files": {} 3547 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 WebDevSimplified 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | services: 2 | redis: 3 | image: redis:latest 4 | container_name: redis-job-queue 5 | restart: always 6 | ports: 7 | - "6379:6379" 8 | volumes: 9 | - redis_data:/data 10 | command: ["redis-server", "--notify-keyspace-events", "Ex"] 11 | 12 | volumes: 13 | redis_data: 14 | driver: local 15 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "job-queue", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "dev": "nodemon --watch src --exec ts-node src/index.ts", 7 | "inspect": "redis-commander" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "description": "", 13 | "devDependencies": { 14 | "@types/node": "^22.13.17", 15 | "nodemon": "^3.1.9", 16 | "redis-commander": "^0.8.0", 17 | "ts-node": "^10.9.2", 18 | "typescript": "^5.8.2" 19 | }, 20 | "dependencies": { 21 | "ioredis": "^5.6.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import { RedisQueue } from "./job-queue/redis-adapter" 2 | import { Worker } from "./job-queue/worker" 3 | 4 | const queue = new RedisQueue<{ email: string; body: string }>( 5 | "redis://localhost:6379", 6 | "test-queue", 7 | { 8 | retryAttempts: 3, 9 | retryDelay: 1000, 10 | } 11 | ) 12 | 13 | queue.addJob({ 14 | data: { email: "test@test.com", body: "Hi" }, 15 | name: "1", 16 | options: { 17 | priority: 1, 18 | }, 19 | }) 20 | 21 | queue.addJob({ 22 | data: { email: "test@test.com", body: "Bye" }, 23 | name: "2", 24 | options: { 25 | priority: 3, 26 | delay: 1000, 27 | }, 28 | }) 29 | 30 | queue.addJob({ 31 | data: { email: "test2@test.com", body: "Hello World" }, 32 | name: "3", 33 | options: { 34 | priority: 2, 35 | }, 36 | }) 37 | 38 | queue.addJob({ 39 | data: { email: "test2@test.com", body: "Error" }, 40 | name: "4", 41 | }) 42 | 43 | setTimeout(() => { 44 | queue.addJob({ 45 | data: { email: "test@test.com", body: "High Priority" }, 46 | name: "5", 47 | options: { 48 | priority: 5, 49 | }, 50 | }) 51 | }, 2000) 52 | 53 | const worker = new Worker( 54 | queue, 55 | async job => { 56 | console.log(`Start: W1 ${job.name}`) 57 | await sendEmail(job.data.email, job.data.body) 58 | }, 59 | { concurrency: 3 } 60 | ) 61 | 62 | worker.start() 63 | 64 | function sendEmail(email: string, body: string) { 65 | if (body === "Error") { 66 | console.log(`Error sending email to ${email}`) 67 | throw new Error("Simulated error") 68 | } 69 | return new Promise(resolve => setTimeout(resolve, 1000)) 70 | } 71 | -------------------------------------------------------------------------------- /src/job-queue/queue.ts: -------------------------------------------------------------------------------- 1 | import { Job, JobOptions } from "./types" 2 | 3 | export type QueueOptions = { 4 | retryAttempts: number 5 | retryDelay: number 6 | } 7 | 8 | export type OptionalJobOptions = Partial & { 9 | retry?: Partial 10 | } 11 | 12 | export abstract class Queue { 13 | protected queueName: string 14 | protected options: QueueOptions 15 | 16 | constructor( 17 | queueName: string, 18 | options: QueueOptions = { retryAttempts: 10, retryDelay: 1000 } 19 | ) { 20 | this.queueName = queueName 21 | this.options = options 22 | } 23 | 24 | async addJob( 25 | job: Omit, "id" | "options"> & { 26 | options?: OptionalJobOptions 27 | id?: string 28 | } 29 | ) { 30 | const id = job.id ?? crypto.randomUUID() 31 | if ( 32 | (job.options?.retry?.totalAttempts ?? 0) >= 33 | (job.options?.retry?.maxAttempts ?? 1) 34 | ) { 35 | return id 36 | } 37 | 38 | await this.push({ 39 | ...job, 40 | id, 41 | options: { 42 | delay: job.options?.delay ?? 0, 43 | priority: job.options?.priority ?? 0, 44 | retry: { 45 | totalAttempts: job.options?.retry?.totalAttempts ?? 0, 46 | maxAttempts: 47 | job.options?.retry?.maxAttempts ?? this.options.retryAttempts, 48 | delay: job.options?.retry?.delay ?? this.options.retryDelay, 49 | }, 50 | }, 51 | }) 52 | 53 | return id 54 | } 55 | 56 | protected abstract push( 57 | job: Job & { options: { retry: Required["options"]["retry"]> } } 58 | ): Promise 59 | abstract getOrWaitForJob(): Promise< 60 | | (Job & { options: { retry: Required["options"]["retry"]> } }) 61 | | null 62 | > 63 | abstract get length(): Promise 64 | } 65 | -------------------------------------------------------------------------------- /src/job-queue/redis-adapter.ts: -------------------------------------------------------------------------------- 1 | import IORedis from "ioredis" 2 | import { Job } from "./types" 3 | import { Queue, QueueOptions } from "./queue" 4 | 5 | export class RedisQueue extends Queue { 6 | private redisBlocking: IORedis 7 | private redisNonBlocking: IORedis 8 | private redisSubscriber: IORedis 9 | 10 | constructor(redisUrl: string, queueName: string, options?: QueueOptions) { 11 | super(queueName, options) 12 | 13 | this.redisBlocking = new IORedis(redisUrl) 14 | this.redisNonBlocking = new IORedis(redisUrl) 15 | this.redisSubscriber = new IORedis(redisUrl) 16 | 17 | this.listenForExpiredJobs() 18 | this.checkForExpiredJobs() 19 | } 20 | 21 | get length() { 22 | return this.redisNonBlocking.zcard(this.activeJobsQueue) 23 | } 24 | 25 | async getOrWaitForJob() { 26 | const data = await this.redisBlocking.bzpopmin(this.activeJobsQueue, 0) 27 | return data?.[1] ? JSON.parse(data[1]) : null 28 | } 29 | 30 | protected async push(job: Job) { 31 | if (job.options.delay > 0) { 32 | return await this.redisNonBlocking 33 | .multi() 34 | .set(this.expiringJobIdList(job.id), job.id) 35 | .pexpire(this.expiringJobIdList(job.id), job.options.delay) 36 | .zadd(this.delayedJobIdsQueue, Date.now() + job.options.delay, job.id) 37 | .hset(this.delayedJobsList, job.id, JSON.stringify(job)) 38 | .exec() 39 | } else { 40 | return await this.addActiveJob(job) 41 | } 42 | } 43 | 44 | // Ready to execute jobs sorted by priority 45 | private get activeJobsQueue() { 46 | return `${this.queueName}:active` 47 | } 48 | 49 | // Full job data for delayed jobs 50 | private get delayedJobsList() { 51 | return `${this.queueName}:jobs` 52 | } 53 | 54 | // Delayed job ids sorted by execution date 55 | private get delayedJobIdsQueue() { 56 | return `${this.queueName}:delayed` 57 | } 58 | 59 | // Delayed job ids that will expire after the delay 60 | private expiringJobIdList(jobId: string) { 61 | return `${this.queueName}:expiringJobs:${jobId}` 62 | } 63 | 64 | private async addActiveJob(job: Job) { 65 | return await this.redisNonBlocking.zadd( 66 | this.activeJobsQueue, 67 | (job.options.priority ?? 0) * -1, 68 | JSON.stringify(job) 69 | ) 70 | } 71 | 72 | private async moveJobToActive(jobId: string) { 73 | const job = await this.redisNonBlocking.hget(this.delayedJobsList, jobId) 74 | if (job == null) return 75 | 76 | await this.addActiveJob(JSON.parse(job)) 77 | await this.redisNonBlocking 78 | .multi() 79 | .zrem(this.delayedJobIdsQueue, jobId) 80 | .hdel(this.delayedJobsList, jobId) 81 | .exec() 82 | } 83 | 84 | private async listenForExpiredJobs() { 85 | await this.redisSubscriber.subscribe("__keyevent@0__:expired") 86 | 87 | this.redisSubscriber.on("message", async (channel, message) => { 88 | if (channel !== "__keyevent@0__:expired") return 89 | if (!message.startsWith(this.expiringJobIdList(""))) return 90 | 91 | const jobId = message.split(":").pop() 92 | if (jobId == null) return 93 | 94 | await this.moveJobToActive(jobId) 95 | }) 96 | } 97 | 98 | private async checkForExpiredJobs() { 99 | const expiredJobs = await this.redisNonBlocking.zrangebyscore( 100 | this.delayedJobIdsQueue, 101 | 0, 102 | Date.now() 103 | ) 104 | 105 | for (const jobId of expiredJobs) { 106 | await this.moveJobToActive(jobId) 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/job-queue/types.ts: -------------------------------------------------------------------------------- 1 | export type JobOptions = { 2 | delay: number 3 | priority: number 4 | retry: { 5 | totalAttempts: number 6 | maxAttempts: number 7 | delay: number 8 | } 9 | } 10 | 11 | export type Job = { 12 | id: string 13 | name: string 14 | data: T 15 | options: JobOptions 16 | } 17 | -------------------------------------------------------------------------------- /src/job-queue/worker.ts: -------------------------------------------------------------------------------- 1 | import { Queue } from "./queue" 2 | import { Job } from "./types" 3 | 4 | export class Worker { 5 | private queue: Queue 6 | private processJob: (job: Job) => Promise 7 | private concurrency 8 | private activeJobs: Map> = new Map() 9 | 10 | constructor( 11 | queue: Queue, 12 | processJob: (job: Job) => Promise, 13 | { concurrency = 1 } = {} 14 | ) { 15 | this.processJob = processJob 16 | this.queue = queue 17 | this.concurrency = concurrency 18 | } 19 | 20 | async start() { 21 | while (true) { 22 | const job = await this.queue.getOrWaitForJob() 23 | if (job == null) { 24 | await new Promise(resolve => setTimeout(resolve, 15000)) 25 | } else { 26 | this.activeJobs.set( 27 | job.id, 28 | this.processJob(job) 29 | .catch(async () => { 30 | await this.queue.addJob({ 31 | ...job, 32 | options: { 33 | ...job.options, 34 | retry: { 35 | ...job.options.retry, 36 | totalAttempts: job.options.retry.totalAttempts + 1, 37 | }, 38 | delay: 39 | job.options.retry.delay * 40 | (job.options.retry.totalAttempts + 1) ** 2, 41 | }, 42 | }) 43 | }) 44 | .finally(() => { 45 | this.activeJobs.delete(job.id) 46 | }) 47 | ) 48 | } 49 | if (this.activeJobs.size >= this.concurrency) { 50 | await Promise.any(this.activeJobs.values()) 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Node 22", 4 | "_version": "22.0.0", 5 | 6 | "compilerOptions": { 7 | "lib": ["es2023"], 8 | "module": "nodenext", 9 | "target": "es2022", 10 | 11 | "strict": true, 12 | "esModuleInterop": true, 13 | "skipLibCheck": true, 14 | "moduleResolution": "node16" 15 | } 16 | } 17 | --------------------------------------------------------------------------------