tasker-engine 1.0.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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +443 -0
- data/Rakefile +10 -0
- data/app/controllers/tasker/analytics_controller.rb +179 -0
- data/app/controllers/tasker/application_controller.rb +45 -0
- data/app/controllers/tasker/graphql_controller.rb +193 -0
- data/app/controllers/tasker/handlers_controller.rb +217 -0
- data/app/controllers/tasker/health_controller.rb +229 -0
- data/app/controllers/tasker/metrics_controller.rb +111 -0
- data/app/controllers/tasker/page_sort.rb +97 -0
- data/app/controllers/tasker/task_diagrams_controller.rb +30 -0
- data/app/controllers/tasker/tasks_controller.rb +123 -0
- data/app/controllers/tasker/workflow_steps_controller.rb +69 -0
- data/app/graphql/examples/all_tasks.graphql +22 -0
- data/app/graphql/examples/pending_tasks.graphql +23 -0
- data/app/graphql/tasker/graph_ql_types/annotation_type.rb +14 -0
- data/app/graphql/tasker/graph_ql_types/base_argument.rb +9 -0
- data/app/graphql/tasker/graph_ql_types/base_connection.rb +11 -0
- data/app/graphql/tasker/graph_ql_types/base_edge.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_enum.rb +9 -0
- data/app/graphql/tasker/graph_ql_types/base_field.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_input_object.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_interface.rb +14 -0
- data/app/graphql/tasker/graph_ql_types/base_object.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_scalar.rb +9 -0
- data/app/graphql/tasker/graph_ql_types/base_union.rb +11 -0
- data/app/graphql/tasker/graph_ql_types/dependent_system_object_map_type.rb +18 -0
- data/app/graphql/tasker/graph_ql_types/dependent_system_type.rb +13 -0
- data/app/graphql/tasker/graph_ql_types/mutation_type.rb +16 -0
- data/app/graphql/tasker/graph_ql_types/named_step_type.rb +16 -0
- data/app/graphql/tasker/graph_ql_types/named_task_type.rb +14 -0
- data/app/graphql/tasker/graph_ql_types/named_tasks_named_step_type.rb +19 -0
- data/app/graphql/tasker/graph_ql_types/node_type.rb +12 -0
- data/app/graphql/tasker/graph_ql_types/query_type.rb +20 -0
- data/app/graphql/tasker/graph_ql_types/task_annotation_type.rb +17 -0
- data/app/graphql/tasker/graph_ql_types/task_interface.rb +17 -0
- data/app/graphql/tasker/graph_ql_types/task_type.rb +26 -0
- data/app/graphql/tasker/graph_ql_types/workflow_step_type.rb +154 -0
- data/app/graphql/tasker/graph_ql_types.rb +42 -0
- data/app/graphql/tasker/mutations/base_mutation.rb +13 -0
- data/app/graphql/tasker/mutations/cancel_step.rb +29 -0
- data/app/graphql/tasker/mutations/cancel_task.rb +29 -0
- data/app/graphql/tasker/mutations/create_task.rb +52 -0
- data/app/graphql/tasker/mutations/update_step.rb +36 -0
- data/app/graphql/tasker/mutations/update_task.rb +41 -0
- data/app/graphql/tasker/queries/all_annotation_types.rb +17 -0
- data/app/graphql/tasker/queries/all_tasks.rb +23 -0
- data/app/graphql/tasker/queries/base_query.rb +9 -0
- data/app/graphql/tasker/queries/helpers.rb +16 -0
- data/app/graphql/tasker/queries/one_step.rb +24 -0
- data/app/graphql/tasker/queries/one_task.rb +18 -0
- data/app/graphql/tasker/queries/tasks_by_annotation.rb +31 -0
- data/app/graphql/tasker/queries/tasks_by_status.rb +30 -0
- data/app/graphql/tasker/tasker_rails_schema.rb +52 -0
- data/app/jobs/tasker/application_job.rb +8 -0
- data/app/jobs/tasker/metrics_export_job.rb +252 -0
- data/app/jobs/tasker/task_runner_job.rb +224 -0
- data/app/models/tasker/annotation_type.rb +26 -0
- data/app/models/tasker/application_record.rb +70 -0
- data/app/models/tasker/dependent_system.rb +26 -0
- data/app/models/tasker/dependent_system_object_map.rb +64 -0
- data/app/models/tasker/diagram/edge.rb +106 -0
- data/app/models/tasker/diagram/flowchart.rb +137 -0
- data/app/models/tasker/diagram/node.rb +99 -0
- data/app/models/tasker/named_step.rb +41 -0
- data/app/models/tasker/named_task.rb +121 -0
- data/app/models/tasker/named_tasks_named_step.rb +82 -0
- data/app/models/tasker/step_dag_relationship.rb +65 -0
- data/app/models/tasker/step_readiness_status.rb +59 -0
- data/app/models/tasker/task.rb +424 -0
- data/app/models/tasker/task_annotation.rb +36 -0
- data/app/models/tasker/task_diagram.rb +332 -0
- data/app/models/tasker/task_execution_context.rb +29 -0
- data/app/models/tasker/task_namespace.rb +41 -0
- data/app/models/tasker/task_transition.rb +235 -0
- data/app/models/tasker/workflow_step.rb +461 -0
- data/app/models/tasker/workflow_step_edge.rb +94 -0
- data/app/models/tasker/workflow_step_transition.rb +434 -0
- data/app/serializers/tasker/annotation_type_serializer.rb +8 -0
- data/app/serializers/tasker/handler_serializer.rb +109 -0
- data/app/serializers/tasker/task_annotation_serializer.rb +32 -0
- data/app/serializers/tasker/task_serializer.rb +168 -0
- data/app/serializers/tasker/workflow_step_serializer.rb +27 -0
- data/app/services/tasker/analytics_service.rb +409 -0
- data/app/views/tasker/task/_diagram.html.erb +32 -0
- data/config/initializers/dry_struct.rb +11 -0
- data/config/initializers/statesman.rb +6 -0
- data/config/initializers/tasker_orchestration.rb +17 -0
- data/config/initializers/time_formats.rb +4 -0
- data/config/routes.rb +34 -0
- data/config/tasker/subscriptions/example_integrations.yml +67 -0
- data/config/tasker/system_events.yml +305 -0
- data/db/functions/calculate_dependency_levels_v01.sql +45 -0
- data/db/functions/get_analytics_metrics_v01.sql +137 -0
- data/db/functions/get_slowest_steps_v01.sql +82 -0
- data/db/functions/get_slowest_tasks_v01.sql +96 -0
- data/db/functions/get_step_readiness_status_batch_v01.sql +140 -0
- data/db/functions/get_step_readiness_status_v01.sql +139 -0
- data/db/functions/get_system_health_counts_v01.sql +108 -0
- data/db/functions/get_task_execution_context_v01.sql +108 -0
- data/db/functions/get_task_execution_contexts_batch_v01.sql +104 -0
- data/db/init/schema.sql +2277 -0
- data/db/migrate/20250701165431_initial_tasker_schema.rb +116 -0
- data/db/views/tasker_step_dag_relationships_v01.sql +69 -0
- data/docs/APPLICATION_GENERATOR.md +384 -0
- data/docs/AUTH.md +1780 -0
- data/docs/CIRCUIT_BREAKER.md +224 -0
- data/docs/DEVELOPER_GUIDE.md +2665 -0
- data/docs/EVENT_SYSTEM.md +637 -0
- data/docs/EXECUTION_CONFIGURATION.md +341 -0
- data/docs/FLOW_CHART.md +149 -0
- data/docs/HEALTH.md +542 -0
- data/docs/METRICS.md +731 -0
- data/docs/OPTIMIZATION_PLAN.md +1479 -0
- data/docs/OVERVIEW.md +552 -0
- data/docs/QUICK_START.md +270 -0
- data/docs/REGISTRY_SYSTEMS.md +373 -0
- data/docs/REST_API.md +632 -0
- data/docs/ROADMAP.md +221 -0
- data/docs/SQL_FUNCTIONS.md +1408 -0
- data/docs/TASK_DIAGRAM.md +252 -0
- data/docs/TASK_EXECUTION_CONTROL_FLOW.md +237 -0
- data/docs/TELEMETRY.md +795 -0
- data/docs/TROUBLESHOOTING.md +756 -0
- data/docs/TaskHandlerGenerator.html +255 -0
- data/docs/Tasker/Analysis/RuntimeGraphAnalyzer.html +907 -0
- data/docs/Tasker/Analysis/TemplateGraphAnalyzer.html +1236 -0
- data/docs/Tasker/Analysis.html +117 -0
- data/docs/Tasker/AnalyticsController.html +450 -0
- data/docs/Tasker/AnalyticsService/BottleneckAnalytics.html +816 -0
- data/docs/Tasker/AnalyticsService/PerformanceAnalytics.html +586 -0
- data/docs/Tasker/AnalyticsService.html +2221 -0
- data/docs/Tasker/AnnotationType.html +137 -0
- data/docs/Tasker/AnnotationTypeSerializer.html +124 -0
- data/docs/Tasker/ApplicationController.html +147 -0
- data/docs/Tasker/ApplicationJob.html +128 -0
- data/docs/Tasker/ApplicationRecord.html +378 -0
- data/docs/Tasker/Authentication/AuthenticationError.html +124 -0
- data/docs/Tasker/Authentication/ConfigurationError.html +124 -0
- data/docs/Tasker/Authentication/Coordinator.html +242 -0
- data/docs/Tasker/Authentication/Interface.html +560 -0
- data/docs/Tasker/Authentication/InterfaceError.html +124 -0
- data/docs/Tasker/Authentication/NoneAuthenticator.html +338 -0
- data/docs/Tasker/Authentication.html +119 -0
- data/docs/Tasker/Authorization/AuthorizationError.html +139 -0
- data/docs/Tasker/Authorization/BaseCoordinator.html +927 -0
- data/docs/Tasker/Authorization/ConfigurationError.html +153 -0
- data/docs/Tasker/Authorization/ResourceConstants/ACTIONS.html +428 -0
- data/docs/Tasker/Authorization/ResourceConstants/RESOURCES.html +365 -0
- data/docs/Tasker/Authorization/ResourceConstants.html +146 -0
- data/docs/Tasker/Authorization/ResourceRegistry.html +882 -0
- data/docs/Tasker/Authorization/UnauthorizedError.html +153 -0
- data/docs/Tasker/Authorization.html +582 -0
- data/docs/Tasker/CacheCapabilities.html +167 -0
- data/docs/Tasker/CacheStrategy.html +1297 -0
- data/docs/Tasker/Concerns/Authenticatable.html +116 -0
- data/docs/Tasker/Concerns/Authorizable/AdminStatusChecker.html +256 -0
- data/docs/Tasker/Concerns/Authorizable.html +816 -0
- data/docs/Tasker/Concerns/ControllerAuthorizable.html +157 -0
- data/docs/Tasker/Concerns/EventPublisher.html +4023 -0
- data/docs/Tasker/Concerns/IdempotentStateTransitions.html +806 -0
- data/docs/Tasker/Concerns/LifecycleEventHelpers.html +129 -0
- data/docs/Tasker/Concerns/OrchestrationPublisher.html +129 -0
- data/docs/Tasker/Concerns/StateMachineBase/ClassMethods.html +1075 -0
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase/ClassMethods.html +191 -0
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase.html +126 -0
- data/docs/Tasker/Concerns/StateMachineBase.html +153 -0
- data/docs/Tasker/Concerns/StructuredLogging.html +1413 -0
- data/docs/Tasker/Concerns.html +117 -0
- data/docs/Tasker/Configuration/AuthConfiguration.html +1023 -0
- data/docs/Tasker/Configuration/ConfigurationProxy.html +581 -0
- data/docs/Tasker/Configuration/DatabaseConfiguration.html +475 -0
- data/docs/Tasker/Configuration/EngineConfiguration.html +1265 -0
- data/docs/Tasker/Configuration/HealthConfiguration.html +791 -0
- data/docs/Tasker/Configuration/TelemetryConfiguration.html +1308 -0
- data/docs/Tasker/Configuration/TelemetryConfigurationProxy.html +388 -0
- data/docs/Tasker/Configuration.html +1669 -0
- data/docs/Tasker/ConfigurationError.html +143 -0
- data/docs/Tasker/ConfiguredTask.html +514 -0
- data/docs/Tasker/Constants/EventDefinitions.html +590 -0
- data/docs/Tasker/Constants/LifecycleEvents.html +137 -0
- data/docs/Tasker/Constants/ObservabilityEvents/Step.html +152 -0
- data/docs/Tasker/Constants/ObservabilityEvents/Task.html +142 -0
- data/docs/Tasker/Constants/ObservabilityEvents.html +126 -0
- data/docs/Tasker/Constants/RegistryEvents.html +285 -0
- data/docs/Tasker/Constants/StepEvents.html +177 -0
- data/docs/Tasker/Constants/TaskEvents.html +167 -0
- data/docs/Tasker/Constants/TaskExecution/ExecutionStatus.html +207 -0
- data/docs/Tasker/Constants/TaskExecution/HealthStatus.html +191 -0
- data/docs/Tasker/Constants/TaskExecution/RecommendedAction.html +207 -0
- data/docs/Tasker/Constants/TaskExecution.html +126 -0
- data/docs/Tasker/Constants/TaskFinalization/ErrorMessages.html +132 -0
- data/docs/Tasker/Constants/TaskFinalization/PendingReasons.html +207 -0
- data/docs/Tasker/Constants/TaskFinalization/ReenqueueReasons.html +239 -0
- data/docs/Tasker/Constants/TaskFinalization.html +126 -0
- data/docs/Tasker/Constants/TaskStatuses.html +223 -0
- data/docs/Tasker/Constants/TestEvents.html +163 -0
- data/docs/Tasker/Constants/WorkflowEvents.html +222 -0
- data/docs/Tasker/Constants/WorkflowStepStatuses.html +223 -0
- data/docs/Tasker/Constants.html +561 -0
- data/docs/Tasker/DependentSystem.html +137 -0
- data/docs/Tasker/DependentSystemObjectMap.html +250 -0
- data/docs/Tasker/DetectorRegistry.html +598 -0
- data/docs/Tasker/Diagram/Edge.html +1191 -0
- data/docs/Tasker/Diagram/Flowchart.html +1539 -0
- data/docs/Tasker/Diagram/Node.html +1165 -0
- data/docs/Tasker/Diagram.html +117 -0
- data/docs/Tasker/Engine.html +215 -0
- data/docs/Tasker/Error.html +139 -0
- data/docs/Tasker/Events/Bus.html +1226 -0
- data/docs/Tasker/Events/Catalog/CatalogPrinter.html +258 -0
- data/docs/Tasker/Events/Catalog/CustomEventRegistrar.html +276 -0
- data/docs/Tasker/Events/Catalog/ExamplePayloadGenerator.html +294 -0
- data/docs/Tasker/Events/Catalog.html +1291 -0
- data/docs/Tasker/Events/CustomRegistry.html +943 -0
- data/docs/Tasker/Events/DefinitionLoader.html +575 -0
- data/docs/Tasker/Events/EventPayloadBuilder/ErrorInfoExtractor.html +286 -0
- data/docs/Tasker/Events/EventPayloadBuilder/StepPayloadBuilder.html +312 -0
- data/docs/Tasker/Events/EventPayloadBuilder.html +664 -0
- data/docs/Tasker/Events/Publisher.html +365 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer/ErrorTypeClassifier.html +1128 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer.html +270 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/MetricTagsExtractor.html +266 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber.html +2556 -0
- data/docs/Tasker/Events/Subscribers/MetricsSubscriber.html +723 -0
- data/docs/Tasker/Events/Subscribers/TelemetrySubscriber.html +2251 -0
- data/docs/Tasker/Events/Subscribers.html +117 -0
- data/docs/Tasker/Events/SubscriptionLoader.html +493 -0
- data/docs/Tasker/Events.html +294 -0
- data/docs/Tasker/EventsGenerator.html +459 -0
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics/AnalyticsMetrics.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics.html +412 -0
- data/docs/Tasker/Functions/FunctionBasedDependencyLevels.html +598 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps/SlowestStep.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps.html +453 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks/SlowestTask.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks.html +453 -0
- data/docs/Tasker/Functions/FunctionBasedStepReadinessStatus.html +1457 -0
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts/HealthMetrics.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts.html +370 -0
- data/docs/Tasker/Functions/FunctionBasedTaskExecutionContext.html +1250 -0
- data/docs/Tasker/Functions/FunctionWrapper.html +479 -0
- data/docs/Tasker/Functions.html +117 -0
- data/docs/Tasker/Generators/AuthenticatorGenerator/UsageInstructionsFormatter.html +244 -0
- data/docs/Tasker/Generators/AuthenticatorGenerator.html +373 -0
- data/docs/Tasker/Generators/AuthorizationCoordinatorGenerator.html +430 -0
- data/docs/Tasker/Generators/SubscriberGenerator.html +377 -0
- data/docs/Tasker/Generators/TaskHandlerGenerator.html +263 -0
- data/docs/Tasker/Generators.html +117 -0
- data/docs/Tasker/GraphQLTypes/AnnotationType.html +132 -0
- data/docs/Tasker/GraphQLTypes/BaseArgument.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseConnection.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseEdge.html +130 -0
- data/docs/Tasker/GraphQLTypes/BaseEnum.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseField.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseInputObject.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseInterface.html +116 -0
- data/docs/Tasker/GraphQLTypes/BaseObject.html +128 -0
- data/docs/Tasker/GraphQLTypes/BaseScalar.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseUnion.html +124 -0
- data/docs/Tasker/GraphQLTypes/DependentSystemObjectMapType.html +132 -0
- data/docs/Tasker/GraphQLTypes/DependentSystemType.html +132 -0
- data/docs/Tasker/GraphQLTypes/MutationType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NamedStepType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NamedTaskType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NamedTasksNamedStepType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NodeType.html +118 -0
- data/docs/Tasker/GraphQLTypes/QueryType.html +139 -0
- data/docs/Tasker/GraphQLTypes/TaskAnnotationType.html +132 -0
- data/docs/Tasker/GraphQLTypes/TaskInterface.html +111 -0
- data/docs/Tasker/GraphQLTypes/TaskType.html +201 -0
- data/docs/Tasker/GraphQLTypes/WorkflowStepType.html +694 -0
- data/docs/Tasker/GraphQLTypes.html +130 -0
- data/docs/Tasker/GraphqlController.html +251 -0
- data/docs/Tasker/HandlerFactory.html +1518 -0
- data/docs/Tasker/HandlerSerializer.html +682 -0
- data/docs/Tasker/HandlersController.html +574 -0
- data/docs/Tasker/HashIdentityStrategy.html +278 -0
- data/docs/Tasker/Health/ReadinessChecker.html +712 -0
- data/docs/Tasker/Health/StatusChecker.html +653 -0
- data/docs/Tasker/Health.html +117 -0
- data/docs/Tasker/HealthController.html +523 -0
- data/docs/Tasker/IdentityStrategy.html +276 -0
- data/docs/Tasker/InvalidTaskHandlerConfig.html +135 -0
- data/docs/Tasker/LifecycleEvents/Events/Step.html +162 -0
- data/docs/Tasker/LifecycleEvents/Events/Task.html +162 -0
- data/docs/Tasker/LifecycleEvents/Events.html +204 -0
- data/docs/Tasker/LifecycleEvents/Publisher.html +132 -0
- data/docs/Tasker/LifecycleEvents.html +799 -0
- data/docs/Tasker/Logging/CorrelationIdGenerator.html +688 -0
- data/docs/Tasker/Logging.html +115 -0
- data/docs/Tasker/MetricsController.html +293 -0
- data/docs/Tasker/MetricsExportJob.html +414 -0
- data/docs/Tasker/Mutations/BaseMutation.html +128 -0
- data/docs/Tasker/Mutations/CancelStep.html +219 -0
- data/docs/Tasker/Mutations/CancelTask.html +221 -0
- data/docs/Tasker/Mutations/CreateTask.html +243 -0
- data/docs/Tasker/Mutations/UpdateStep.html +243 -0
- data/docs/Tasker/Mutations/UpdateTask.html +243 -0
- data/docs/Tasker/Mutations.html +117 -0
- data/docs/Tasker/NamedStep.html +216 -0
- data/docs/Tasker/NamedTask.html +910 -0
- data/docs/Tasker/NamedTasksNamedStep.html +435 -0
- data/docs/Tasker/Orchestration/BackoffCalculator.html +404 -0
- data/docs/Tasker/Orchestration/ConnectionBuilder/ConfigValidator.html +258 -0
- data/docs/Tasker/Orchestration/ConnectionBuilder.html +435 -0
- data/docs/Tasker/Orchestration/ConnectionPoolIntelligence.html +513 -0
- data/docs/Tasker/Orchestration/Coordinator.html +641 -0
- data/docs/Tasker/Orchestration/FutureStateAnalyzer.html +1045 -0
- data/docs/Tasker/Orchestration/Orchestrator.html +679 -0
- data/docs/Tasker/Orchestration/PluginIntegration.html +1127 -0
- data/docs/Tasker/Orchestration/ResponseProcessor.html +504 -0
- data/docs/Tasker/Orchestration/RetryHeaderParser.html +304 -0
- data/docs/Tasker/Orchestration/StepExecutor.html +995 -0
- data/docs/Tasker/Orchestration/StepSequenceFactory.html +644 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/BlockageChecker.html +264 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/ContextManager.html +254 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/DelayCalculator.html +556 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationDecisionMaker.html +348 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationProcessor.html +286 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/ReasonDeterminer.html +432 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/ReenqueueManager.html +296 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/UnclearStateHandler.html +314 -0
- data/docs/Tasker/Orchestration/TaskFinalizer.html +1212 -0
- data/docs/Tasker/Orchestration/TaskInitializer.html +766 -0
- data/docs/Tasker/Orchestration/TaskReenqueuer.html +506 -0
- data/docs/Tasker/Orchestration/ViableStepDiscovery.html +442 -0
- data/docs/Tasker/Orchestration/WorkflowCoordinator.html +510 -0
- data/docs/Tasker/Orchestration.html +130 -0
- data/docs/Tasker/PageSort/PageSortParamsBuilder.html +296 -0
- data/docs/Tasker/PageSort.html +247 -0
- data/docs/Tasker/PermanentError.html +518 -0
- data/docs/Tasker/ProceduralError.html +147 -0
- data/docs/Tasker/Queries/AllAnnotationTypes.html +217 -0
- data/docs/Tasker/Queries/AllTasks.html +221 -0
- data/docs/Tasker/Queries/BaseQuery.html +128 -0
- data/docs/Tasker/Queries/Helpers.html +187 -0
- data/docs/Tasker/Queries/OneStep.html +225 -0
- data/docs/Tasker/Queries/OneTask.html +217 -0
- data/docs/Tasker/Queries/TasksByAnnotation.html +231 -0
- data/docs/Tasker/Queries/TasksByStatus.html +233 -0
- data/docs/Tasker/Queries.html +119 -0
- data/docs/Tasker/Railtie.html +124 -0
- data/docs/Tasker/Registry/BaseRegistry.html +1690 -0
- data/docs/Tasker/Registry/EventPublisher.html +667 -0
- data/docs/Tasker/Registry/InterfaceValidator.html +569 -0
- data/docs/Tasker/Registry/RegistrationError.html +132 -0
- data/docs/Tasker/Registry/RegistryError.html +139 -0
- data/docs/Tasker/Registry/StatisticsCollector.html +841 -0
- data/docs/Tasker/Registry/SubscriberRegistry.html +1504 -0
- data/docs/Tasker/Registry/ValidationError.html +132 -0
- data/docs/Tasker/Registry.html +119 -0
- data/docs/Tasker/RetryableError.html +515 -0
- data/docs/Tasker/StateMachine/Compatibility.html +282 -0
- data/docs/Tasker/StateMachine/InvalidStateTransition.html +135 -0
- data/docs/Tasker/StateMachine/StepStateMachine/StandardizedPayloadBuilder.html +260 -0
- data/docs/Tasker/StateMachine/StepStateMachine.html +2215 -0
- data/docs/Tasker/StateMachine/TaskStateMachine.html +734 -0
- data/docs/Tasker/StateMachine.html +602 -0
- data/docs/Tasker/StepDagRelationship.html +657 -0
- data/docs/Tasker/StepHandler/Api/Config.html +1091 -0
- data/docs/Tasker/StepHandler/Api.html +884 -0
- data/docs/Tasker/StepHandler/AutomaticEventPublishing.html +321 -0
- data/docs/Tasker/StepHandler/Base.html +970 -0
- data/docs/Tasker/StepHandler.html +119 -0
- data/docs/Tasker/StepReadinessStatus.html +836 -0
- data/docs/Tasker/Task.html +2575 -0
- data/docs/Tasker/TaskAnnotation.html +137 -0
- data/docs/Tasker/TaskAnnotationSerializer.html +124 -0
- data/docs/Tasker/TaskBuilder/StepNameValidator.html +264 -0
- data/docs/Tasker/TaskBuilder/StepTemplateDefiner.html +264 -0
- data/docs/Tasker/TaskBuilder.html +764 -0
- data/docs/Tasker/TaskDiagram/StepToStepEdgeBuilder.html +260 -0
- data/docs/Tasker/TaskDiagram/TaskToRootStepEdgeBuilder.html +290 -0
- data/docs/Tasker/TaskDiagram.html +548 -0
- data/docs/Tasker/TaskDiagramsController.html +240 -0
- data/docs/Tasker/TaskExecutionContext.html +469 -0
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/ClassBasedEventRegistrar.html +238 -0
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/YamlEventRegistrar.html +254 -0
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner.html +988 -0
- data/docs/Tasker/TaskHandler/ClassMethods.html +357 -0
- data/docs/Tasker/TaskHandler/InstanceMethods.html +1396 -0
- data/docs/Tasker/TaskHandler/StepGroup.html +1748 -0
- data/docs/Tasker/TaskHandler.html +271 -0
- data/docs/Tasker/TaskNamespace.html +312 -0
- data/docs/Tasker/TaskRunnerJob.html +406 -0
- data/docs/Tasker/TaskSerializer.html +474 -0
- data/docs/Tasker/TaskTransition.html +1517 -0
- data/docs/Tasker/TaskWorkflowSummary.html +988 -0
- data/docs/Tasker/TaskerRailsSchema/InvalidObjectTypeError.html +132 -0
- data/docs/Tasker/TaskerRailsSchema/TypeResolutionError.html +139 -0
- data/docs/Tasker/TaskerRailsSchema/UnknownInterfaceError.html +132 -0
- data/docs/Tasker/TaskerRailsSchema.html +384 -0
- data/docs/Tasker/TasksController.html +595 -0
- data/docs/Tasker/Telemetry/EventMapping.html +1307 -0
- data/docs/Tasker/Telemetry/EventRouter.html +2178 -0
- data/docs/Tasker/Telemetry/Events/ExportEvents.html +246 -0
- data/docs/Tasker/Telemetry/Events.html +115 -0
- data/docs/Tasker/Telemetry/ExportCoordinator/DistributedLockTimeoutError.html +135 -0
- data/docs/Tasker/Telemetry/ExportCoordinator.html +2137 -0
- data/docs/Tasker/Telemetry/IntelligentCacheManager.html +1083 -0
- data/docs/Tasker/Telemetry/LogBackend.html +1088 -0
- data/docs/Tasker/Telemetry/MetricTypes/Counter.html +1054 -0
- data/docs/Tasker/Telemetry/MetricTypes/Gauge.html +1270 -0
- data/docs/Tasker/Telemetry/MetricTypes/Histogram.html +1492 -0
- data/docs/Tasker/Telemetry/MetricTypes.html +153 -0
- data/docs/Tasker/Telemetry/MetricsBackend.html +2510 -0
- data/docs/Tasker/Telemetry/MetricsExportService.html +578 -0
- data/docs/Tasker/Telemetry/PluginRegistry.html +1774 -0
- data/docs/Tasker/Telemetry/Plugins/BaseExporter.html +1835 -0
- data/docs/Tasker/Telemetry/Plugins/CsvExporter.html +768 -0
- data/docs/Tasker/Telemetry/Plugins/JsonExporter.html +747 -0
- data/docs/Tasker/Telemetry/Plugins.html +117 -0
- data/docs/Tasker/Telemetry/PrometheusExporter.html +481 -0
- data/docs/Tasker/Telemetry/TraceBackend.html +891 -0
- data/docs/Tasker/Telemetry.html +130 -0
- data/docs/Tasker/Types/AuthConfig.html +886 -0
- data/docs/Tasker/Types/BackoffConfig.html +1063 -0
- data/docs/Tasker/Types/BaseConfig.html +227 -0
- data/docs/Tasker/Types/CacheConfig.html +1731 -0
- data/docs/Tasker/Types/DatabaseConfig.html +388 -0
- data/docs/Tasker/Types/DependencyGraph.html +526 -0
- data/docs/Tasker/Types/DependencyGraphConfig.html +753 -0
- data/docs/Tasker/Types/EngineConfig.html +1181 -0
- data/docs/Tasker/Types/ExecutionConfig.html +1963 -0
- data/docs/Tasker/Types/GraphEdge.html +517 -0
- data/docs/Tasker/Types/GraphMetadata.html +781 -0
- data/docs/Tasker/Types/GraphNode.html +694 -0
- data/docs/Tasker/Types/HealthConfig.html +784 -0
- data/docs/Tasker/Types/StepSequence.html +353 -0
- data/docs/Tasker/Types/StepTemplate.html +1193 -0
- data/docs/Tasker/Types/TaskRequest.html +1179 -0
- data/docs/Tasker/Types/TelemetryConfig.html +2746 -0
- data/docs/Tasker/Types.html +154 -0
- data/docs/Tasker/WorkflowStep/StepFinder.html +282 -0
- data/docs/Tasker/WorkflowStep.html +2724 -0
- data/docs/Tasker/WorkflowStepEdge.html +304 -0
- data/docs/Tasker/WorkflowStepSerializer.html +305 -0
- data/docs/Tasker/WorkflowStepTransition/TransitionDescriptionFormatter.html +282 -0
- data/docs/Tasker/WorkflowStepTransition.html +2201 -0
- data/docs/Tasker/WorkflowStepsController.html +462 -0
- data/docs/Tasker.html +452 -0
- data/docs/VISION.md +584 -0
- data/docs/WHY.md +21 -0
- data/docs/_index.html +2375 -0
- data/docs/class_list.html +54 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +503 -0
- data/docs/events/migration_plan_outcomes.md +80 -0
- data/docs/file.README.html +541 -0
- data/docs/file_list.html +59 -0
- data/docs/frames.html +22 -0
- data/docs/index.html +541 -0
- data/docs/js/app.js +344 -0
- data/docs/js/full_list.js +242 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +9182 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/generators/tasker/authenticator_generator.rb +301 -0
- data/lib/generators/tasker/authorization_coordinator_generator.rb +139 -0
- data/lib/generators/tasker/events_generator.rb +91 -0
- data/lib/generators/tasker/subscriber_generator.rb +107 -0
- data/lib/generators/tasker/task_handler_generator.rb +138 -0
- data/lib/generators/tasker/templates/api_token_authenticator.rb.erb +113 -0
- data/lib/generators/tasker/templates/api_token_authenticator_spec.rb.erb +144 -0
- data/lib/generators/tasker/templates/authorization_coordinator.rb.erb +95 -0
- data/lib/generators/tasker/templates/authorization_coordinator_spec.rb.erb +142 -0
- data/lib/generators/tasker/templates/custom_authenticator.rb.erb +108 -0
- data/lib/generators/tasker/templates/custom_authenticator_spec.rb.erb +162 -0
- data/lib/generators/tasker/templates/custom_events.yml.erb +62 -0
- data/lib/generators/tasker/templates/custom_subscriber.rb.erb +72 -0
- data/lib/generators/tasker/templates/devise_authenticator.rb.erb +101 -0
- data/lib/generators/tasker/templates/devise_authenticator_spec.rb.erb +126 -0
- data/lib/generators/tasker/templates/initialize.rb.erb +202 -0
- data/lib/generators/tasker/templates/jwt_authenticator.rb.erb +144 -0
- data/lib/generators/tasker/templates/jwt_authenticator_spec.rb.erb +298 -0
- data/lib/generators/tasker/templates/metrics_subscriber.rb.erb +258 -0
- data/lib/generators/tasker/templates/metrics_subscriber_spec.rb.erb +308 -0
- data/lib/generators/tasker/templates/omniauth_authenticator.rb.erb +135 -0
- data/lib/generators/tasker/templates/omniauth_authenticator_spec.rb.erb +196 -0
- data/lib/generators/tasker/templates/opentelemetry_initializer.rb +52 -0
- data/lib/generators/tasker/templates/subscriber.rb.erb +64 -0
- data/lib/generators/tasker/templates/subscriber_spec.rb.erb +80 -0
- data/lib/generators/tasker/templates/task_config.yaml.erb +117 -0
- data/lib/generators/tasker/templates/task_handler.rb.erb +59 -0
- data/lib/generators/tasker/templates/task_handler_spec.rb.erb +159 -0
- data/lib/tasker/analysis/runtime_graph_analyzer.rb +1168 -0
- data/lib/tasker/analysis/template_graph_analyzer.rb +328 -0
- data/lib/tasker/authentication/coordinator.rb +78 -0
- data/lib/tasker/authentication/errors.rb +9 -0
- data/lib/tasker/authentication/interface.rb +36 -0
- data/lib/tasker/authentication/none_authenticator.rb +26 -0
- data/lib/tasker/authorization/base_coordinator.rb +112 -0
- data/lib/tasker/authorization/errors.rb +26 -0
- data/lib/tasker/authorization/resource_constants.rb +74 -0
- data/lib/tasker/authorization/resource_registry.rb +143 -0
- data/lib/tasker/authorization.rb +75 -0
- data/lib/tasker/cache_capabilities.rb +131 -0
- data/lib/tasker/cache_strategy.rb +469 -0
- data/lib/tasker/concerns/authenticatable.rb +41 -0
- data/lib/tasker/concerns/authorizable.rb +204 -0
- data/lib/tasker/concerns/controller_authorizable.rb +124 -0
- data/lib/tasker/concerns/event_publisher.rb +716 -0
- data/lib/tasker/concerns/idempotent_state_transitions.rb +128 -0
- data/lib/tasker/concerns/state_machine_base.rb +218 -0
- data/lib/tasker/concerns/structured_logging.rb +387 -0
- data/lib/tasker/configuration.rb +325 -0
- data/lib/tasker/constants/event_definitions.rb +147 -0
- data/lib/tasker/constants/registry_events.rb +54 -0
- data/lib/tasker/constants.rb +417 -0
- data/lib/tasker/engine.rb +90 -0
- data/lib/tasker/errors.rb +90 -0
- data/lib/tasker/events/catalog.rb +432 -0
- data/lib/tasker/events/custom_registry.rb +175 -0
- data/lib/tasker/events/definition_loader.rb +199 -0
- data/lib/tasker/events/event_payload_builder.rb +461 -0
- data/lib/tasker/events/publisher.rb +149 -0
- data/lib/tasker/events/subscribers/base_subscriber.rb +601 -0
- data/lib/tasker/events/subscribers/metrics_subscriber.rb +120 -0
- data/lib/tasker/events/subscribers/telemetry_subscriber.rb +462 -0
- data/lib/tasker/events/subscription_loader.rb +161 -0
- data/lib/tasker/events.rb +37 -0
- data/lib/tasker/functions/function_based_analytics_metrics.rb +103 -0
- data/lib/tasker/functions/function_based_dependency_levels.rb +54 -0
- data/lib/tasker/functions/function_based_slowest_steps.rb +84 -0
- data/lib/tasker/functions/function_based_slowest_tasks.rb +84 -0
- data/lib/tasker/functions/function_based_step_readiness_status.rb +183 -0
- data/lib/tasker/functions/function_based_system_health_counts.rb +94 -0
- data/lib/tasker/functions/function_based_task_execution_context.rb +148 -0
- data/lib/tasker/functions/function_wrapper.rb +42 -0
- data/lib/tasker/functions.rb +12 -0
- data/lib/tasker/handler_factory.rb +322 -0
- data/lib/tasker/health/readiness_checker.rb +186 -0
- data/lib/tasker/health/status_checker.rb +203 -0
- data/lib/tasker/identity_strategy.rb +38 -0
- data/lib/tasker/logging/correlation_id_generator.rb +120 -0
- data/lib/tasker/orchestration/backoff_calculator.rb +184 -0
- data/lib/tasker/orchestration/connection_builder.rb +122 -0
- data/lib/tasker/orchestration/connection_pool_intelligence.rb +177 -0
- data/lib/tasker/orchestration/coordinator.rb +119 -0
- data/lib/tasker/orchestration/future_state_analyzer.rb +137 -0
- data/lib/tasker/orchestration/plugin_integration.rb +124 -0
- data/lib/tasker/orchestration/response_processor.rb +168 -0
- data/lib/tasker/orchestration/retry_header_parser.rb +78 -0
- data/lib/tasker/orchestration/step_executor.rb +941 -0
- data/lib/tasker/orchestration/step_sequence_factory.rb +67 -0
- data/lib/tasker/orchestration/task_finalizer.rb +564 -0
- data/lib/tasker/orchestration/task_initializer.rb +140 -0
- data/lib/tasker/orchestration/task_reenqueuer.rb +71 -0
- data/lib/tasker/orchestration/viable_step_discovery.rb +65 -0
- data/lib/tasker/orchestration/workflow_coordinator.rb +294 -0
- data/lib/tasker/orchestration.rb +45 -0
- data/lib/tasker/railtie.rb +9 -0
- data/lib/tasker/registry/base_registry.rb +177 -0
- data/lib/tasker/registry/event_publisher.rb +91 -0
- data/lib/tasker/registry/interface_validator.rb +140 -0
- data/lib/tasker/registry/statistics_collector.rb +381 -0
- data/lib/tasker/registry/subscriber_registry.rb +285 -0
- data/lib/tasker/registry.rb +22 -0
- data/lib/tasker/state_machine/step_state_machine.rb +508 -0
- data/lib/tasker/state_machine/task_state_machine.rb +192 -0
- data/lib/tasker/state_machine.rb +83 -0
- data/lib/tasker/step_handler/api.rb +410 -0
- data/lib/tasker/step_handler/base.rb +206 -0
- data/lib/tasker/task_builder.rb +432 -0
- data/lib/tasker/task_handler/class_methods.rb +324 -0
- data/lib/tasker/task_handler/instance_methods.rb +293 -0
- data/lib/tasker/task_handler/step_group.rb +182 -0
- data/lib/tasker/task_handler.rb +43 -0
- data/lib/tasker/telemetry/event_mapping.rb +126 -0
- data/lib/tasker/telemetry/event_router.rb +318 -0
- data/lib/tasker/telemetry/events/export_events.rb +38 -0
- data/lib/tasker/telemetry/export_coordinator.rb +497 -0
- data/lib/tasker/telemetry/intelligent_cache_manager.rb +508 -0
- data/lib/tasker/telemetry/log_backend.rb +224 -0
- data/lib/tasker/telemetry/metric_types.rb +368 -0
- data/lib/tasker/telemetry/metrics_backend.rb +1227 -0
- data/lib/tasker/telemetry/metrics_export_service.rb +392 -0
- data/lib/tasker/telemetry/plugin_registry.rb +333 -0
- data/lib/tasker/telemetry/plugins/base_exporter.rb +246 -0
- data/lib/tasker/telemetry/plugins/csv_exporter.rb +198 -0
- data/lib/tasker/telemetry/plugins/json_exporter.rb +141 -0
- data/lib/tasker/telemetry/prometheus_exporter.rb +249 -0
- data/lib/tasker/telemetry/trace_backend.rb +186 -0
- data/lib/tasker/telemetry.rb +59 -0
- data/lib/tasker/types/auth_config.rb +81 -0
- data/lib/tasker/types/backoff_config.rb +142 -0
- data/lib/tasker/types/cache_config.rb +257 -0
- data/lib/tasker/types/database_config.rb +39 -0
- data/lib/tasker/types/dependency_graph.rb +225 -0
- data/lib/tasker/types/dependency_graph_config.rb +149 -0
- data/lib/tasker/types/engine_config.rb +131 -0
- data/lib/tasker/types/execution_config.rb +289 -0
- data/lib/tasker/types/health_config.rb +84 -0
- data/lib/tasker/types/step_sequence.rb +24 -0
- data/lib/tasker/types/step_template.rb +63 -0
- data/lib/tasker/types/task_request.rb +60 -0
- data/lib/tasker/types/telemetry_config.rb +273 -0
- data/lib/tasker/types.rb +64 -0
- data/lib/tasker/version.rb +7 -0
- data/lib/tasker.rb +82 -0
- data/lib/tasks/tasker_tasks.rake +302 -0
- metadata +958 -0
@@ -0,0 +1,140 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../concerns/idempotent_state_transitions'
|
4
|
+
require_relative '../concerns/event_publisher'
|
5
|
+
require 'tasker/events/event_payload_builder'
|
6
|
+
|
7
|
+
module Tasker
|
8
|
+
module Orchestration
|
9
|
+
# TaskInitializer handles task creation and initialization logic
|
10
|
+
#
|
11
|
+
# This component is responsible for:
|
12
|
+
# - Creating tasks from TaskRequest objects
|
13
|
+
# - Validating task context against schemas
|
14
|
+
# - Starting task execution (transitioning to in_progress)
|
15
|
+
# - Enqueuing tasks for processing
|
16
|
+
class TaskInitializer
|
17
|
+
include Tasker::Concerns::IdempotentStateTransitions
|
18
|
+
include Tasker::Concerns::EventPublisher
|
19
|
+
|
20
|
+
class << self
|
21
|
+
# Initialize a new task from a task request
|
22
|
+
#
|
23
|
+
# Creates a task record, validates the context against the schema,
|
24
|
+
# and enqueues the task for processing.
|
25
|
+
#
|
26
|
+
# @param task_request [Tasker::Types::TaskRequest] The task request
|
27
|
+
# @param task_handler [Object] The task handler instance for schema validation
|
28
|
+
# @return [Tasker::Task] The created task
|
29
|
+
delegate :initialize_task!, to: :new
|
30
|
+
|
31
|
+
# Start a task's execution
|
32
|
+
#
|
33
|
+
# Updates the task status to IN_PROGRESS and fires the appropriate event.
|
34
|
+
#
|
35
|
+
# @param task [Tasker::Task] The task to start
|
36
|
+
# @return [Boolean] True if the task was started successfully
|
37
|
+
delegate :start_task!, to: :new
|
38
|
+
end
|
39
|
+
|
40
|
+
# Initialize a new task from a task request
|
41
|
+
#
|
42
|
+
# @param task_request [Tasker::Types::TaskRequest] The task request
|
43
|
+
# @param task_handler [Object] The task handler instance for schema validation
|
44
|
+
# @return [Tasker::Task] The created task
|
45
|
+
def initialize_task!(task_request, task_handler)
|
46
|
+
task = nil
|
47
|
+
context_errors = validate_context_with_handler(task_request.context, task_handler)
|
48
|
+
|
49
|
+
if context_errors.length.positive?
|
50
|
+
task = Tasker::Task.from_task_request(task_request)
|
51
|
+
context_errors.each do |error|
|
52
|
+
task.errors.add(:context, error)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Use clean API for task initialization failure
|
56
|
+
publish_task_failed(
|
57
|
+
task,
|
58
|
+
error_message: context_errors.join(', '),
|
59
|
+
initialization_failed: true
|
60
|
+
)
|
61
|
+
return task
|
62
|
+
end
|
63
|
+
|
64
|
+
Tasker::Task.transaction do
|
65
|
+
task = Tasker::Task.create_with_defaults!(task_request)
|
66
|
+
# Get sequence and establish dependencies
|
67
|
+
StepSequenceFactory.create_sequence_for_task!(task, task_handler)
|
68
|
+
end
|
69
|
+
|
70
|
+
# Use clean API for task initialization success
|
71
|
+
publish_task_started(
|
72
|
+
task,
|
73
|
+
step_count: task.workflow_steps.count
|
74
|
+
)
|
75
|
+
|
76
|
+
enqueue_task(task)
|
77
|
+
task
|
78
|
+
end
|
79
|
+
|
80
|
+
# Start a task's execution
|
81
|
+
#
|
82
|
+
# @param task [Tasker::Task] The task to start
|
83
|
+
# @return [Boolean] True if the task was started successfully
|
84
|
+
def start_task!(task)
|
85
|
+
raise(Tasker::ProceduralError, "task already complete for task #{task.task_id}") if task.complete
|
86
|
+
|
87
|
+
unless task.status == Tasker::Constants::TaskStatuses::PENDING
|
88
|
+
raise(Tasker::ProceduralError,
|
89
|
+
"task is not pending for task #{task.task_id}, status is #{task.status}")
|
90
|
+
end
|
91
|
+
|
92
|
+
task.context = ActiveSupport::HashWithIndifferentAccess.new(task.context)
|
93
|
+
|
94
|
+
# Use state machine to transition task to in_progress
|
95
|
+
unless safe_transition_to(task, Tasker::Constants::TaskStatuses::IN_PROGRESS, {
|
96
|
+
initialization_completed: true,
|
97
|
+
step_dependencies_established: task.workflow_steps.count
|
98
|
+
})
|
99
|
+
|
100
|
+
# Use clean API for task start failure
|
101
|
+
publish_task_failed(
|
102
|
+
task,
|
103
|
+
error_message: 'Failed to transition to in_progress',
|
104
|
+
initialization_failed: true
|
105
|
+
)
|
106
|
+
|
107
|
+
return false
|
108
|
+
end
|
109
|
+
|
110
|
+
# Use clean API for task start success
|
111
|
+
publish_task_started(task, task_context: task.context)
|
112
|
+
|
113
|
+
true
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
# Validate a task context against the handler's schema
|
119
|
+
#
|
120
|
+
# @param context [Hash] The context to validate
|
121
|
+
# @param task_handler [Object] The task handler with schema
|
122
|
+
# @return [Array<String>] Validation errors, if any
|
123
|
+
def validate_context_with_handler(context, task_handler)
|
124
|
+
return [] unless task_handler.respond_to?(:schema) && task_handler.schema
|
125
|
+
|
126
|
+
data = context.to_hash.deep_symbolize_keys
|
127
|
+
JSON::Validator.fully_validate(task_handler.schema, data, strict: true, insert_defaults: true)
|
128
|
+
end
|
129
|
+
|
130
|
+
# Enqueue a task for processing
|
131
|
+
#
|
132
|
+
# @param task [Tasker::Task] The task to enqueue
|
133
|
+
def enqueue_task(task)
|
134
|
+
publish_task_enqueue(task)
|
135
|
+
|
136
|
+
Tasker::TaskRunnerJob.perform_later(task.task_id)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../concerns/idempotent_state_transitions'
|
4
|
+
require_relative '../concerns/event_publisher'
|
5
|
+
|
6
|
+
module Tasker
|
7
|
+
module Orchestration
|
8
|
+
# TaskReenqueuer handles the mechanics of re-enqueueing tasks for continued processing
|
9
|
+
#
|
10
|
+
# This class provides implementation for task re-enqueueing logic while firing
|
11
|
+
# lifecycle events for observability. Separates the decision to re-enqueue
|
12
|
+
# from the mechanics of how re-enqueueing works.
|
13
|
+
class TaskReenqueuer
|
14
|
+
include Tasker::Concerns::IdempotentStateTransitions
|
15
|
+
include Tasker::Concerns::EventPublisher
|
16
|
+
|
17
|
+
# Re-enqueue a task for continued processing
|
18
|
+
#
|
19
|
+
# @param task [Tasker::Task] The task to re-enqueue
|
20
|
+
# @param reason [String] The reason for re-enqueueing (for observability)
|
21
|
+
# @return [Boolean] True if re-enqueueing was successful
|
22
|
+
def reenqueue_task(task, reason: Constants::TaskFinalization::ReenqueueReasons::PENDING_STEPS_REMAINING)
|
23
|
+
# Fire re-enqueue started event
|
24
|
+
publish_task_reenqueue_started(task, reason: reason)
|
25
|
+
|
26
|
+
# Transition task back to pending state for clarity
|
27
|
+
if safe_transition_to(task, Tasker::Constants::TaskStatuses::PENDING)
|
28
|
+
Rails.logger.debug { "TaskReenqueuer: Task #{task.task_id} transitioned back to pending" }
|
29
|
+
end
|
30
|
+
|
31
|
+
# Enqueue the task for processing
|
32
|
+
Tasker::TaskRunnerJob.perform_later(task.task_id)
|
33
|
+
|
34
|
+
# Fire re-enqueue completed event
|
35
|
+
publish_task_reenqueue_requested(task, reason: reason)
|
36
|
+
|
37
|
+
Rails.logger.debug { "TaskReenqueuer: Task #{task.task_id} re-enqueued due to #{reason}" }
|
38
|
+
true
|
39
|
+
rescue StandardError => e
|
40
|
+
# Fire re-enqueue failed event
|
41
|
+
publish_task_reenqueue_failed(task, reason: reason, error: e.message)
|
42
|
+
|
43
|
+
Rails.logger.error("TaskReenqueuer: Failed to re-enqueue task #{task.task_id}: #{e.message}")
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
# Schedule a delayed re-enqueue (for retry scenarios)
|
48
|
+
#
|
49
|
+
# @param task [Tasker::Task] The task to re-enqueue
|
50
|
+
# @param delay_seconds [Integer] Number of seconds to delay
|
51
|
+
# @param reason [String] The reason for delayed re-enqueueing
|
52
|
+
# @return [Boolean] True if scheduling was successful
|
53
|
+
def reenqueue_task_delayed(task, delay_seconds:,
|
54
|
+
reason: Constants::TaskFinalization::ReenqueueReasons::RETRY_BACKOFF)
|
55
|
+
# Fire delayed re-enqueue started event
|
56
|
+
publish_task_reenqueue_delayed(task, delay_seconds: delay_seconds, reason: reason)
|
57
|
+
|
58
|
+
# Schedule the delayed job
|
59
|
+
Tasker::TaskRunnerJob.set(wait: delay_seconds.seconds).perform_later(task.task_id)
|
60
|
+
|
61
|
+
Rails.logger.debug do
|
62
|
+
"TaskReenqueuer: Task #{task.task_id} scheduled for re-enqueue in #{delay_seconds} seconds"
|
63
|
+
end
|
64
|
+
true
|
65
|
+
rescue StandardError => e
|
66
|
+
Rails.logger.error("TaskReenqueuer: Failed to schedule delayed re-enqueue for task #{task.task_id}: #{e.message}")
|
67
|
+
false
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../concerns/idempotent_state_transitions'
|
4
|
+
require_relative '../concerns/event_publisher'
|
5
|
+
require_relative '../types/step_sequence'
|
6
|
+
|
7
|
+
module Tasker
|
8
|
+
module Orchestration
|
9
|
+
# ViableStepDiscovery provides implementation for finding steps ready for execution
|
10
|
+
#
|
11
|
+
# This class is a simple implementation provider that wraps the existing
|
12
|
+
# WorkflowStep.get_viable_steps logic while firing lifecycle events
|
13
|
+
# for observability. No complex event subscriptions needed.
|
14
|
+
class ViableStepDiscovery
|
15
|
+
include Tasker::Concerns::EventPublisher
|
16
|
+
|
17
|
+
# Find viable steps for execution
|
18
|
+
#
|
19
|
+
# This is just a clean wrapper around the existing WorkflowStep.get_viable_steps
|
20
|
+
# method that fires observability events.
|
21
|
+
#
|
22
|
+
# @param task [Tasker::Task] The task to find steps for
|
23
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
24
|
+
# @return [Array<Tasker::WorkflowStep>] Array of viable steps
|
25
|
+
def find_viable_steps(task, sequence)
|
26
|
+
# Use the existing proven logic - this is where the real work happens
|
27
|
+
viable_steps = Tasker::WorkflowStep.get_viable_steps(task, sequence)
|
28
|
+
|
29
|
+
# Fire appropriate discovery event based on results through orchestrator
|
30
|
+
if viable_steps.any?
|
31
|
+
publish_viable_steps_discovered(
|
32
|
+
task.task_id,
|
33
|
+
viable_steps.map(&:workflow_step_id),
|
34
|
+
processing_mode: 'concurrent',
|
35
|
+
viable_count: viable_steps.size,
|
36
|
+
step_names: viable_steps.map(&:name)
|
37
|
+
)
|
38
|
+
else
|
39
|
+
publish_no_viable_steps(
|
40
|
+
task.task_id,
|
41
|
+
reason: 'No steps ready for execution',
|
42
|
+
total_steps_checked: sequence.steps.size
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
Rails.logger.debug { "ViableStepDiscovery: Found #{viable_steps.size} viable steps for task #{task.task_id}" }
|
47
|
+
viable_steps
|
48
|
+
end
|
49
|
+
|
50
|
+
# Discover viable steps for a task by task ID
|
51
|
+
#
|
52
|
+
# Convenience method for testing and external usage that loads a task
|
53
|
+
# and gets its sequence before calling find_viable_steps.
|
54
|
+
#
|
55
|
+
# @param task_id [String] The task ID to discover steps for
|
56
|
+
# @return [Array<Tasker::WorkflowStep>] Array of viable steps
|
57
|
+
def discover_steps_for_task(task_id)
|
58
|
+
task = Tasker::Task.find(task_id)
|
59
|
+
task_handler = Tasker::HandlerFactory.instance.get(task.name)
|
60
|
+
sequence = Tasker::Orchestration::StepSequenceFactory.get_sequence(task, task_handler)
|
61
|
+
find_viable_steps(task, sequence)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,294 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tasker
|
4
|
+
module Orchestration
|
5
|
+
# WorkflowCoordinator handles the main task execution loop
|
6
|
+
#
|
7
|
+
# This coordinator extracts the proven loop-based execution logic from TaskHandler
|
8
|
+
# and provides a strategy pattern for composition with different reenqueuer strategies.
|
9
|
+
# This enables proper testing of the complete workflow execution path.
|
10
|
+
#
|
11
|
+
# Enhanced with structured logging and performance monitoring for production observability.
|
12
|
+
class WorkflowCoordinator
|
13
|
+
include Tasker::Concerns::StructuredLogging
|
14
|
+
include Tasker::Concerns::EventPublisher
|
15
|
+
|
16
|
+
attr_reader :reenqueuer_strategy
|
17
|
+
|
18
|
+
# Initialize coordinator with reenqueuer strategy
|
19
|
+
#
|
20
|
+
# @param reenqueuer_strategy [Object] Strategy for handling task reenqueuing
|
21
|
+
def initialize(reenqueuer_strategy: nil)
|
22
|
+
@reenqueuer_strategy = reenqueuer_strategy || default_reenqueuer_strategy
|
23
|
+
end
|
24
|
+
|
25
|
+
# Execute the complete workflow for a task
|
26
|
+
#
|
27
|
+
# This method contains the proven loop logic extracted from TaskHandler#handle
|
28
|
+
# and delegates to orchestration components for implementation details.
|
29
|
+
#
|
30
|
+
# Enhanced with correlation ID propagation and structured logging.
|
31
|
+
#
|
32
|
+
# @param task [Tasker::Task] The task to execute
|
33
|
+
# @param task_handler [Object] The task handler instance for delegation
|
34
|
+
# @return [void]
|
35
|
+
def execute_workflow(task, task_handler)
|
36
|
+
# Establish correlation ID for the entire workflow execution
|
37
|
+
workflow_correlation_id = correlation_id
|
38
|
+
|
39
|
+
with_correlation_id(workflow_correlation_id) do
|
40
|
+
log_orchestration_event('workflow_execution', :started,
|
41
|
+
task_id: task.task_id,
|
42
|
+
task_name: task.name,
|
43
|
+
correlation_id: workflow_correlation_id)
|
44
|
+
|
45
|
+
# Publish workflow started event
|
46
|
+
publish_workflow_task_started(task.task_id, correlation_id: workflow_correlation_id)
|
47
|
+
|
48
|
+
# Execute the main workflow loop with performance monitoring
|
49
|
+
execute_workflow_with_monitoring(task, task_handler)
|
50
|
+
end
|
51
|
+
rescue StandardError => e
|
52
|
+
log_exception(e, context: {
|
53
|
+
task_id: task.task_id,
|
54
|
+
operation: 'workflow_execution',
|
55
|
+
correlation_id: workflow_correlation_id
|
56
|
+
})
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
# Execute workflow with performance monitoring
|
63
|
+
#
|
64
|
+
# @param task [Tasker::Task] The task to execute
|
65
|
+
# @param task_handler [Object] The task handler instance
|
66
|
+
# @return [void]
|
67
|
+
def execute_workflow_with_monitoring(task, task_handler)
|
68
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
69
|
+
all_processed_steps = []
|
70
|
+
loop_iteration = 0
|
71
|
+
|
72
|
+
log_performance_event('workflow_execution', 0,
|
73
|
+
task_id: task.task_id,
|
74
|
+
operation: 'workflow_start')
|
75
|
+
|
76
|
+
# PROVEN APPROACH: Process steps iteratively until completion or error
|
77
|
+
loop do
|
78
|
+
break if execute_workflow_iteration(task, task_handler, all_processed_steps, loop_iteration)
|
79
|
+
|
80
|
+
loop_iteration += 1
|
81
|
+
end
|
82
|
+
|
83
|
+
# Calculate total execution time
|
84
|
+
total_duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
85
|
+
|
86
|
+
log_performance_event('workflow_execution', total_duration,
|
87
|
+
task_id: task.task_id,
|
88
|
+
total_iterations: loop_iteration,
|
89
|
+
total_steps_processed: all_processed_steps.size,
|
90
|
+
operation: 'workflow_complete')
|
91
|
+
|
92
|
+
# DELEGATE: Finalize via TaskFinalizer (fires events internally)
|
93
|
+
finalize_task_with_logging(task, task_handler.get_sequence(task), all_processed_steps, task_handler)
|
94
|
+
end
|
95
|
+
|
96
|
+
# Execute a single workflow iteration
|
97
|
+
#
|
98
|
+
# @param task [Tasker::Task] The task being processed
|
99
|
+
# @param task_handler [Object] The task handler instance
|
100
|
+
# @param all_processed_steps [Array] Accumulator for processed steps
|
101
|
+
# @param iteration [Integer] Current iteration number
|
102
|
+
# @return [Boolean] True if workflow should exit, false to continue
|
103
|
+
def execute_workflow_iteration(task, task_handler, all_processed_steps, iteration)
|
104
|
+
task.reload
|
105
|
+
sequence = task_handler.get_sequence(task)
|
106
|
+
|
107
|
+
log_orchestration_event('workflow_iteration', :started,
|
108
|
+
task_id: task.task_id,
|
109
|
+
iteration: iteration,
|
110
|
+
current_status: task.status)
|
111
|
+
|
112
|
+
# Find viable steps with performance monitoring
|
113
|
+
viable_steps = find_viable_steps_with_monitoring(task, sequence, task_handler)
|
114
|
+
|
115
|
+
if viable_steps.empty?
|
116
|
+
log_orchestration_event('workflow_iteration', :completed,
|
117
|
+
task_id: task.task_id,
|
118
|
+
iteration: iteration,
|
119
|
+
result: 'no_viable_steps',
|
120
|
+
total_processed: all_processed_steps.size)
|
121
|
+
return true # Exit loop
|
122
|
+
end
|
123
|
+
|
124
|
+
# Execute viable steps with monitoring
|
125
|
+
processed_steps = handle_viable_steps_with_monitoring(task, sequence, viable_steps, task_handler)
|
126
|
+
all_processed_steps.concat(processed_steps)
|
127
|
+
|
128
|
+
# Check if blocked by errors
|
129
|
+
if blocked_by_errors_with_monitoring?(task, sequence, processed_steps, task_handler)
|
130
|
+
log_orchestration_event('workflow_iteration', :completed,
|
131
|
+
task_id: task.task_id,
|
132
|
+
iteration: iteration,
|
133
|
+
result: 'blocked_by_errors',
|
134
|
+
total_processed: all_processed_steps.size)
|
135
|
+
return true # Exit loop
|
136
|
+
end
|
137
|
+
|
138
|
+
log_orchestration_event('workflow_iteration', :completed,
|
139
|
+
task_id: task.task_id,
|
140
|
+
iteration: iteration,
|
141
|
+
result: 'continue',
|
142
|
+
steps_processed: processed_steps.size,
|
143
|
+
total_processed: all_processed_steps.size)
|
144
|
+
|
145
|
+
false # Continue loop
|
146
|
+
end
|
147
|
+
|
148
|
+
# Get default reenqueuer strategy for production use
|
149
|
+
#
|
150
|
+
# @return [Tasker::Orchestration::TaskReenqueuer] Production reenqueuer
|
151
|
+
def default_reenqueuer_strategy
|
152
|
+
Tasker::Orchestration::TaskReenqueuer.new
|
153
|
+
end
|
154
|
+
|
155
|
+
# Find steps that are ready for execution with performance monitoring
|
156
|
+
#
|
157
|
+
# @param task [Tasker::Task] The task being processed
|
158
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
159
|
+
# @param task_handler [Object] The task handler for delegation
|
160
|
+
# @return [Array<Tasker::WorkflowStep>] Steps ready for execution
|
161
|
+
def find_viable_steps_with_monitoring(task, sequence, _task_handler)
|
162
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
163
|
+
|
164
|
+
# Delegate to the existing orchestration component
|
165
|
+
viable_steps = Orchestration::ViableStepDiscovery.new.find_viable_steps(task, sequence)
|
166
|
+
|
167
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
168
|
+
|
169
|
+
log_performance_event('viable_step_discovery', duration,
|
170
|
+
task_id: task.task_id,
|
171
|
+
step_count: viable_steps.size,
|
172
|
+
sequence_length: sequence.steps.size)
|
173
|
+
|
174
|
+
if viable_steps.any?
|
175
|
+
publish_viable_steps_discovered(task.task_id, viable_steps.map(&:workflow_step_id))
|
176
|
+
else
|
177
|
+
publish_no_viable_steps(task.task_id, reason: 'No steps ready for execution')
|
178
|
+
end
|
179
|
+
|
180
|
+
viable_steps
|
181
|
+
end
|
182
|
+
|
183
|
+
# Handle execution of viable steps with monitoring
|
184
|
+
#
|
185
|
+
# @param task [Tasker::Task] The task being processed
|
186
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
187
|
+
# @param viable_steps [Array<Tasker::WorkflowStep>] Steps ready for execution
|
188
|
+
# @param task_handler [Object] The task handler for delegation
|
189
|
+
# @return [Array<Tasker::WorkflowStep>] Processed steps
|
190
|
+
def handle_viable_steps_with_monitoring(task, sequence, viable_steps, task_handler)
|
191
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
192
|
+
|
193
|
+
log_orchestration_event('step_batch_execution', :started,
|
194
|
+
task_id: task.task_id,
|
195
|
+
step_count: viable_steps.size,
|
196
|
+
step_names: viable_steps.map(&:name))
|
197
|
+
|
198
|
+
# Delegate to task handler's step executor
|
199
|
+
processed_steps = task_handler.send(:step_executor).execute_steps(task, sequence, viable_steps, task_handler)
|
200
|
+
|
201
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
202
|
+
successful_count = processed_steps.count { |s| s&.status == Tasker::Constants::WorkflowStepStatuses::COMPLETE }
|
203
|
+
|
204
|
+
log_performance_event('step_batch_execution', duration,
|
205
|
+
task_id: task.task_id,
|
206
|
+
step_count: viable_steps.size,
|
207
|
+
processed_count: processed_steps.size,
|
208
|
+
successful_count: successful_count,
|
209
|
+
failure_count: processed_steps.size - successful_count)
|
210
|
+
|
211
|
+
log_orchestration_event('step_batch_execution', :completed,
|
212
|
+
task_id: task.task_id,
|
213
|
+
processed_count: processed_steps.size,
|
214
|
+
successful_count: successful_count,
|
215
|
+
duration_ms: (duration * 1000).round(2))
|
216
|
+
|
217
|
+
processed_steps
|
218
|
+
end
|
219
|
+
|
220
|
+
# Check if task is blocked by errors with monitoring
|
221
|
+
#
|
222
|
+
# @param task [Tasker::Task] The task to check
|
223
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
224
|
+
# @param processed_steps [Array<Tasker::WorkflowStep>] Recently processed steps
|
225
|
+
# @param task_handler [Object] The task handler for delegation
|
226
|
+
# @return [Boolean] True if blocked by errors
|
227
|
+
def blocked_by_errors_with_monitoring?(task, sequence, processed_steps, task_handler)
|
228
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
229
|
+
|
230
|
+
# Delegate to task handler's task finalizer
|
231
|
+
is_blocked = task_handler.send(:task_finalizer).blocked_by_errors?(task, sequence, processed_steps)
|
232
|
+
|
233
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
234
|
+
|
235
|
+
log_performance_event('error_blocking_check', duration,
|
236
|
+
task_id: task.task_id,
|
237
|
+
is_blocked: is_blocked,
|
238
|
+
processed_steps_count: processed_steps.size)
|
239
|
+
|
240
|
+
if is_blocked
|
241
|
+
log_orchestration_event('workflow_blocking', :detected,
|
242
|
+
task_id: task.task_id,
|
243
|
+
reason: 'blocked_by_errors',
|
244
|
+
failed_steps: processed_steps.select do |s|
|
245
|
+
s&.status == Tasker::Constants::WorkflowStepStatuses::ERROR
|
246
|
+
end.map(&:name))
|
247
|
+
end
|
248
|
+
|
249
|
+
is_blocked
|
250
|
+
end
|
251
|
+
|
252
|
+
# Finalize the task with structured logging
|
253
|
+
#
|
254
|
+
# @param task [Tasker::Task] The task to finalize
|
255
|
+
# @param sequence [Tasker::Types::StepSequence] The final step sequence
|
256
|
+
# @param processed_steps [Array<Tasker::WorkflowStep>] All processed steps
|
257
|
+
# @param task_handler [Object] The task handler for delegation
|
258
|
+
def finalize_task_with_logging(task, sequence, processed_steps, task_handler)
|
259
|
+
start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
260
|
+
|
261
|
+
log_orchestration_event('task_finalization', :started,
|
262
|
+
task_id: task.task_id,
|
263
|
+
processed_steps_count: processed_steps.size)
|
264
|
+
|
265
|
+
# Publish finalization started event
|
266
|
+
publish_task_finalization_started(task, processed_steps_count: processed_steps.size)
|
267
|
+
|
268
|
+
# Call update_annotations hook before finalizing
|
269
|
+
if task_handler.respond_to?(:update_annotations)
|
270
|
+
task_handler.update_annotations(task, sequence, processed_steps)
|
271
|
+
end
|
272
|
+
|
273
|
+
# Delegate to task handler's task finalizer
|
274
|
+
task_handler.send(:task_finalizer).finalize_task_with_steps(task, sequence, processed_steps)
|
275
|
+
|
276
|
+
duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start_time
|
277
|
+
task.reload # Get final status
|
278
|
+
|
279
|
+
log_performance_event('task_finalization', duration,
|
280
|
+
task_id: task.task_id,
|
281
|
+
final_status: task.status,
|
282
|
+
processed_steps_count: processed_steps.size)
|
283
|
+
|
284
|
+
# Publish finalization completed event
|
285
|
+
publish_task_finalization_completed(task, processed_steps_count: processed_steps.size)
|
286
|
+
|
287
|
+
log_orchestration_event('task_finalization', :completed,
|
288
|
+
task_id: task.task_id,
|
289
|
+
final_status: task.status,
|
290
|
+
duration_ms: (duration * 1000).round(2))
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Tasker::Orchestration namespace for event-driven workflow orchestration
|
4
|
+
#
|
5
|
+
# This module provides a declarative, event-driven alternative to the imperative
|
6
|
+
# TaskHandler workflow loop. It coordinates workflow execution through state machine
|
7
|
+
# events and publisher/subscriber patterns.
|
8
|
+
#
|
9
|
+
# Components:
|
10
|
+
# - Events::Publisher: Unified event publisher for all workflow events (singleton)
|
11
|
+
# - ViableStepDiscovery: Discovers which steps can be executed based on workflow state
|
12
|
+
# - StepExecutor: Handles the execution of workflow steps via state machine transitions
|
13
|
+
# - TaskFinalizer: Handles task completion and finalization logic
|
14
|
+
# - Coordinator: Manages the setup and initialization of the event-driven workflow system
|
15
|
+
#
|
16
|
+
# Usage:
|
17
|
+
# # Initialize the workflow orchestration system (do this once at startup)
|
18
|
+
# Tasker::Orchestration::Coordinator.initialize!
|
19
|
+
#
|
20
|
+
# # Access the unified event publisher
|
21
|
+
# publisher = Tasker::Events::Publisher.instance
|
22
|
+
#
|
23
|
+
# Benefits:
|
24
|
+
# - Declarative: Steps declare what events they respond to
|
25
|
+
# - Testable: Each component can be tested in isolation
|
26
|
+
# - Extensible: Easy to add new behaviors via event subscribers
|
27
|
+
# - Observable: Rich event stream for debugging and monitoring
|
28
|
+
# - Concurrent-Safe: State machines handle race conditions
|
29
|
+
# - Audit Trail: Complete history of all state transitions
|
30
|
+
|
31
|
+
# Explicitly require orchestration components for predictable loading
|
32
|
+
require_relative 'orchestration/viable_step_discovery'
|
33
|
+
require_relative 'orchestration/step_executor'
|
34
|
+
require_relative 'orchestration/task_finalizer'
|
35
|
+
require_relative 'orchestration/task_initializer'
|
36
|
+
require_relative 'orchestration/task_reenqueuer'
|
37
|
+
require_relative 'orchestration/step_sequence_factory'
|
38
|
+
require_relative 'orchestration/coordinator'
|
39
|
+
|
40
|
+
module Tasker
|
41
|
+
module Orchestration
|
42
|
+
# All orchestration components are now explicitly loaded above
|
43
|
+
# This provides predictable loading order and avoids autoload complexity
|
44
|
+
end
|
45
|
+
end
|