@nest-batch/core 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +368 -0
- package/dist/src/adapters/in-process.adapter.d.ts +140 -0
- package/dist/src/adapters/in-process.adapter.d.ts.map +1 -0
- package/dist/src/adapters/in-process.adapter.js +86 -0
- package/dist/src/adapters/in-process.adapter.js.map +1 -0
- package/dist/src/adapters/index.d.ts +18 -0
- package/dist/src/adapters/index.d.ts.map +1 -0
- package/dist/src/adapters/index.js +35 -0
- package/dist/src/adapters/index.js.map +1 -0
- package/dist/src/builder/batch-builder.d.ts +26 -0
- package/dist/src/builder/batch-builder.d.ts.map +1 -0
- package/dist/src/builder/batch-builder.js +25 -0
- package/dist/src/builder/batch-builder.js.map +1 -0
- package/dist/src/builder/flow-builder.d.ts +59 -0
- package/dist/src/builder/flow-builder.d.ts.map +1 -0
- package/dist/src/builder/flow-builder.js +115 -0
- package/dist/src/builder/flow-builder.js.map +1 -0
- package/dist/src/builder/index.d.ts +5 -0
- package/dist/src/builder/index.d.ts.map +1 -0
- package/dist/src/builder/index.js +23 -0
- package/dist/src/builder/index.js.map +1 -0
- package/dist/src/builder/job-builder.d.ts +76 -0
- package/dist/src/builder/job-builder.d.ts.map +1 -0
- package/dist/src/builder/job-builder.js +166 -0
- package/dist/src/builder/job-builder.js.map +1 -0
- package/dist/src/builder/step-builder.d.ts +74 -0
- package/dist/src/builder/step-builder.d.ts.map +1 -0
- package/dist/src/builder/step-builder.js +144 -0
- package/dist/src/builder/step-builder.js.map +1 -0
- package/dist/src/compiler/builder-types.d.ts +20 -0
- package/dist/src/compiler/builder-types.d.ts.map +1 -0
- package/dist/src/compiler/builder-types.js +6 -0
- package/dist/src/compiler/builder-types.js.map +1 -0
- package/dist/src/compiler/definition-compiler.d.ts +99 -0
- package/dist/src/compiler/definition-compiler.d.ts.map +1 -0
- package/dist/src/compiler/definition-compiler.js +257 -0
- package/dist/src/compiler/definition-compiler.js.map +1 -0
- package/dist/src/compiler/index.d.ts +3 -0
- package/dist/src/compiler/index.d.ts.map +1 -0
- package/dist/src/compiler/index.js +21 -0
- package/dist/src/compiler/index.js.map +1 -0
- package/dist/src/core/errors.d.ts +77 -0
- package/dist/src/core/errors.d.ts.map +1 -0
- package/dist/src/core/errors.js +170 -0
- package/dist/src/core/errors.js.map +1 -0
- package/dist/src/core/execution-context/index.d.ts +4 -0
- package/dist/src/core/execution-context/index.d.ts.map +1 -0
- package/dist/src/core/execution-context/index.js +22 -0
- package/dist/src/core/execution-context/index.js.map +1 -0
- package/dist/src/core/execution-context/json-value.d.ts +5 -0
- package/dist/src/core/execution-context/json-value.d.ts.map +1 -0
- package/dist/src/core/execution-context/json-value.js +6 -0
- package/dist/src/core/execution-context/json-value.js.map +1 -0
- package/dist/src/core/execution-context/serializer.d.ts +4 -0
- package/dist/src/core/execution-context/serializer.d.ts.map +1 -0
- package/dist/src/core/execution-context/serializer.js +34 -0
- package/dist/src/core/execution-context/serializer.js.map +1 -0
- package/dist/src/core/execution-context/validator.d.ts +18 -0
- package/dist/src/core/execution-context/validator.d.ts.map +1 -0
- package/dist/src/core/execution-context/validator.js +90 -0
- package/dist/src/core/execution-context/validator.js.map +1 -0
- package/dist/src/core/index.d.ts +8 -0
- package/dist/src/core/index.d.ts.map +1 -0
- package/dist/src/core/index.js +26 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/core/ir/decider-definition.d.ts +20 -0
- package/dist/src/core/ir/decider-definition.d.ts.map +1 -0
- package/dist/src/core/ir/decider-definition.js +6 -0
- package/dist/src/core/ir/decider-definition.js.map +1 -0
- package/dist/src/core/ir/index.d.ts +8 -0
- package/dist/src/core/ir/index.d.ts.map +1 -0
- package/dist/src/core/ir/index.js +26 -0
- package/dist/src/core/ir/index.js.map +1 -0
- package/dist/src/core/ir/job-definition.d.ts +15 -0
- package/dist/src/core/ir/job-definition.d.ts.map +1 -0
- package/dist/src/core/ir/job-definition.js +6 -0
- package/dist/src/core/ir/job-definition.js.map +1 -0
- package/dist/src/core/ir/listener-definition.d.ts +10 -0
- package/dist/src/core/ir/listener-definition.d.ts.map +1 -0
- package/dist/src/core/ir/listener-definition.js +6 -0
- package/dist/src/core/ir/listener-definition.js.map +1 -0
- package/dist/src/core/ir/policy-config.d.ts +24 -0
- package/dist/src/core/ir/policy-config.d.ts.map +1 -0
- package/dist/src/core/ir/policy-config.js +6 -0
- package/dist/src/core/ir/policy-config.js.map +1 -0
- package/dist/src/core/ir/refs.d.ts +42 -0
- package/dist/src/core/ir/refs.d.ts.map +1 -0
- package/dist/src/core/ir/refs.js +18 -0
- package/dist/src/core/ir/refs.js.map +1 -0
- package/dist/src/core/ir/step-definition.d.ts +59 -0
- package/dist/src/core/ir/step-definition.d.ts.map +1 -0
- package/dist/src/core/ir/step-definition.js +6 -0
- package/dist/src/core/ir/step-definition.js.map +1 -0
- package/dist/src/core/ir/transition-definition.d.ts +8 -0
- package/dist/src/core/ir/transition-definition.d.ts.map +1 -0
- package/dist/src/core/ir/transition-definition.js +6 -0
- package/dist/src/core/ir/transition-definition.js.map +1 -0
- package/dist/src/core/item/index.d.ts +2 -0
- package/dist/src/core/item/index.d.ts.map +1 -0
- package/dist/src/core/item/index.js +20 -0
- package/dist/src/core/item/index.js.map +1 -0
- package/dist/src/core/item/interfaces.d.ts +64 -0
- package/dist/src/core/item/interfaces.d.ts.map +1 -0
- package/dist/src/core/item/interfaces.js +6 -0
- package/dist/src/core/item/interfaces.js.map +1 -0
- package/dist/src/core/repository/index.d.ts +3 -0
- package/dist/src/core/repository/index.d.ts.map +1 -0
- package/dist/src/core/repository/index.js +21 -0
- package/dist/src/core/repository/index.js.map +1 -0
- package/dist/src/core/repository/job-repository.d.ts +60 -0
- package/dist/src/core/repository/job-repository.d.ts.map +1 -0
- package/dist/src/core/repository/job-repository.js +27 -0
- package/dist/src/core/repository/job-repository.js.map +1 -0
- package/dist/src/core/repository/types.d.ts +84 -0
- package/dist/src/core/repository/types.d.ts.map +1 -0
- package/dist/src/core/repository/types.js +6 -0
- package/dist/src/core/repository/types.js.map +1 -0
- package/dist/src/core/status.d.ts +29 -0
- package/dist/src/core/status.d.ts.map +1 -0
- package/dist/src/core/status.js +58 -0
- package/dist/src/core/status.js.map +1 -0
- package/dist/src/core/transaction/index.d.ts +2 -0
- package/dist/src/core/transaction/index.d.ts.map +1 -0
- package/dist/src/core/transaction/index.js +20 -0
- package/dist/src/core/transaction/index.js.map +1 -0
- package/dist/src/core/transaction/transaction-manager.d.ts +8 -0
- package/dist/src/core/transaction/transaction-manager.d.ts.map +1 -0
- package/dist/src/core/transaction/transaction-manager.js +14 -0
- package/dist/src/core/transaction/transaction-manager.js.map +1 -0
- package/dist/src/core/validation/definition-validator.d.ts +46 -0
- package/dist/src/core/validation/definition-validator.d.ts.map +1 -0
- package/dist/src/core/validation/definition-validator.js +177 -0
- package/dist/src/core/validation/definition-validator.js.map +1 -0
- package/dist/src/core/validation/index.d.ts +2 -0
- package/dist/src/core/validation/index.d.ts.map +1 -0
- package/dist/src/core/validation/index.js +20 -0
- package/dist/src/core/validation/index.js.map +1 -0
- package/dist/src/decorators/constants.d.ts +10 -0
- package/dist/src/decorators/constants.d.ts.map +1 -0
- package/dist/src/decorators/constants.js +50 -0
- package/dist/src/decorators/constants.js.map +1 -0
- package/dist/src/decorators/flow.decorator.d.ts +25 -0
- package/dist/src/decorators/flow.decorator.d.ts.map +1 -0
- package/dist/src/decorators/flow.decorator.js +19 -0
- package/dist/src/decorators/flow.decorator.js.map +1 -0
- package/dist/src/decorators/index.d.ts +8 -0
- package/dist/src/decorators/index.d.ts.map +1 -0
- package/dist/src/decorators/index.js +26 -0
- package/dist/src/decorators/index.js.map +1 -0
- package/dist/src/decorators/item.decorators.d.ts +32 -0
- package/dist/src/decorators/item.decorators.d.ts.map +1 -0
- package/dist/src/decorators/item.decorators.js +40 -0
- package/dist/src/decorators/item.decorators.js.map +1 -0
- package/dist/src/decorators/job.decorator.d.ts +11 -0
- package/dist/src/decorators/job.decorator.d.ts.map +1 -0
- package/dist/src/decorators/job.decorator.js +17 -0
- package/dist/src/decorators/job.decorator.js.map +1 -0
- package/dist/src/decorators/listener.decorators.d.ts +56 -0
- package/dist/src/decorators/listener.decorators.d.ts.map +1 -0
- package/dist/src/decorators/listener.decorators.js +157 -0
- package/dist/src/decorators/listener.decorators.js.map +1 -0
- package/dist/src/decorators/step.decorator.d.ts +25 -0
- package/dist/src/decorators/step.decorator.d.ts.map +1 -0
- package/dist/src/decorators/step.decorator.js +21 -0
- package/dist/src/decorators/step.decorator.js.map +1 -0
- package/dist/src/decorators/tasklet.decorator.d.ts +7 -0
- package/dist/src/decorators/tasklet.decorator.d.ts.map +1 -0
- package/dist/src/decorators/tasklet.decorator.js +21 -0
- package/dist/src/decorators/tasklet.decorator.js.map +1 -0
- package/dist/src/execution/batch-worker-runner.d.ts +27 -0
- package/dist/src/execution/batch-worker-runner.d.ts.map +1 -0
- package/dist/src/execution/batch-worker-runner.js +147 -0
- package/dist/src/execution/batch-worker-runner.js.map +1 -0
- package/dist/src/execution/chunk-step-executor.d.ts +86 -0
- package/dist/src/execution/chunk-step-executor.d.ts.map +1 -0
- package/dist/src/execution/chunk-step-executor.js +482 -0
- package/dist/src/execution/chunk-step-executor.js.map +1 -0
- package/dist/src/execution/execution-strategy.d.ts +110 -0
- package/dist/src/execution/execution-strategy.d.ts.map +1 -0
- package/dist/src/execution/execution-strategy.js +13 -0
- package/dist/src/execution/execution-strategy.js.map +1 -0
- package/dist/src/execution/external-task-execution-strategy.d.ts +36 -0
- package/dist/src/execution/external-task-execution-strategy.d.ts.map +1 -0
- package/dist/src/execution/external-task-execution-strategy.js +97 -0
- package/dist/src/execution/external-task-execution-strategy.js.map +1 -0
- package/dist/src/execution/in-process-execution-strategy.d.ts +129 -0
- package/dist/src/execution/in-process-execution-strategy.d.ts.map +1 -0
- package/dist/src/execution/in-process-execution-strategy.js +141 -0
- package/dist/src/execution/in-process-execution-strategy.js.map +1 -0
- package/dist/src/execution/index.d.ts +14 -0
- package/dist/src/execution/index.d.ts.map +1 -0
- package/dist/src/execution/index.js +32 -0
- package/dist/src/execution/index.js.map +1 -0
- package/dist/src/execution/job-executor.d.ts +145 -0
- package/dist/src/execution/job-executor.d.ts.map +1 -0
- package/dist/src/execution/job-executor.js +475 -0
- package/dist/src/execution/job-executor.js.map +1 -0
- package/dist/src/execution/job-explorer.d.ts +15 -0
- package/dist/src/execution/job-explorer.d.ts.map +1 -0
- package/dist/src/execution/job-explorer.js +84 -0
- package/dist/src/execution/job-explorer.js.map +1 -0
- package/dist/src/execution/job-key.d.ts +3 -0
- package/dist/src/execution/job-key.d.ts.map +1 -0
- package/dist/src/execution/job-key.js +43 -0
- package/dist/src/execution/job-key.js.map +1 -0
- package/dist/src/execution/job-launcher.d.ts +75 -0
- package/dist/src/execution/job-launcher.d.ts.map +1 -0
- package/dist/src/execution/job-launcher.js +112 -0
- package/dist/src/execution/job-launcher.js.map +1 -0
- package/dist/src/execution/job-operator.d.ts +22 -0
- package/dist/src/execution/job-operator.d.ts.map +1 -0
- package/dist/src/execution/job-operator.js +125 -0
- package/dist/src/execution/job-operator.js.map +1 -0
- package/dist/src/execution/listener-invoker.d.ts +164 -0
- package/dist/src/execution/listener-invoker.d.ts.map +1 -0
- package/dist/src/execution/listener-invoker.js +246 -0
- package/dist/src/execution/listener-invoker.js.map +1 -0
- package/dist/src/execution/ref-resolver.d.ts +40 -0
- package/dist/src/execution/ref-resolver.d.ts.map +1 -0
- package/dist/src/execution/ref-resolver.js +41 -0
- package/dist/src/execution/ref-resolver.js.map +1 -0
- package/dist/src/execution/tasklet-step-executor.d.ts +79 -0
- package/dist/src/execution/tasklet-step-executor.d.ts.map +1 -0
- package/dist/src/execution/tasklet-step-executor.js +138 -0
- package/dist/src/execution/tasklet-step-executor.js.map +1 -0
- package/dist/src/explorer/batch-explorer.d.ts +138 -0
- package/dist/src/explorer/batch-explorer.d.ts.map +1 -0
- package/dist/src/explorer/batch-explorer.js +167 -0
- package/dist/src/explorer/batch-explorer.js.map +1 -0
- package/dist/src/explorer/index.d.ts +2 -0
- package/dist/src/explorer/index.d.ts.map +1 -0
- package/dist/src/explorer/index.js +20 -0
- package/dist/src/explorer/index.js.map +1 -0
- package/dist/src/flow/flow-evaluator.d.ts +30 -0
- package/dist/src/flow/flow-evaluator.d.ts.map +1 -0
- package/dist/src/flow/flow-evaluator.js +80 -0
- package/dist/src/flow/flow-evaluator.js.map +1 -0
- package/dist/src/flow/index.d.ts +2 -0
- package/dist/src/flow/index.d.ts.map +1 -0
- package/dist/src/flow/index.js +20 -0
- package/dist/src/flow/index.js.map +1 -0
- package/dist/src/index.d.ts +18 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +90 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/io/checkpoint.d.ts +7 -0
- package/dist/src/io/checkpoint.d.ts.map +1 -0
- package/dist/src/io/checkpoint.js +56 -0
- package/dist/src/io/checkpoint.js.map +1 -0
- package/dist/src/io/database.d.ts +50 -0
- package/dist/src/io/database.d.ts.map +1 -0
- package/dist/src/io/database.js +108 -0
- package/dist/src/io/database.js.map +1 -0
- package/dist/src/io/file-readers.d.ts +54 -0
- package/dist/src/io/file-readers.d.ts.map +1 -0
- package/dist/src/io/file-readers.js +167 -0
- package/dist/src/io/file-readers.js.map +1 -0
- package/dist/src/io/file-writers.d.ts +31 -0
- package/dist/src/io/file-writers.d.ts.map +1 -0
- package/dist/src/io/file-writers.js +80 -0
- package/dist/src/io/file-writers.js.map +1 -0
- package/dist/src/io/index.d.ts +6 -0
- package/dist/src/io/index.d.ts.map +1 -0
- package/dist/src/io/index.js +24 -0
- package/dist/src/io/index.js.map +1 -0
- package/dist/src/io/s3.d.ts +50 -0
- package/dist/src/io/s3.d.ts.map +1 -0
- package/dist/src/io/s3.js +96 -0
- package/dist/src/io/s3.js.map +1 -0
- package/dist/src/listeners/builtin-listeners.d.ts +77 -0
- package/dist/src/listeners/builtin-listeners.d.ts.map +1 -0
- package/dist/src/listeners/builtin-listeners.js +108 -0
- package/dist/src/listeners/builtin-listeners.js.map +1 -0
- package/dist/src/listeners/index.d.ts +8 -0
- package/dist/src/listeners/index.d.ts.map +1 -0
- package/dist/src/listeners/index.js +25 -0
- package/dist/src/listeners/index.js.map +1 -0
- package/dist/src/module/adapter-options.d.ts +39 -0
- package/dist/src/module/adapter-options.d.ts.map +1 -0
- package/dist/src/module/adapter-options.js +34 -0
- package/dist/src/module/adapter-options.js.map +1 -0
- package/dist/src/module/adapter.d.ts +157 -0
- package/dist/src/module/adapter.d.ts.map +1 -0
- package/dist/src/module/adapter.js +80 -0
- package/dist/src/module/adapter.js.map +1 -0
- package/dist/src/module/batch-schedule-registry.d.ts +110 -0
- package/dist/src/module/batch-schedule-registry.d.ts.map +1 -0
- package/dist/src/module/batch-schedule-registry.js +0 -0
- package/dist/src/module/batch-schedule-registry.js.map +1 -0
- package/dist/src/module/index.d.ts +14 -0
- package/dist/src/module/index.d.ts.map +1 -0
- package/dist/src/module/index.js +31 -0
- package/dist/src/module/index.js.map +1 -0
- package/dist/src/module/nest-batch.module.d.ts +236 -0
- package/dist/src/module/nest-batch.module.d.ts.map +1 -0
- package/dist/src/module/nest-batch.module.js +475 -0
- package/dist/src/module/nest-batch.module.js.map +1 -0
- package/dist/src/module/tokens.d.ts +83 -0
- package/dist/src/module/tokens.d.ts.map +1 -0
- package/dist/src/module/tokens.js +58 -0
- package/dist/src/module/tokens.js.map +1 -0
- package/dist/src/observability/event-types.d.ts +55 -0
- package/dist/src/observability/event-types.d.ts.map +1 -0
- package/dist/src/observability/event-types.js +36 -0
- package/dist/src/observability/event-types.js.map +1 -0
- package/dist/src/observability/exporters.d.ts +35 -0
- package/dist/src/observability/exporters.d.ts.map +1 -0
- package/dist/src/observability/exporters.js +93 -0
- package/dist/src/observability/exporters.js.map +1 -0
- package/dist/src/observability/index.d.ts +3 -0
- package/dist/src/observability/index.d.ts.map +1 -0
- package/dist/src/observability/index.js +21 -0
- package/dist/src/observability/index.js.map +1 -0
- package/dist/src/partition-helpers.d.ts +127 -0
- package/dist/src/partition-helpers.d.ts.map +1 -0
- package/dist/src/partition-helpers.js +136 -0
- package/dist/src/partition-helpers.js.map +1 -0
- package/dist/src/policies/backoff.d.ts +3 -0
- package/dist/src/policies/backoff.d.ts.map +1 -0
- package/dist/src/policies/backoff.js +34 -0
- package/dist/src/policies/backoff.js.map +1 -0
- package/dist/src/policies/index.d.ts +4 -0
- package/dist/src/policies/index.d.ts.map +1 -0
- package/dist/src/policies/index.js +22 -0
- package/dist/src/policies/index.js.map +1 -0
- package/dist/src/policies/retry-policy.d.ts +13 -0
- package/dist/src/policies/retry-policy.d.ts.map +1 -0
- package/dist/src/policies/retry-policy.js +55 -0
- package/dist/src/policies/retry-policy.js.map +1 -0
- package/dist/src/policies/skip-policy.d.ts +12 -0
- package/dist/src/policies/skip-policy.d.ts.map +1 -0
- package/dist/src/policies/skip-policy.js +44 -0
- package/dist/src/policies/skip-policy.js.map +1 -0
- package/dist/src/registry/index.d.ts +2 -0
- package/dist/src/registry/index.d.ts.map +1 -0
- package/dist/src/registry/index.js +20 -0
- package/dist/src/registry/index.js.map +1 -0
- package/dist/src/registry/job-registry.d.ts +16 -0
- package/dist/src/registry/job-registry.d.ts.map +1 -0
- package/dist/src/registry/job-registry.js +50 -0
- package/dist/src/registry/job-registry.js.map +1 -0
- package/dist/src/repository/id-generator.d.ts +18 -0
- package/dist/src/repository/id-generator.d.ts.map +1 -0
- package/dist/src/repository/id-generator.js +37 -0
- package/dist/src/repository/id-generator.js.map +1 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.d.ts +49 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.d.ts.map +1 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.js +291 -0
- package/dist/src/repository/in-memory/in-memory-job-repository.js.map +1 -0
- package/dist/src/repository/in-memory/index.d.ts +2 -0
- package/dist/src/repository/in-memory/index.d.ts.map +1 -0
- package/dist/src/repository/in-memory/index.js +20 -0
- package/dist/src/repository/in-memory/index.js.map +1 -0
- package/dist/src/repository/index.d.ts +4 -0
- package/dist/src/repository/index.d.ts.map +1 -0
- package/dist/src/repository/index.js +22 -0
- package/dist/src/repository/index.js.map +1 -0
- package/dist/src/repository/uuid-v7.d.ts +20 -0
- package/dist/src/repository/uuid-v7.d.ts.map +1 -0
- package/dist/src/repository/uuid-v7.js +31 -0
- package/dist/src/repository/uuid-v7.js.map +1 -0
- package/dist/src/scheduling/batch-scheduled.d.ts +87 -0
- package/dist/src/scheduling/batch-scheduled.d.ts.map +1 -0
- package/dist/src/scheduling/batch-scheduled.js +170 -0
- package/dist/src/scheduling/batch-scheduled.js.map +1 -0
- package/dist/src/transaction/in-memory-transaction-manager.d.ts +16 -0
- package/dist/src/transaction/in-memory-transaction-manager.d.ts.map +1 -0
- package/dist/src/transaction/in-memory-transaction-manager.js +33 -0
- package/dist/src/transaction/in-memory-transaction-manager.js.map +1 -0
- package/dist/src/transaction/index.d.ts +2 -0
- package/dist/src/transaction/index.d.ts.map +1 -0
- package/dist/src/transaction/index.js +20 -0
- package/dist/src/transaction/index.js.map +1 -0
- package/dist/tests/contracts/index.d.ts +26 -0
- package/dist/tests/contracts/index.d.ts.map +1 -0
- package/dist/tests/contracts/index.js +37 -0
- package/dist/tests/contracts/index.js.map +1 -0
- package/dist/tests/contracts/job-repository.contract.d.ts +46 -0
- package/dist/tests/contracts/job-repository.contract.d.ts.map +1 -0
- package/dist/tests/contracts/job-repository.contract.js +644 -0
- package/dist/tests/contracts/job-repository.contract.js.map +1 -0
- package/package.json +80 -0
- package/src/adapters/in-process.adapter.ts +182 -0
- package/src/adapters/index.ts +17 -0
- package/src/builder/batch-builder.ts +32 -0
- package/src/builder/flow-builder.ts +141 -0
- package/src/builder/index.ts +4 -0
- package/src/builder/job-builder.ts +206 -0
- package/src/builder/step-builder.ts +190 -0
- package/src/compiler/builder-types.ts +27 -0
- package/src/compiler/definition-compiler.ts +325 -0
- package/src/compiler/index.ts +2 -0
- package/src/core/errors.ts +125 -0
- package/src/core/execution-context/index.ts +3 -0
- package/src/core/execution-context/json-value.ts +3 -0
- package/src/core/execution-context/serializer.ts +21 -0
- package/src/core/execution-context/validator.ts +103 -0
- package/src/core/index.ts +7 -0
- package/src/core/ir/decider-definition.ts +25 -0
- package/src/core/ir/index.ts +7 -0
- package/src/core/ir/job-definition.ts +15 -0
- package/src/core/ir/listener-definition.ts +19 -0
- package/src/core/ir/policy-config.ts +19 -0
- package/src/core/ir/refs.ts +42 -0
- package/src/core/ir/step-definition.ts +62 -0
- package/src/core/ir/transition-definition.ts +9 -0
- package/src/core/item/index.ts +1 -0
- package/src/core/item/interfaces.ts +70 -0
- package/src/core/repository/index.ts +2 -0
- package/src/core/repository/job-repository.ts +100 -0
- package/src/core/repository/types.ts +91 -0
- package/src/core/status.ts +31 -0
- package/src/core/transaction/index.ts +1 -0
- package/src/core/transaction/transaction-manager.ts +8 -0
- package/src/core/validation/definition-validator.ts +215 -0
- package/src/core/validation/index.ts +1 -0
- package/src/decorators/constants.ts +9 -0
- package/src/decorators/flow.decorator.ts +31 -0
- package/src/decorators/index.ts +7 -0
- package/src/decorators/item.decorators.ts +51 -0
- package/src/decorators/job.decorator.ts +16 -0
- package/src/decorators/listener.decorators.ts +142 -0
- package/src/decorators/step.decorator.ts +33 -0
- package/src/decorators/tasklet.decorator.ts +14 -0
- package/src/execution/batch-worker-runner.ts +142 -0
- package/src/execution/chunk-step-executor.ts +594 -0
- package/src/execution/execution-strategy.ts +115 -0
- package/src/execution/external-task-execution-strategy.ts +104 -0
- package/src/execution/in-process-execution-strategy.ts +207 -0
- package/src/execution/index.ts +13 -0
- package/src/execution/job-executor.ts +553 -0
- package/src/execution/job-explorer.ts +73 -0
- package/src/execution/job-key.ts +35 -0
- package/src/execution/job-launcher.ts +132 -0
- package/src/execution/job-operator.ts +127 -0
- package/src/execution/listener-invoker.ts +389 -0
- package/src/execution/ref-resolver.ts +64 -0
- package/src/execution/tasklet-step-executor.ts +182 -0
- package/src/explorer/batch-explorer.ts +251 -0
- package/src/explorer/index.ts +1 -0
- package/src/flow/flow-evaluator.ts +89 -0
- package/src/flow/index.ts +1 -0
- package/src/index.ts +24 -0
- package/src/io/checkpoint.ts +47 -0
- package/src/io/database.ts +114 -0
- package/src/io/file-readers.ts +191 -0
- package/src/io/file-writers.ts +99 -0
- package/src/io/index.ts +5 -0
- package/src/io/s3.ts +117 -0
- package/src/listeners/builtin-listeners.ts +151 -0
- package/src/listeners/index.ts +7 -0
- package/src/module/adapter-options.ts +38 -0
- package/src/module/adapter.ts +160 -0
- package/src/module/batch-schedule-registry.ts +0 -0
- package/src/module/index.ts +13 -0
- package/src/module/nest-batch.module.ts +674 -0
- package/src/module/tokens.ts +95 -0
- package/src/observability/event-types.ts +61 -0
- package/src/observability/exporters.ts +96 -0
- package/src/observability/index.ts +2 -0
- package/src/partition-helpers.ts +204 -0
- package/src/policies/backoff.ts +22 -0
- package/src/policies/index.ts +3 -0
- package/src/policies/retry-policy.ts +57 -0
- package/src/policies/skip-policy.ts +51 -0
- package/src/registry/index.ts +1 -0
- package/src/registry/job-registry.ts +42 -0
- package/src/repository/id-generator.ts +25 -0
- package/src/repository/in-memory/in-memory-job-repository.ts +334 -0
- package/src/repository/in-memory/index.ts +1 -0
- package/src/repository/index.ts +3 -0
- package/src/repository/uuid-v7.ts +40 -0
- package/src/scheduling/batch-scheduled.ts +257 -0
- package/src/transaction/in-memory-transaction-manager.ts +23 -0
- package/src/transaction/index.ts +1 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
_export_star(require("./listener-invoker"), exports);
|
|
6
|
+
_export_star(require("./tasklet-step-executor"), exports);
|
|
7
|
+
_export_star(require("./chunk-step-executor"), exports);
|
|
8
|
+
_export_star(require("./job-executor"), exports);
|
|
9
|
+
_export_star(require("./job-launcher"), exports);
|
|
10
|
+
_export_star(require("./job-explorer"), exports);
|
|
11
|
+
_export_star(require("./job-operator"), exports);
|
|
12
|
+
_export_star(require("./batch-worker-runner"), exports);
|
|
13
|
+
_export_star(require("./external-task-execution-strategy"), exports);
|
|
14
|
+
_export_star(require("./job-key"), exports);
|
|
15
|
+
_export_star(require("./execution-strategy"), exports);
|
|
16
|
+
_export_star(require("./ref-resolver"), exports);
|
|
17
|
+
_export_star(require("./in-process-execution-strategy"), exports);
|
|
18
|
+
function _export_star(from, to) {
|
|
19
|
+
Object.keys(from).forEach(function(k) {
|
|
20
|
+
if (k !== "default" && !Object.prototype.hasOwnProperty.call(to, k)) {
|
|
21
|
+
Object.defineProperty(to, k, {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
get: function() {
|
|
24
|
+
return from[k];
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
return from;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/execution/index.ts"],"sourcesContent":["export * from './listener-invoker';\nexport * from './tasklet-step-executor';\nexport * from './chunk-step-executor';\nexport * from './job-executor';\nexport * from './job-launcher';\nexport * from './job-explorer';\nexport * from './job-operator';\nexport * from './batch-worker-runner';\nexport * from './external-task-execution-strategy';\nexport * from './job-key';\nexport * from './execution-strategy';\nexport * from './ref-resolver';\nexport * from './in-process-execution-strategy';\n"],"names":[],"mappings":";;;;qBAAc;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA;qBACA"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import type { JobDefinition } from '../core/ir';
|
|
2
|
+
import { JobRepository, type JobParameters, type JobExecution } from '../core/repository';
|
|
3
|
+
import { TransactionManager } from '../core/transaction';
|
|
4
|
+
import { TaskletStepExecutor } from './tasklet-step-executor';
|
|
5
|
+
import { ChunkStepExecutor } from './chunk-step-executor';
|
|
6
|
+
import { ListenerInvoker } from './listener-invoker';
|
|
7
|
+
import { FlowEvaluator } from '../flow/flow-evaluator';
|
|
8
|
+
import { type BatchObserver } from '../observability';
|
|
9
|
+
/**
|
|
10
|
+
* JobExecutor — drives a single JobExecution to completion.
|
|
11
|
+
*
|
|
12
|
+
* Flow (per ORACLE verdict 3c):
|
|
13
|
+
* 1. Mark execution as STARTED.
|
|
14
|
+
* 2. `before:job:*` listeners.
|
|
15
|
+
* 3. Loop:
|
|
16
|
+
* a. Look up the current step (jobDef.steps[currentStepId]). If the
|
|
17
|
+
* step is missing, mark the job FAILED with exit code
|
|
18
|
+
* `NO_SUCH_STEP` and break.
|
|
19
|
+
* b. Create a StepExecution, run it (tasklet or chunk), and persist
|
|
20
|
+
* the result via `updateStepExecution`. During the run, the
|
|
21
|
+
* step's own `after-step:*` listeners fire (see
|
|
22
|
+
* `TaskletStepExecutor.execute` step 4 / `ChunkStepExecutor`).
|
|
23
|
+
* Those listeners run BEFORE we evaluate transitions so they get
|
|
24
|
+
* a chance to mutate the result (e.g. flip COMPLETED → FAILED)
|
|
25
|
+
* and the resulting flow routing sees the override.
|
|
26
|
+
* c. Map the (possibly overridden) step status to a
|
|
27
|
+
* `FlowExecutionStatus` and ask the `FlowEvaluator` for the next
|
|
28
|
+
* step. `null` means END.
|
|
29
|
+
* d. If the step FAILED and the evaluator returned `null`
|
|
30
|
+
* (no recovery transition matches), short-circuit the job to
|
|
31
|
+
* FAILED — we must not continue running subsequent steps
|
|
32
|
+
* declared in the graph, because none are reachable.
|
|
33
|
+
* 4. `after:job:*` listeners (with the final status).
|
|
34
|
+
*
|
|
35
|
+
* Out of scope (future tasks):
|
|
36
|
+
* - Concurrency control (Task 38).
|
|
37
|
+
* - `on-error:job:*` listener invocation when the executor itself
|
|
38
|
+
* throws (the catch block can be wired to it in a follow-up).
|
|
39
|
+
*/
|
|
40
|
+
export declare class JobExecutor {
|
|
41
|
+
private readonly repository;
|
|
42
|
+
private readonly transactionManager;
|
|
43
|
+
private readonly taskletExecutor;
|
|
44
|
+
private readonly chunkExecutor;
|
|
45
|
+
private readonly listenerInvoker;
|
|
46
|
+
private readonly flowEvaluator;
|
|
47
|
+
private readonly observer;
|
|
48
|
+
private readonly logger;
|
|
49
|
+
constructor(repository: JobRepository, transactionManager: TransactionManager, taskletExecutor: TaskletStepExecutor, chunkExecutor: ChunkStepExecutor, listenerInvoker: ListenerInvoker, flowEvaluator: FlowEvaluator, observer?: BatchObserver);
|
|
50
|
+
/**
|
|
51
|
+
* Execute a JobExecution against its `JobDefinition`. Returns the
|
|
52
|
+
* final, persisted `JobExecution` (status = COMPLETED | FAILED).
|
|
53
|
+
*
|
|
54
|
+
* Restart behavior (per Metis verdict 3b — restartable opt-in, per
|
|
55
|
+
* ORACLE 3b — default-on for persisted repositories):
|
|
56
|
+
* - If `execution.status` is `FAILED` on entry, this is a restart
|
|
57
|
+
* attempt. We require `jobDef.restartable === true`; otherwise we
|
|
58
|
+
* throw `JobNotRestartableError` and leave the execution alone.
|
|
59
|
+
* - For each chunk step, we look up the latest FAILED StepExecution
|
|
60
|
+
* for that step in this job execution. If one exists, we read its
|
|
61
|
+
* ExecutionContext's `lastChunkIndex` checkpoint and pass it to the
|
|
62
|
+
* `ChunkStepExecutor` as `resumeFromChunkIndex`, which then skips
|
|
63
|
+
* chunks ≤ that index. Tasklet steps always re-run from scratch
|
|
64
|
+
* (they have no chunk-level resume granularity in this MVP).
|
|
65
|
+
*
|
|
66
|
+
* Partition routing (T8): the optional third argument carries the
|
|
67
|
+
* `partitionIndex` / `partitionCount` pair the transport attached
|
|
68
|
+
* to the job. When set, the chunk executor bounds the read loop
|
|
69
|
+
* to the partition's range (see `packages/core/src/partition-helpers.ts`).
|
|
70
|
+
*/
|
|
71
|
+
execute(execution: JobExecution, jobDef: JobDefinition, partition?: {
|
|
72
|
+
partitionIndex?: number;
|
|
73
|
+
partitionCount?: number;
|
|
74
|
+
}): Promise<JobExecution>;
|
|
75
|
+
/**
|
|
76
|
+
* Build a listener resolver map for the given job. Walks every
|
|
77
|
+
* `ListenerDefinition` in `jobDef.listeners` (job-level + step-level +
|
|
78
|
+
* chunk-level + item-level + skip-level) and resolves each ref into a
|
|
79
|
+
* callable `ListenerEntry` keyed by `${phase}:${kind}:${name}`.
|
|
80
|
+
*
|
|
81
|
+
* The returned map is consumed by `ListenerInvoker.invokeBefore /
|
|
82
|
+
* invokeAfter / invokeOnError / invokeOnSkip*` (Task 20 API). The legacy
|
|
83
|
+
* step-level methods (`invokeBeforeStep` etc.) consume a derived
|
|
84
|
+
* legacy-shaped map produced by `buildLegacyStepResolvers` — that
|
|
85
|
+
* conversion happens at the call site, not here, so this method stays
|
|
86
|
+
* the single source of truth for the new shape.
|
|
87
|
+
*
|
|
88
|
+
* Ref resolution rules:
|
|
89
|
+
* - `RefKind.BuilderLambda` → use `ref.fn` directly (the compiler
|
|
90
|
+
* pre-binds decorator-discovered methods
|
|
91
|
+
* and the builder API ships bare fns).
|
|
92
|
+
* - `RefKind.Method` → requires the Jobable instance. Until
|
|
93
|
+
* a `ModuleRef` is wired (Task 9+), this
|
|
94
|
+
* branch logs a warning and is skipped.
|
|
95
|
+
* - `RefKind.ProviderToken` → resolved in Task 9 against a
|
|
96
|
+
* pre-built provider map. Skipped here
|
|
97
|
+
* with a warning.
|
|
98
|
+
*/
|
|
99
|
+
private buildResolverMap;
|
|
100
|
+
/**
|
|
101
|
+
* Resolve a single `ListenerDefinition` to its callable function, or
|
|
102
|
+
* `null` if the ref kind is not yet supported. See `buildResolverMap`
|
|
103
|
+
* for the per-kind resolution contract.
|
|
104
|
+
*/
|
|
105
|
+
private resolveListenerRef;
|
|
106
|
+
/**
|
|
107
|
+
* Derive the `name` segment of the resolver key. Method refs carry a
|
|
108
|
+
* `classToken` + `methodName` pair that uniquely identifies the bound
|
|
109
|
+
* method; BuilderLambda refs do not carry a name (the compiler drops
|
|
110
|
+
* the method name when it pre-binds), so we mint a `lambda-N` name
|
|
111
|
+
* from a per-job counter to guarantee uniqueness.
|
|
112
|
+
*/
|
|
113
|
+
private resolveListenerName;
|
|
114
|
+
/**
|
|
115
|
+
* Derive a legacy `Map<string, ListenerResolver>` from a new
|
|
116
|
+
* `ResolverMap`, containing only the step-level entries with their
|
|
117
|
+
* keys translated from `${phase}:step:${name}` back to the legacy
|
|
118
|
+
* `${phase}-step:${name}` shape. The `nonCritical` flag is dropped
|
|
119
|
+
* (legacy `ListenerResolver` is a bare function with no metadata).
|
|
120
|
+
*
|
|
121
|
+
* This is the bridge the `TaskletStepExecutor` (which still consumes
|
|
122
|
+
* the legacy shape) needs until it migrates to the new API. Kept as
|
|
123
|
+
* a private helper so the conversion logic is in one place.
|
|
124
|
+
*/
|
|
125
|
+
private buildLegacyStepResolvers;
|
|
126
|
+
/**
|
|
127
|
+
* Read the `lastChunkIndex` checkpoint from the step-scoped
|
|
128
|
+
* ExecutionContext for `stepExecutionId`. Returns `undefined` when the
|
|
129
|
+
* step has no recorded checkpoint (e.g., the prior run failed on the
|
|
130
|
+
* very first chunk and never got a chance to write one). The chunk
|
|
131
|
+
* executor treats `undefined` as "no resume; start from the beginning".
|
|
132
|
+
*/
|
|
133
|
+
private getLastCheckpoint;
|
|
134
|
+
private resolveDeciderExitStatus;
|
|
135
|
+
/**
|
|
136
|
+
* Dispatch a BatchEvent to the configured observer. Errors thrown by
|
|
137
|
+
* the observer are swallowed: a failing logger/queue must not crash
|
|
138
|
+
* the executor (the job's persisted state is the source of truth).
|
|
139
|
+
*/
|
|
140
|
+
private emit;
|
|
141
|
+
}
|
|
142
|
+
export type { StepExecutionResult } from './tasklet-step-executor';
|
|
143
|
+
export type { ChunkExecutionResult } from './chunk-step-executor';
|
|
144
|
+
export type { JobParameters, JobExecution };
|
|
145
|
+
//# sourceMappingURL=job-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"job-executor.d.ts","sourceRoot":"","sources":["../../../src/execution/job-executor.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAsB,MAAM,YAAY,CAAC;AAEpE,OAAO,EAAE,aAAa,EAAE,KAAK,aAAa,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGzD,OAAO,EAAE,mBAAmB,EAA4B,MAAM,yBAAyB,CAAC;AACxF,OAAO,EAAE,iBAAiB,EAA6B,MAAM,uBAAuB,CAAC;AACrF,OAAO,EACL,eAAe,EAGhB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,kBAAkB,CAAC;AAa1B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,qBACa,WAAW;IAIpB,OAAO,CAAC,QAAQ,CAAC,UAAU;IAE3B,OAAO,CAAC,QAAQ,CAAC,kBAAkB;IACnC,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAC9B,OAAO,CAAC,QAAQ,CAAC,eAAe;IAChC,OAAO,CAAC,QAAQ,CAAC,aAAa;IAE9B,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAX3B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgC;gBAGpC,UAAU,EAAE,aAAa,EAEzB,kBAAkB,EAAE,kBAAkB,EACtC,eAAe,EAAE,mBAAmB,EACpC,aAAa,EAAE,iBAAiB,EAChC,eAAe,EAAE,eAAe,EAChC,aAAa,EAAE,aAAa,EAE5B,QAAQ,GAAE,aAAuC;IAGpE;;;;;;;;;;;;;;;;;;;;OAoBG;IACG,OAAO,CACX,SAAS,EAAE,YAAY,EACvB,MAAM,EAAE,aAAa,EACrB,SAAS,CAAC,EAAE;QAAE,cAAc,CAAC,EAAE,MAAM,CAAC;QAAC,cAAc,CAAC,EAAE,MAAM,CAAA;KAAE,GAC/D,OAAO,CAAC,YAAY,CAAC;IA6RxB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,OAAO,CAAC,gBAAgB;IAqBxB;;;;OAIG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAO3B;;;;;;;;;;OAUG;IACH,OAAO,CAAC,wBAAwB;IAchC;;;;;;OAMG;YACW,iBAAiB;YASjB,wBAAwB;IAYtC;;;;OAIG;YACW,IAAI;CAQnB;AAID,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,YAAY,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "JobExecutor", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return JobExecutor;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _common = require("@nestjs/common");
|
|
12
|
+
const _ir = require("../core/ir");
|
|
13
|
+
const _repository = require("../core/repository");
|
|
14
|
+
const _transaction = require("../core/transaction");
|
|
15
|
+
const _status = require("../core/status");
|
|
16
|
+
const _errors = require("../core/errors");
|
|
17
|
+
const _taskletstepexecutor = require("./tasklet-step-executor");
|
|
18
|
+
const _chunkstepexecutor = require("./chunk-step-executor");
|
|
19
|
+
const _listenerinvoker = require("./listener-invoker");
|
|
20
|
+
const _flowevaluator = require("../flow/flow-evaluator");
|
|
21
|
+
const _observability = require("../observability");
|
|
22
|
+
function _ts_decorate(decorators, target, key, desc) {
|
|
23
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
24
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
25
|
+
else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
26
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
27
|
+
}
|
|
28
|
+
function _ts_metadata(k, v) {
|
|
29
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
30
|
+
}
|
|
31
|
+
function _ts_param(paramIndex, decorator) {
|
|
32
|
+
return function(target, key) {
|
|
33
|
+
decorator(target, key, paramIndex);
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
let JobExecutor = class JobExecutor {
|
|
37
|
+
repository;
|
|
38
|
+
transactionManager;
|
|
39
|
+
taskletExecutor;
|
|
40
|
+
chunkExecutor;
|
|
41
|
+
listenerInvoker;
|
|
42
|
+
flowEvaluator;
|
|
43
|
+
observer;
|
|
44
|
+
logger = new _common.Logger(JobExecutor.name);
|
|
45
|
+
constructor(repository, transactionManager, taskletExecutor, chunkExecutor, listenerInvoker, flowEvaluator, observer = new _observability.NoopBatchObserver()){
|
|
46
|
+
this.repository = repository;
|
|
47
|
+
this.transactionManager = transactionManager;
|
|
48
|
+
this.taskletExecutor = taskletExecutor;
|
|
49
|
+
this.chunkExecutor = chunkExecutor;
|
|
50
|
+
this.listenerInvoker = listenerInvoker;
|
|
51
|
+
this.flowEvaluator = flowEvaluator;
|
|
52
|
+
this.observer = observer;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Execute a JobExecution against its `JobDefinition`. Returns the
|
|
56
|
+
* final, persisted `JobExecution` (status = COMPLETED | FAILED).
|
|
57
|
+
*
|
|
58
|
+
* Restart behavior (per Metis verdict 3b — restartable opt-in, per
|
|
59
|
+
* ORACLE 3b — default-on for persisted repositories):
|
|
60
|
+
* - If `execution.status` is `FAILED` on entry, this is a restart
|
|
61
|
+
* attempt. We require `jobDef.restartable === true`; otherwise we
|
|
62
|
+
* throw `JobNotRestartableError` and leave the execution alone.
|
|
63
|
+
* - For each chunk step, we look up the latest FAILED StepExecution
|
|
64
|
+
* for that step in this job execution. If one exists, we read its
|
|
65
|
+
* ExecutionContext's `lastChunkIndex` checkpoint and pass it to the
|
|
66
|
+
* `ChunkStepExecutor` as `resumeFromChunkIndex`, which then skips
|
|
67
|
+
* chunks ≤ that index. Tasklet steps always re-run from scratch
|
|
68
|
+
* (they have no chunk-level resume granularity in this MVP).
|
|
69
|
+
*
|
|
70
|
+
* Partition routing (T8): the optional third argument carries the
|
|
71
|
+
* `partitionIndex` / `partitionCount` pair the transport attached
|
|
72
|
+
* to the job. When set, the chunk executor bounds the read loop
|
|
73
|
+
* to the partition's range (see `packages/core/src/partition-helpers.ts`).
|
|
74
|
+
*/ async execute(execution, jobDef, partition) {
|
|
75
|
+
// Capture the pre-execute status. For a fresh launch, the launcher
|
|
76
|
+
// created the execution with status STARTING; for a restart, the
|
|
77
|
+
// caller (JobLauncher.run) hands us a terminal execution that can
|
|
78
|
+
// be resumed.
|
|
79
|
+
const isRestart = execution.status === _status.JobStatus.FAILED || execution.status === _status.JobStatus.STOPPED;
|
|
80
|
+
if (isRestart && !jobDef.restartable) {
|
|
81
|
+
throw new _errors.JobNotRestartableError(jobDef.id);
|
|
82
|
+
}
|
|
83
|
+
await this.repository.updateJobExecution(execution.id, {
|
|
84
|
+
status: _status.JobStatus.STARTED,
|
|
85
|
+
startTime: new Date()
|
|
86
|
+
});
|
|
87
|
+
await this.emit({
|
|
88
|
+
type: _observability.BATCH_EVENT.JOB_STARTED,
|
|
89
|
+
timestamp: new Date(),
|
|
90
|
+
jobExecutionId: execution.id,
|
|
91
|
+
data: {
|
|
92
|
+
jobName: jobDef.id
|
|
93
|
+
}
|
|
94
|
+
});
|
|
95
|
+
// Build the full resolver map once. The same map powers both the
|
|
96
|
+
// job-level `invokeBefore` / `invokeAfter` calls below and the
|
|
97
|
+
// step-level resolvers handed to the TaskletStepExecutor (derived
|
|
98
|
+
// by `buildLegacyStepResolvers` into the legacy key shape). Building
|
|
99
|
+
// it once per execution avoids re-walking the IR on every step.
|
|
100
|
+
const jobResolvers = this.buildResolverMap(jobDef);
|
|
101
|
+
const stepResolvers = this.buildLegacyStepResolvers(jobResolvers);
|
|
102
|
+
await this.listenerInvoker.invokeBefore(jobResolvers, 'job', {
|
|
103
|
+
jobExecutionId: execution.id,
|
|
104
|
+
stepExecutionId: '<job>'
|
|
105
|
+
});
|
|
106
|
+
// Cache the step order once. `Object.keys` returns insertion order
|
|
107
|
+
// for string keys (per ES2015+), so this is the canonical
|
|
108
|
+
// declaration order — used for the linear fallback below.
|
|
109
|
+
const stepOrder = Object.keys(jobDef.steps);
|
|
110
|
+
let currentStepId = jobDef.startStepId;
|
|
111
|
+
let finalStatus = _status.JobStatus.COMPLETED;
|
|
112
|
+
let currentStepExecutionId = null;
|
|
113
|
+
try {
|
|
114
|
+
while(currentStepId !== null){
|
|
115
|
+
const step = jobDef.steps[currentStepId];
|
|
116
|
+
if (!step) {
|
|
117
|
+
await this.repository.updateJobExecution(execution.id, {
|
|
118
|
+
status: _status.JobStatus.FAILED,
|
|
119
|
+
endTime: new Date(),
|
|
120
|
+
exitCode: 'NO_SUCH_STEP',
|
|
121
|
+
exitMessage: `Step "${currentStepId}" not found`
|
|
122
|
+
});
|
|
123
|
+
finalStatus = _status.JobStatus.FAILED;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
// Restart path: if this is a restart and the current step is a
|
|
127
|
+
// chunk step, locate the latest FAILED step execution for the
|
|
128
|
+
// same step name and load its `lastChunkIndex` checkpoint. That
|
|
129
|
+
// value is passed to the chunk executor as `resumeFromChunkIndex`.
|
|
130
|
+
// For tasklet steps (and chunk steps with no prior failure) we
|
|
131
|
+
// leave `resumeFromChunkIndex` undefined — the chunk executor
|
|
132
|
+
// treats undefined as "start from the beginning".
|
|
133
|
+
//
|
|
134
|
+
// Look this up BEFORE createStepExecution so the just-created
|
|
135
|
+
// STARTING step isn't returned as the "latest" entry.
|
|
136
|
+
let resumeFromChunkIndex;
|
|
137
|
+
if (isRestart && step.kind === 'chunk') {
|
|
138
|
+
const priorFailed = await this.repository.findLatestStepExecution(execution.id, step.id);
|
|
139
|
+
if (priorFailed && priorFailed.status === _status.StepStatus.FAILED) {
|
|
140
|
+
resumeFromChunkIndex = await this.getLastCheckpoint(priorFailed.id);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
const stepExecution = await this.repository.createStepExecution(execution.id, step.id);
|
|
144
|
+
currentStepExecutionId = stepExecution.id;
|
|
145
|
+
await this.emit({
|
|
146
|
+
type: _observability.BATCH_EVENT.STEP_STARTED,
|
|
147
|
+
timestamp: new Date(),
|
|
148
|
+
jobExecutionId: execution.id,
|
|
149
|
+
stepExecutionId: stepExecution.id,
|
|
150
|
+
data: {
|
|
151
|
+
stepId: step.id,
|
|
152
|
+
kind: step.kind
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
let result;
|
|
156
|
+
try {
|
|
157
|
+
if (step.kind === 'tasklet') {
|
|
158
|
+
result = await this.taskletExecutor.execute(step, {
|
|
159
|
+
jobExecutionId: execution.id,
|
|
160
|
+
jobRepository: this.repository,
|
|
161
|
+
transactionManager: this.transactionManager,
|
|
162
|
+
listenerInvoker: this.listenerInvoker,
|
|
163
|
+
listenerResolvers: stepResolvers
|
|
164
|
+
});
|
|
165
|
+
} else {
|
|
166
|
+
// Forward the partition routing (T8) when the transport
|
|
167
|
+
// supplied one. The chunk executor uses the partition
|
|
168
|
+
// index + count + the step's `partitions.range` to bound
|
|
169
|
+
// its read loop. Absent partition args fall through to
|
|
170
|
+
// the 0.1.0 non-partitioned chunk pipeline.
|
|
171
|
+
const partitionArgs = partition?.partitionIndex !== undefined && partition?.partitionCount !== undefined ? {
|
|
172
|
+
partitionIndex: partition.partitionIndex,
|
|
173
|
+
partitionCount: partition.partitionCount
|
|
174
|
+
} : {};
|
|
175
|
+
result = await this.chunkExecutor.execute(step, {
|
|
176
|
+
jobExecutionId: execution.id,
|
|
177
|
+
stepExecutionId: stepExecution.id,
|
|
178
|
+
jobRepository: this.repository,
|
|
179
|
+
transactionManager: this.transactionManager,
|
|
180
|
+
listenerInvoker: this.listenerInvoker,
|
|
181
|
+
jobExecutionId2: execution.id,
|
|
182
|
+
resolvers: new Map(),
|
|
183
|
+
...resumeFromChunkIndex !== undefined ? {
|
|
184
|
+
resumeFromChunkIndex
|
|
185
|
+
} : {},
|
|
186
|
+
...partitionArgs
|
|
187
|
+
});
|
|
188
|
+
}
|
|
189
|
+
} catch (stepErr) {
|
|
190
|
+
// The executor itself threw (e.g. resolveReader threw in a
|
|
191
|
+
// chunk step before the executor's own try-catch could catch
|
|
192
|
+
// it). Persist the step as FAILED with the error message and
|
|
193
|
+
// re-raise so the outer handler marks the job FAILED.
|
|
194
|
+
await this.repository.updateStepExecution(stepExecution.id, {
|
|
195
|
+
status: _status.StepStatus.FAILED,
|
|
196
|
+
exitCode: 'FAILED',
|
|
197
|
+
exitMessage: stepErr instanceof Error ? stepErr.message : String(stepErr),
|
|
198
|
+
endTime: new Date()
|
|
199
|
+
});
|
|
200
|
+
currentStepExecutionId = null;
|
|
201
|
+
throw stepErr;
|
|
202
|
+
}
|
|
203
|
+
currentStepExecutionId = null;
|
|
204
|
+
await this.repository.updateStepExecution(stepExecution.id, {
|
|
205
|
+
status: result.status,
|
|
206
|
+
...result.readCount !== undefined ? {
|
|
207
|
+
readCount: result.readCount
|
|
208
|
+
} : {},
|
|
209
|
+
...result.writeCount !== undefined ? {
|
|
210
|
+
writeCount: result.writeCount
|
|
211
|
+
} : {},
|
|
212
|
+
...result.skipCount !== undefined ? {
|
|
213
|
+
skipCount: result.skipCount
|
|
214
|
+
} : {},
|
|
215
|
+
...'commitCount' in result && result.commitCount !== undefined ? {
|
|
216
|
+
commitCount: result.commitCount
|
|
217
|
+
} : {},
|
|
218
|
+
exitCode: result.exitCode,
|
|
219
|
+
exitMessage: result.exitMessage,
|
|
220
|
+
endTime: new Date()
|
|
221
|
+
});
|
|
222
|
+
await this.emit({
|
|
223
|
+
type: result.status === _status.StepStatus.COMPLETED ? _observability.BATCH_EVENT.STEP_COMPLETED : result.status === _status.StepStatus.FAILED ? _observability.BATCH_EVENT.STEP_FAILED : _observability.BATCH_EVENT.STEP_COMPLETED,
|
|
224
|
+
timestamp: new Date(),
|
|
225
|
+
jobExecutionId: execution.id,
|
|
226
|
+
stepExecutionId: stepExecution.id,
|
|
227
|
+
data: {
|
|
228
|
+
stepId: step.id,
|
|
229
|
+
status: result.status,
|
|
230
|
+
...result.exitCode !== undefined ? {
|
|
231
|
+
exitCode: result.exitCode
|
|
232
|
+
} : {}
|
|
233
|
+
}
|
|
234
|
+
});
|
|
235
|
+
// Map StepStatus -> FlowExecutionStatus. Anything other than
|
|
236
|
+
// COMPLETED/FAILED collapses to UNKNOWN → evaluator returns
|
|
237
|
+
// null → flow ends.
|
|
238
|
+
const flowStatus = result.status === _status.StepStatus.COMPLETED ? _status.FlowExecutionStatus.COMPLETED : result.status === _status.StepStatus.FAILED ? _status.FlowExecutionStatus.FAILED : _status.FlowExecutionStatus.UNKNOWN;
|
|
239
|
+
const deciderExitStatus = await this.resolveDeciderExitStatus(jobDef, currentStepId, {
|
|
240
|
+
jobExecution: execution,
|
|
241
|
+
stepId: step.id,
|
|
242
|
+
stepExecutionId: stepExecution.id,
|
|
243
|
+
stepStatus: result.status,
|
|
244
|
+
exitCode: result.exitCode,
|
|
245
|
+
exitMessage: result.exitMessage
|
|
246
|
+
});
|
|
247
|
+
const flowExitStatus = deciderExitStatus ?? (result.exitCode || flowStatus);
|
|
248
|
+
let evaluatorResult = await this.flowEvaluator.evaluate(jobDef.transitions, currentStepId, flowExitStatus);
|
|
249
|
+
// Distinguish "no transition declared" (linear fallback) from
|
|
250
|
+
// "transition declared with toStepId: null" (explicit END).
|
|
251
|
+
// FlowEvaluator returns null for both, so we inspect the
|
|
252
|
+
// transition list directly.
|
|
253
|
+
let hasMatchingTransition = jobDef.transitions.some((t)=>this.flowEvaluator.matches(t, currentStepId, flowExitStatus));
|
|
254
|
+
if (!hasMatchingTransition && flowExitStatus !== flowStatus) {
|
|
255
|
+
evaluatorResult = await this.flowEvaluator.evaluate(jobDef.transitions, currentStepId, flowStatus);
|
|
256
|
+
hasMatchingTransition = jobDef.transitions.some((t)=>this.flowEvaluator.matches(t, currentStepId, flowStatus));
|
|
257
|
+
}
|
|
258
|
+
let nextStepId;
|
|
259
|
+
if (hasMatchingTransition) {
|
|
260
|
+
// Explicit transition: respect its target, including null
|
|
261
|
+
// (END). Do not fall through to linear order.
|
|
262
|
+
nextStepId = evaluatorResult;
|
|
263
|
+
} else if (result.status === _status.StepStatus.FAILED) {
|
|
264
|
+
// FAILED with no matching transition → short-circuit. The
|
|
265
|
+
// graph declares no path forward, so the job is FAILED — we
|
|
266
|
+
// must not invent a "next" step.
|
|
267
|
+
await this.repository.updateJobExecution(execution.id, {
|
|
268
|
+
status: _status.JobStatus.FAILED,
|
|
269
|
+
endTime: new Date(),
|
|
270
|
+
exitCode: result.exitCode,
|
|
271
|
+
exitMessage: result.exitMessage
|
|
272
|
+
});
|
|
273
|
+
finalStatus = _status.JobStatus.FAILED;
|
|
274
|
+
break;
|
|
275
|
+
} else {
|
|
276
|
+
// COMPLETED with no transition → linear fallback to the next
|
|
277
|
+
// step in declaration order. If we're already on the last
|
|
278
|
+
// step, the job ends.
|
|
279
|
+
const currentIdx = stepOrder.indexOf(currentStepId);
|
|
280
|
+
const nextIdx = currentIdx + 1;
|
|
281
|
+
nextStepId = nextIdx < stepOrder.length ? stepOrder[nextIdx] : null;
|
|
282
|
+
}
|
|
283
|
+
currentStepId = nextStepId;
|
|
284
|
+
}
|
|
285
|
+
if (finalStatus === _status.JobStatus.COMPLETED) {
|
|
286
|
+
await this.repository.updateJobExecution(execution.id, {
|
|
287
|
+
status: _status.JobStatus.COMPLETED,
|
|
288
|
+
endTime: new Date(),
|
|
289
|
+
exitCode: 'COMPLETED'
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
} catch (err) {
|
|
293
|
+
// Defensive: leave the job FAILED rather than crash the host.
|
|
294
|
+
await this.repository.updateJobExecution(execution.id, {
|
|
295
|
+
status: _status.JobStatus.FAILED,
|
|
296
|
+
endTime: new Date(),
|
|
297
|
+
exitMessage: err instanceof Error ? err.message : String(err)
|
|
298
|
+
});
|
|
299
|
+
finalStatus = _status.JobStatus.FAILED;
|
|
300
|
+
}
|
|
301
|
+
// `after:job:*` listeners run once the job is in a terminal state.
|
|
302
|
+
// They receive the final status as the second positional argument
|
|
303
|
+
// (the `args` slot in the current API; the legacy builder path used
|
|
304
|
+
// the same shape). The resolver map is the same one built above;
|
|
305
|
+
// we re-use it to avoid a second IR walk.
|
|
306
|
+
await this.listenerInvoker.invokeAfter(jobResolvers, 'job', {
|
|
307
|
+
jobExecutionId: execution.id,
|
|
308
|
+
stepExecutionId: '<job>'
|
|
309
|
+
}, [
|
|
310
|
+
{
|
|
311
|
+
status: finalStatus
|
|
312
|
+
}
|
|
313
|
+
]);
|
|
314
|
+
await this.emit({
|
|
315
|
+
type: finalStatus === _status.JobStatus.COMPLETED ? _observability.BATCH_EVENT.JOB_COMPLETED : _observability.BATCH_EVENT.JOB_FAILED,
|
|
316
|
+
timestamp: new Date(),
|
|
317
|
+
jobExecutionId: execution.id,
|
|
318
|
+
data: {
|
|
319
|
+
status: finalStatus
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
return await this.repository.getJobExecution(execution.id);
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Build a listener resolver map for the given job. Walks every
|
|
326
|
+
* `ListenerDefinition` in `jobDef.listeners` (job-level + step-level +
|
|
327
|
+
* chunk-level + item-level + skip-level) and resolves each ref into a
|
|
328
|
+
* callable `ListenerEntry` keyed by `${phase}:${kind}:${name}`.
|
|
329
|
+
*
|
|
330
|
+
* The returned map is consumed by `ListenerInvoker.invokeBefore /
|
|
331
|
+
* invokeAfter / invokeOnError / invokeOnSkip*` (Task 20 API). The legacy
|
|
332
|
+
* step-level methods (`invokeBeforeStep` etc.) consume a derived
|
|
333
|
+
* legacy-shaped map produced by `buildLegacyStepResolvers` — that
|
|
334
|
+
* conversion happens at the call site, not here, so this method stays
|
|
335
|
+
* the single source of truth for the new shape.
|
|
336
|
+
*
|
|
337
|
+
* Ref resolution rules:
|
|
338
|
+
* - `RefKind.BuilderLambda` → use `ref.fn` directly (the compiler
|
|
339
|
+
* pre-binds decorator-discovered methods
|
|
340
|
+
* and the builder API ships bare fns).
|
|
341
|
+
* - `RefKind.Method` → requires the Jobable instance. Until
|
|
342
|
+
* a `ModuleRef` is wired (Task 9+), this
|
|
343
|
+
* branch logs a warning and is skipped.
|
|
344
|
+
* - `RefKind.ProviderToken` → resolved in Task 9 against a
|
|
345
|
+
* pre-built provider map. Skipped here
|
|
346
|
+
* with a warning.
|
|
347
|
+
*/ buildResolverMap(jobDef) {
|
|
348
|
+
const resolvers = new Map();
|
|
349
|
+
let lambdaCounter = 0;
|
|
350
|
+
for (const def of jobDef.listeners){
|
|
351
|
+
const fn = this.resolveListenerRef(def);
|
|
352
|
+
if (fn === null) continue;
|
|
353
|
+
const name = this.resolveListenerName(def.ref, lambdaCounter);
|
|
354
|
+
if (def.ref.kind === _ir.RefKind.BuilderLambda) lambdaCounter += 1;
|
|
355
|
+
const key = `${def.phase}:${def.kind}:${name}`;
|
|
356
|
+
resolvers.set(key, {
|
|
357
|
+
fn,
|
|
358
|
+
...def.nonCritical !== undefined ? {
|
|
359
|
+
nonCritical: def.nonCritical
|
|
360
|
+
} : {}
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
return resolvers;
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Resolve a single `ListenerDefinition` to its callable function, or
|
|
367
|
+
* `null` if the ref kind is not yet supported. See `buildResolverMap`
|
|
368
|
+
* for the per-kind resolution contract.
|
|
369
|
+
*/ resolveListenerRef(def) {
|
|
370
|
+
const ref = def.ref;
|
|
371
|
+
switch(ref.kind){
|
|
372
|
+
case _ir.RefKind.BuilderLambda:
|
|
373
|
+
return ref.fn ?? null;
|
|
374
|
+
case _ir.RefKind.Method:
|
|
375
|
+
this.logger.warn(`JobExecutor: Method-ref listener (classToken=${ref.classToken ?? '<unknown>'}, ` + `methodName=${ref.methodName ?? '<unknown>'}) requires a Jobable instance; ` + 'this resolution path lands in a follow-up task. Listener skipped.');
|
|
376
|
+
return null;
|
|
377
|
+
case _ir.RefKind.ProviderToken:
|
|
378
|
+
this.logger.warn(`JobExecutor: ProviderToken-ref listener (token=${ref.token ?? '<empty>'}) ` + 'is resolved in Task 9. Listener skipped.');
|
|
379
|
+
return null;
|
|
380
|
+
default:
|
|
381
|
+
{
|
|
382
|
+
const _exhaustive = ref.kind;
|
|
383
|
+
void _exhaustive;
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
/**
|
|
389
|
+
* Derive the `name` segment of the resolver key. Method refs carry a
|
|
390
|
+
* `classToken` + `methodName` pair that uniquely identifies the bound
|
|
391
|
+
* method; BuilderLambda refs do not carry a name (the compiler drops
|
|
392
|
+
* the method name when it pre-binds), so we mint a `lambda-N` name
|
|
393
|
+
* from a per-job counter to guarantee uniqueness.
|
|
394
|
+
*/ resolveListenerName(ref, lambdaCounter) {
|
|
395
|
+
if (ref.kind === _ir.RefKind.Method) {
|
|
396
|
+
return `${ref.classToken ?? '<unknown>'}.${ref.methodName ?? '<unknown>'}`;
|
|
397
|
+
}
|
|
398
|
+
return `lambda-${lambdaCounter}`;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Derive a legacy `Map<string, ListenerResolver>` from a new
|
|
402
|
+
* `ResolverMap`, containing only the step-level entries with their
|
|
403
|
+
* keys translated from `${phase}:step:${name}` back to the legacy
|
|
404
|
+
* `${phase}-step:${name}` shape. The `nonCritical` flag is dropped
|
|
405
|
+
* (legacy `ListenerResolver` is a bare function with no metadata).
|
|
406
|
+
*
|
|
407
|
+
* This is the bridge the `TaskletStepExecutor` (which still consumes
|
|
408
|
+
* the legacy shape) needs until it migrates to the new API. Kept as
|
|
409
|
+
* a private helper so the conversion logic is in one place.
|
|
410
|
+
*/ buildLegacyStepResolvers(resolvers) {
|
|
411
|
+
const legacy = new Map();
|
|
412
|
+
for (const [key, entry] of resolvers.entries()){
|
|
413
|
+
if (key.startsWith('before:step:')) {
|
|
414
|
+
legacy.set(`before-step:${key.slice('before:step:'.length)}`, entry.fn);
|
|
415
|
+
} else if (key.startsWith('after:step:')) {
|
|
416
|
+
legacy.set(`after-step:${key.slice('after:step:'.length)}`, entry.fn);
|
|
417
|
+
} else if (key.startsWith('on-error:step:')) {
|
|
418
|
+
legacy.set(`on-step-error:${key.slice('on-error:step:'.length)}`, entry.fn);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return legacy;
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Read the `lastChunkIndex` checkpoint from the step-scoped
|
|
425
|
+
* ExecutionContext for `stepExecutionId`. Returns `undefined` when the
|
|
426
|
+
* step has no recorded checkpoint (e.g., the prior run failed on the
|
|
427
|
+
* very first chunk and never got a chance to write one). The chunk
|
|
428
|
+
* executor treats `undefined` as "no resume; start from the beginning".
|
|
429
|
+
*/ async getLastCheckpoint(stepExecutionId) {
|
|
430
|
+
const ctx = await this.repository.getExecutionContext({
|
|
431
|
+
stepExecutionId
|
|
432
|
+
});
|
|
433
|
+
if (ctx.data === null || typeof ctx.data !== 'object' || Array.isArray(ctx.data)) {
|
|
434
|
+
return undefined;
|
|
435
|
+
}
|
|
436
|
+
const value = ctx.data.lastChunkIndex;
|
|
437
|
+
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
438
|
+
}
|
|
439
|
+
async resolveDeciderExitStatus(jobDef, afterStepId, context) {
|
|
440
|
+
const decider = (jobDef.deciders ?? []).find((d)=>d.afterStepId === afterStepId);
|
|
441
|
+
if (decider === undefined) return undefined;
|
|
442
|
+
const status = await decider.decide(context);
|
|
443
|
+
const trimmed = status.trim();
|
|
444
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
445
|
+
}
|
|
446
|
+
/**
|
|
447
|
+
* Dispatch a BatchEvent to the configured observer. Errors thrown by
|
|
448
|
+
* the observer are swallowed: a failing logger/queue must not crash
|
|
449
|
+
* the executor (the job's persisted state is the source of truth).
|
|
450
|
+
*/ async emit(event) {
|
|
451
|
+
try {
|
|
452
|
+
await this.observer.onEvent(event);
|
|
453
|
+
} catch {
|
|
454
|
+
// intentional: observer failures are best-effort and must not
|
|
455
|
+
// affect the executor's own state transitions.
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
JobExecutor = _ts_decorate([
|
|
460
|
+
(0, _common.Injectable)(),
|
|
461
|
+
_ts_param(1, (0, _common.Inject)((0, _common.forwardRef)(()=>_transaction.TransactionManager))),
|
|
462
|
+
_ts_param(6, (0, _common.Optional)()),
|
|
463
|
+
_ts_metadata("design:type", Function),
|
|
464
|
+
_ts_metadata("design:paramtypes", [
|
|
465
|
+
typeof _repository.JobRepository === "undefined" ? Object : _repository.JobRepository,
|
|
466
|
+
typeof _transaction.TransactionManager === "undefined" ? Object : _transaction.TransactionManager,
|
|
467
|
+
typeof _taskletstepexecutor.TaskletStepExecutor === "undefined" ? Object : _taskletstepexecutor.TaskletStepExecutor,
|
|
468
|
+
typeof _chunkstepexecutor.ChunkStepExecutor === "undefined" ? Object : _chunkstepexecutor.ChunkStepExecutor,
|
|
469
|
+
typeof _listenerinvoker.ListenerInvoker === "undefined" ? Object : _listenerinvoker.ListenerInvoker,
|
|
470
|
+
typeof _flowevaluator.FlowEvaluator === "undefined" ? Object : _flowevaluator.FlowEvaluator,
|
|
471
|
+
typeof BatchObserver === "undefined" ? Object : BatchObserver
|
|
472
|
+
])
|
|
473
|
+
], JobExecutor);
|
|
474
|
+
|
|
475
|
+
//# sourceMappingURL=job-executor.js.map
|