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,716 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../events/event_payload_builder'
|
4
|
+
require_relative '../events/custom_registry'
|
5
|
+
require_relative 'structured_logging'
|
6
|
+
|
7
|
+
module Tasker
|
8
|
+
module Concerns
|
9
|
+
# EventPublisher provides a clean interface for publishing events
|
10
|
+
#
|
11
|
+
# This concern provides domain-specific event publishing methods that automatically
|
12
|
+
# build standardized payloads and resolve event constants. The API is designed for
|
13
|
+
# maximum clarity and minimum cognitive overhead.
|
14
|
+
#
|
15
|
+
# Enhanced with structured logging integration for production observability.
|
16
|
+
#
|
17
|
+
# Usage:
|
18
|
+
# include Tasker::Concerns::EventPublisher
|
19
|
+
#
|
20
|
+
# # Step events - method name determines event type automatically
|
21
|
+
# publish_step_completed(step, operation_count: 42)
|
22
|
+
# publish_step_failed(step, error: exception)
|
23
|
+
# publish_step_started(step)
|
24
|
+
#
|
25
|
+
# # Task events - clean and obvious
|
26
|
+
# publish_task_started(task)
|
27
|
+
# publish_task_completed(task, total_duration: 120.5)
|
28
|
+
# publish_task_failed(task, error_message: "Payment failed")
|
29
|
+
module EventPublisher
|
30
|
+
extend ActiveSupport::Concern
|
31
|
+
|
32
|
+
included do
|
33
|
+
# Include structured logging for event publishing observability
|
34
|
+
include Tasker::Concerns::StructuredLogging
|
35
|
+
end
|
36
|
+
|
37
|
+
# ========================================================================
|
38
|
+
# CLEAN STEP EVENT PUBLISHING - METHOD NAME = EVENT TYPE
|
39
|
+
# ========================================================================
|
40
|
+
|
41
|
+
# Publish step started event
|
42
|
+
# Automatically resolves to StepEvents::EXECUTION_REQUESTED with :started event type
|
43
|
+
#
|
44
|
+
# @param step [WorkflowStep] The step being started
|
45
|
+
# @param context [Hash] Additional context to merge into payload
|
46
|
+
# @return [void]
|
47
|
+
def publish_step_started(step, **context)
|
48
|
+
payload = build_step_payload(step, :started, context)
|
49
|
+
publish_event_with_logging(Tasker::Constants::StepEvents::EXECUTION_REQUESTED, payload) do
|
50
|
+
log_step_event(step, :started, **context.slice(:processing_mode, :concurrent_batch_size))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Publish step before handle event
|
55
|
+
# Automatically resolves to StepEvents::BEFORE_HANDLE with :before_handle event type
|
56
|
+
#
|
57
|
+
# @param step [WorkflowStep] The step about to be handled
|
58
|
+
# @param context [Hash] Additional context to merge into payload
|
59
|
+
# @return [void]
|
60
|
+
def publish_step_before_handle(step, **context)
|
61
|
+
payload = build_step_payload(step, :before_handle, context)
|
62
|
+
publish_event_with_logging(Tasker::Constants::StepEvents::BEFORE_HANDLE, payload) do
|
63
|
+
log_step_event(step, :before_handle, **context.slice(:handler_class, :dependencies_met))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Publish step completed event
|
68
|
+
# Automatically resolves to StepEvents::COMPLETED with :completed event type
|
69
|
+
#
|
70
|
+
# @param step [WorkflowStep] The step that completed
|
71
|
+
# @param context [Hash] Additional context to merge into payload
|
72
|
+
# @return [void]
|
73
|
+
def publish_step_completed(step, **context)
|
74
|
+
payload = build_step_payload(step, :completed, context)
|
75
|
+
publish_event_with_logging(Tasker::Constants::StepEvents::COMPLETED, payload) do
|
76
|
+
duration = context[:duration] || extract_duration_from_step(step)
|
77
|
+
log_step_event(step, :completed, duration: duration, **context.slice(:operation_count, :records_processed))
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# Publish step failed event
|
82
|
+
# Automatically resolves to StepEvents::FAILED with :failed event type
|
83
|
+
# Automatically extracts error information if :error is provided
|
84
|
+
#
|
85
|
+
# @param step [WorkflowStep] The step that failed
|
86
|
+
# @param error [Exception, nil] The exception that caused the failure
|
87
|
+
# @param context [Hash] Additional context to merge into payload
|
88
|
+
# @return [void]
|
89
|
+
def publish_step_failed(step, error: nil, **context)
|
90
|
+
# Automatically extract error information into context
|
91
|
+
if error
|
92
|
+
context = context.merge(
|
93
|
+
error_message: error.message,
|
94
|
+
error_class: error.class.name,
|
95
|
+
backtrace: error.backtrace&.first(10)
|
96
|
+
)
|
97
|
+
end
|
98
|
+
|
99
|
+
payload = build_step_payload(step, :failed, context)
|
100
|
+
publish_event_with_logging(Tasker::Constants::StepEvents::FAILED, payload) do
|
101
|
+
duration = context[:duration] || extract_duration_from_step(step)
|
102
|
+
log_step_event(step, :failed, duration: duration, error: error&.message)
|
103
|
+
log_exception(error, context: { step_id: step.workflow_step_id, task_id: step.task.task_id }) if error
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
# Publish step retry requested event
|
108
|
+
# Automatically resolves to StepEvents::RETRY_REQUESTED with :retry event type
|
109
|
+
#
|
110
|
+
# @param step [WorkflowStep] The step being retried
|
111
|
+
# @param retry_reason [String] The reason for the retry
|
112
|
+
# @param context [Hash] Additional context to merge into payload
|
113
|
+
# @return [void]
|
114
|
+
def publish_step_retry_requested(step, retry_reason: 'Step execution failed', **context)
|
115
|
+
context = context.merge(retry_reason: retry_reason)
|
116
|
+
payload = build_step_payload(step, :retry, context)
|
117
|
+
publish_event_with_logging(Tasker::Constants::StepEvents::RETRY_REQUESTED, payload) do
|
118
|
+
log_step_event(step, :retry_requested,
|
119
|
+
retry_reason: retry_reason,
|
120
|
+
attempt_count: step.attempts,
|
121
|
+
**context.slice(:backoff_seconds, :max_retries))
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# Publish step cancelled event
|
126
|
+
# Automatically resolves to StepEvents::CANCELLED with :cancelled event type
|
127
|
+
#
|
128
|
+
# @param step [WorkflowStep] The step being cancelled
|
129
|
+
# @param cancellation_reason [String] The reason for cancellation
|
130
|
+
# @param context [Hash] Additional context to merge into payload
|
131
|
+
# @return [void]
|
132
|
+
def publish_step_cancelled(step, cancellation_reason: 'Step cancelled', **context)
|
133
|
+
context = context.merge(cancellation_reason: cancellation_reason)
|
134
|
+
payload = build_step_payload(step, :cancelled, context)
|
135
|
+
publish_event_with_logging(Tasker::Constants::StepEvents::CANCELLED, payload) do
|
136
|
+
log_step_event(step, :cancelled, cancellation_reason: cancellation_reason)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# ========================================================================
|
141
|
+
# CLEAN TASK EVENT PUBLISHING - METHOD NAME = EVENT TYPE
|
142
|
+
# ========================================================================
|
143
|
+
|
144
|
+
# Publish task started event
|
145
|
+
# Automatically resolves to TaskEvents::START_REQUESTED with :started event type
|
146
|
+
#
|
147
|
+
# @param task [Task] The task being started
|
148
|
+
# @param context [Hash] Additional context to merge into payload
|
149
|
+
# @return [void]
|
150
|
+
def publish_task_started(task, **context)
|
151
|
+
payload = build_task_payload(task, :started, context)
|
152
|
+
publish_event_with_logging(Tasker::Constants::TaskEvents::START_REQUESTED, payload) do
|
153
|
+
log_task_event(task, :started, **context.slice(:execution_mode, :priority, :step_count))
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Publish task completed event
|
158
|
+
# Automatically resolves to TaskEvents::COMPLETED with :completed event type
|
159
|
+
#
|
160
|
+
# @param task [Task] The task that completed
|
161
|
+
# @param context [Hash] Additional context to merge into payload
|
162
|
+
# @return [void]
|
163
|
+
def publish_task_completed(task, **context)
|
164
|
+
payload = build_task_payload(task, :completed, context)
|
165
|
+
publish_event_with_logging(Tasker::Constants::TaskEvents::COMPLETED, payload) do
|
166
|
+
log_task_event(task, :completed, **context.slice(:total_duration, :completed_steps, :total_steps))
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
# Publish task failed event
|
171
|
+
# Automatically resolves to TaskEvents::FAILED with :failed event type
|
172
|
+
#
|
173
|
+
# @param task [Task] The task that failed
|
174
|
+
# @param error_message [String] The error message
|
175
|
+
# @param error_steps [Array] Array of failed step information
|
176
|
+
# @param context [Hash] Additional context to merge into payload
|
177
|
+
# @return [void]
|
178
|
+
def publish_task_failed(task, error_message: 'Task execution failed', error_steps: [], **context)
|
179
|
+
context = context.merge(
|
180
|
+
error_message: error_message,
|
181
|
+
error_steps: error_steps
|
182
|
+
)
|
183
|
+
|
184
|
+
payload = build_task_payload(task, :failed, context)
|
185
|
+
publish_event_with_logging(Tasker::Constants::TaskEvents::FAILED, payload) do
|
186
|
+
log_task_event(task, :failed,
|
187
|
+
error: error_message,
|
188
|
+
failed_step_count: error_steps.size,
|
189
|
+
**context.slice(:total_duration, :completed_steps))
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
# Publish task retry requested event
|
194
|
+
# Automatically resolves to TaskEvents::RETRY_REQUESTED with :retry event type
|
195
|
+
#
|
196
|
+
# @param task [Task] The task being retried
|
197
|
+
# @param retry_reason [String] The reason for the retry
|
198
|
+
# @param context [Hash] Additional context to merge into payload
|
199
|
+
# @return [void]
|
200
|
+
def publish_task_retry_requested(task, retry_reason: 'Task retry requested', **context)
|
201
|
+
context = context.merge(retry_reason: retry_reason)
|
202
|
+
payload = build_task_payload(task, :retry, context)
|
203
|
+
publish_event_with_logging(Tasker::Constants::TaskEvents::RETRY_REQUESTED, payload) do
|
204
|
+
log_task_event(task, :retry_requested, retry_reason: retry_reason)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# ========================================================================
|
209
|
+
# CLEAN WORKFLOW ORCHESTRATION EVENTS - SIMPLIFIED API
|
210
|
+
# ========================================================================
|
211
|
+
|
212
|
+
# Publish workflow task started event (orchestration layer)
|
213
|
+
# Automatically resolves to WorkflowEvents::TASK_STARTED
|
214
|
+
#
|
215
|
+
# @param task_id [String] The task ID
|
216
|
+
# @param context [Hash] Additional orchestration context
|
217
|
+
# @return [void]
|
218
|
+
def publish_workflow_task_started(task_id, **context)
|
219
|
+
context = context.merge(task_id: task_id)
|
220
|
+
payload = build_orchestration_payload(:task_started, context)
|
221
|
+
publish_event_with_logging(Tasker::Constants::WorkflowEvents::TASK_STARTED, payload) do
|
222
|
+
log_orchestration_event('workflow_task_started', :started, task_id: task_id, **context)
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
# Publish workflow step completed event (orchestration layer)
|
227
|
+
# Automatically resolves to WorkflowEvents::STEP_COMPLETED
|
228
|
+
#
|
229
|
+
# @param task_id [String] The task ID
|
230
|
+
# @param step_id [String] The step ID
|
231
|
+
# @param context [Hash] Additional orchestration context
|
232
|
+
# @return [void]
|
233
|
+
def publish_workflow_step_completed(task_id, step_id, **context)
|
234
|
+
context = context.merge(task_id: task_id, step_id: step_id)
|
235
|
+
payload = build_orchestration_payload(:step_completed, context)
|
236
|
+
publish_event_with_logging(Tasker::Constants::WorkflowEvents::STEP_COMPLETED, payload) do
|
237
|
+
log_orchestration_event('workflow_step_completed', :completed,
|
238
|
+
task_id: task_id, step_id: step_id, **context)
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
# Publish viable steps discovered event
|
243
|
+
# Automatically resolves to WorkflowEvents::VIABLE_STEPS_DISCOVERED
|
244
|
+
#
|
245
|
+
# @param task_id [String] The task ID
|
246
|
+
# @param step_ids [Array<String>] Array of step IDs that are viable
|
247
|
+
# @param processing_mode [String] The processing mode ('concurrent' or 'sequential')
|
248
|
+
# @param context [Hash] Additional orchestration context
|
249
|
+
# @return [void]
|
250
|
+
def publish_viable_steps_discovered(task_id, step_ids, processing_mode: 'concurrent', **context)
|
251
|
+
context = context.merge(
|
252
|
+
task_id: task_id,
|
253
|
+
step_ids: step_ids,
|
254
|
+
processing_mode: processing_mode,
|
255
|
+
step_count: step_ids.size
|
256
|
+
)
|
257
|
+
|
258
|
+
payload = build_orchestration_payload(:viable_steps_discovered, context)
|
259
|
+
publish_event_with_logging(Tasker::Constants::WorkflowEvents::VIABLE_STEPS_DISCOVERED, payload) do
|
260
|
+
log_orchestration_event('viable_steps_discovered', :discovered,
|
261
|
+
task_id: task_id, step_count: step_ids.size, processing_mode: processing_mode)
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Publish no viable steps event
|
266
|
+
# Automatically resolves to WorkflowEvents::NO_VIABLE_STEPS
|
267
|
+
#
|
268
|
+
# @param task_id [String] The task ID
|
269
|
+
# @param reason [String] The reason why no steps are viable
|
270
|
+
# @param context [Hash] Additional orchestration context
|
271
|
+
# @return [void]
|
272
|
+
def publish_no_viable_steps(task_id, reason: 'No steps ready for execution', **context)
|
273
|
+
context = context.merge(task_id: task_id, reason: reason)
|
274
|
+
payload = build_orchestration_payload(:no_viable_steps, context)
|
275
|
+
publish_event_with_logging(Tasker::Constants::WorkflowEvents::NO_VIABLE_STEPS, payload) do
|
276
|
+
log_orchestration_event('no_viable_steps', :detected, task_id: task_id, reason: reason)
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
# ========================================================================
|
281
|
+
# TASK FINALIZATION EVENTS WITH STRUCTURED LOGGING
|
282
|
+
# ========================================================================
|
283
|
+
|
284
|
+
# Publish task finalization started event
|
285
|
+
#
|
286
|
+
# @param task [Task] The task being finalized
|
287
|
+
# @param processed_steps_count [Integer] Number of steps processed
|
288
|
+
# @param context [Hash] Additional context
|
289
|
+
# @return [void]
|
290
|
+
def publish_task_finalization_started(task, processed_steps_count: 0, **context)
|
291
|
+
context = context.merge(
|
292
|
+
task_id: task.task_id,
|
293
|
+
processed_steps_count: processed_steps_count
|
294
|
+
)
|
295
|
+
|
296
|
+
payload = build_orchestration_payload(:task_finalization_started, context)
|
297
|
+
publish_event_with_logging(Tasker::Constants::WorkflowEvents::TASK_FINALIZATION_STARTED, payload) do
|
298
|
+
log_orchestration_event('task_finalization', :started,
|
299
|
+
task_id: task.task_id, processed_steps_count: processed_steps_count)
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
# Publish task finalization completed event
|
304
|
+
#
|
305
|
+
# @param task [Task] The task that was finalized
|
306
|
+
# @param processed_steps_count [Integer] Number of steps processed
|
307
|
+
# @param context [Hash] Additional context
|
308
|
+
# @return [void]
|
309
|
+
def publish_task_finalization_completed(task, processed_steps_count: 0, **context)
|
310
|
+
context = context.merge(
|
311
|
+
task_id: task.task_id,
|
312
|
+
processed_steps_count: processed_steps_count,
|
313
|
+
final_status: task.status
|
314
|
+
)
|
315
|
+
|
316
|
+
payload = build_orchestration_payload(:task_finalization_completed, context)
|
317
|
+
publish_event_with_logging(Tasker::Constants::WorkflowEvents::TASK_FINALIZATION_COMPLETED, payload) do
|
318
|
+
log_orchestration_event('task_finalization', :completed,
|
319
|
+
task_id: task.task_id,
|
320
|
+
final_status: task.status,
|
321
|
+
processed_steps_count: processed_steps_count)
|
322
|
+
end
|
323
|
+
end
|
324
|
+
|
325
|
+
# Publish task pending transition event (for synchronous processing)
|
326
|
+
# Automatically resolves to TaskEvents::INITIALIZE_REQUESTED with pending context
|
327
|
+
#
|
328
|
+
# @param task [Task] The task being set to pending
|
329
|
+
# @param reason [String] The reason for setting to pending
|
330
|
+
# @param context [Hash] Additional pending context
|
331
|
+
# @return [void]
|
332
|
+
def publish_task_pending_transition(task, reason: 'Task set to pending', **context)
|
333
|
+
context = context.merge(
|
334
|
+
task_id: task.task_id,
|
335
|
+
task_name: task.name,
|
336
|
+
reason: reason
|
337
|
+
)
|
338
|
+
|
339
|
+
payload = build_task_payload(task, :pending_transition, context)
|
340
|
+
publish_event(Tasker::Constants::TaskEvents::INITIALIZE_REQUESTED, payload)
|
341
|
+
end
|
342
|
+
|
343
|
+
# Publish workflow unclear state event (for monitoring/alerting)
|
344
|
+
# Automatically resolves to WorkflowEvents::TASK_STATE_UNCLEAR
|
345
|
+
#
|
346
|
+
# @param task [Task] The task in unclear state
|
347
|
+
# @param reason [String] The reason the state is unclear
|
348
|
+
# @param context [Hash] Additional unclear state context
|
349
|
+
# @return [void]
|
350
|
+
def publish_workflow_state_unclear(task, reason: 'Task in unclear state', **context)
|
351
|
+
context = context.merge(
|
352
|
+
task_id: task.task_id,
|
353
|
+
task_name: task.name,
|
354
|
+
reason: reason
|
355
|
+
)
|
356
|
+
|
357
|
+
payload = build_orchestration_payload(:task_state_unclear, context)
|
358
|
+
publish_event(Tasker::Constants::WorkflowEvents::TASK_STATE_UNCLEAR, payload)
|
359
|
+
end
|
360
|
+
|
361
|
+
# ========================================================================
|
362
|
+
# TASK REENQUEUE ORCHESTRATION EVENTS - NEW CLEAN HELPERS
|
363
|
+
# ========================================================================
|
364
|
+
|
365
|
+
# Publish task reenqueue started event
|
366
|
+
# Automatically resolves to WorkflowEvents::TASK_REENQUEUE_STARTED
|
367
|
+
#
|
368
|
+
# @param task [Task] The task being reenqueued
|
369
|
+
# @param reason [String] The reason for reenqueue
|
370
|
+
# @param context [Hash] Additional reenqueue context
|
371
|
+
# @return [void]
|
372
|
+
def publish_task_reenqueue_started(task, reason: 'Task reenqueue started', **context)
|
373
|
+
context = context.merge(
|
374
|
+
task_id: task.task_id,
|
375
|
+
task_name: task.name,
|
376
|
+
reason: reason,
|
377
|
+
current_status: task.status,
|
378
|
+
timestamp: Time.current
|
379
|
+
)
|
380
|
+
|
381
|
+
payload = build_orchestration_payload(:task_reenqueue_started, context)
|
382
|
+
publish_event(Tasker::Constants::WorkflowEvents::TASK_REENQUEUE_STARTED, payload)
|
383
|
+
end
|
384
|
+
|
385
|
+
# Publish task reenqueue requested event
|
386
|
+
# Automatically resolves to WorkflowEvents::TASK_REENQUEUE_REQUESTED
|
387
|
+
#
|
388
|
+
# @param task [Task] The task reenqueue was requested for
|
389
|
+
# @param reason [String] The reason for reenqueue
|
390
|
+
# @param context [Hash] Additional reenqueue context
|
391
|
+
# @return [void]
|
392
|
+
def publish_task_reenqueue_requested(task, reason: 'Task reenqueue requested', **context)
|
393
|
+
context = context.merge(
|
394
|
+
task_id: task.task_id,
|
395
|
+
task_name: task.name,
|
396
|
+
reason: reason,
|
397
|
+
timestamp: Time.current
|
398
|
+
)
|
399
|
+
|
400
|
+
payload = build_orchestration_payload(:task_reenqueue_requested, context)
|
401
|
+
publish_event(Tasker::Constants::WorkflowEvents::TASK_REENQUEUE_REQUESTED, payload)
|
402
|
+
end
|
403
|
+
|
404
|
+
# Publish task reenqueue failed event
|
405
|
+
# Automatically resolves to WorkflowEvents::TASK_REENQUEUE_FAILED
|
406
|
+
#
|
407
|
+
# @param task [Task] The task that failed to reenqueue
|
408
|
+
# @param reason [String] The reason for reenqueue attempt
|
409
|
+
# @param error [String] The error message
|
410
|
+
# @param context [Hash] Additional reenqueue context
|
411
|
+
# @return [void]
|
412
|
+
def publish_task_reenqueue_failed(task, reason: 'Task reenqueue failed', error: 'Unknown error', **context)
|
413
|
+
context = context.merge(
|
414
|
+
task_id: task.task_id,
|
415
|
+
task_name: task.name,
|
416
|
+
reason: reason,
|
417
|
+
error: error,
|
418
|
+
timestamp: Time.current
|
419
|
+
)
|
420
|
+
|
421
|
+
payload = build_orchestration_payload(:task_reenqueue_failed, context)
|
422
|
+
publish_event(Tasker::Constants::WorkflowEvents::TASK_REENQUEUE_FAILED, payload)
|
423
|
+
end
|
424
|
+
|
425
|
+
# Publish task reenqueue delayed event
|
426
|
+
# Automatically resolves to WorkflowEvents::TASK_REENQUEUE_DELAYED
|
427
|
+
#
|
428
|
+
# @param task [Task] The task being delayed for reenqueue
|
429
|
+
# @param delay_seconds [Integer] Number of seconds to delay
|
430
|
+
# @param reason [String] The reason for delayed reenqueue
|
431
|
+
# @param context [Hash] Additional reenqueue context
|
432
|
+
# @return [void]
|
433
|
+
def publish_task_reenqueue_delayed(task, delay_seconds:, reason: 'Task reenqueue delayed', **context)
|
434
|
+
context = context.merge(
|
435
|
+
task_id: task.task_id,
|
436
|
+
task_name: task.name,
|
437
|
+
reason: reason,
|
438
|
+
delay_seconds: delay_seconds,
|
439
|
+
scheduled_for: Time.current + delay_seconds.seconds,
|
440
|
+
timestamp: Time.current
|
441
|
+
)
|
442
|
+
|
443
|
+
payload = build_orchestration_payload(:task_reenqueue_delayed, context)
|
444
|
+
publish_event(Tasker::Constants::WorkflowEvents::TASK_REENQUEUE_DELAYED, payload)
|
445
|
+
end
|
446
|
+
|
447
|
+
# ========================================================================
|
448
|
+
# STEPS EXECUTION ORCHESTRATION EVENTS - NEW CLEAN HELPERS
|
449
|
+
# ========================================================================
|
450
|
+
|
451
|
+
# Publish steps execution started event (batch processing)
|
452
|
+
# Automatically resolves to WorkflowEvents::STEPS_EXECUTION_STARTED
|
453
|
+
#
|
454
|
+
# @param task [Task] The task whose steps are being executed
|
455
|
+
# @param step_count [Integer] Number of steps being executed
|
456
|
+
# @param processing_mode [String] The processing mode (concurrent/sequential)
|
457
|
+
# @param context [Hash] Additional execution context
|
458
|
+
# @return [void]
|
459
|
+
def publish_steps_execution_started(task, step_count:, processing_mode: 'concurrent', **context)
|
460
|
+
context = context.merge(
|
461
|
+
task_id: task.task_id,
|
462
|
+
task_name: task.name,
|
463
|
+
step_count: step_count,
|
464
|
+
processing_mode: processing_mode
|
465
|
+
)
|
466
|
+
|
467
|
+
payload = build_orchestration_payload(:steps_execution_started, context)
|
468
|
+
publish_event(Tasker::Constants::WorkflowEvents::STEPS_EXECUTION_STARTED, payload)
|
469
|
+
end
|
470
|
+
|
471
|
+
# Publish steps execution completed event (batch processing)
|
472
|
+
# Automatically resolves to WorkflowEvents::STEPS_EXECUTION_COMPLETED
|
473
|
+
#
|
474
|
+
# @param task [Task] The task whose steps were executed
|
475
|
+
# @param processed_count [Integer] Number of steps processed
|
476
|
+
# @param successful_count [Integer] Number of steps that succeeded
|
477
|
+
# @param context [Hash] Additional execution context
|
478
|
+
# @return [void]
|
479
|
+
def publish_steps_execution_completed(task, processed_count:, successful_count:, **context)
|
480
|
+
context = context.merge(
|
481
|
+
task_id: task.task_id,
|
482
|
+
task_name: task.name,
|
483
|
+
processed_count: processed_count,
|
484
|
+
successful_count: successful_count
|
485
|
+
)
|
486
|
+
|
487
|
+
payload = build_orchestration_payload(:steps_execution_completed, context)
|
488
|
+
publish_event_with_logging(Tasker::Constants::WorkflowEvents::STEPS_EXECUTION_COMPLETED, payload) do
|
489
|
+
log_orchestration_event('steps_execution_completed', :completed,
|
490
|
+
task_id: task.task_id,
|
491
|
+
processed_count: processed_count,
|
492
|
+
successful_count: successful_count,
|
493
|
+
failure_count: processed_count - successful_count)
|
494
|
+
end
|
495
|
+
end
|
496
|
+
|
497
|
+
# ========================================================================
|
498
|
+
# STEP OBSERVABILITY EVENTS - NEW CLEAN HELPERS
|
499
|
+
# ========================================================================
|
500
|
+
|
501
|
+
# Publish step backoff event (for retry/rate limiting scenarios)
|
502
|
+
# Automatically resolves to ObservabilityEvents::Step::BACKOFF
|
503
|
+
#
|
504
|
+
# @param step [WorkflowStep] The step being backed off
|
505
|
+
# @param backoff_seconds [Float] Number of seconds to wait
|
506
|
+
# @param backoff_type [String] Type of backoff (server_requested/exponential)
|
507
|
+
# @param context [Hash] Additional backoff context
|
508
|
+
# @return [void]
|
509
|
+
def publish_step_backoff(step, backoff_seconds:, backoff_type: 'exponential', **context)
|
510
|
+
context = context.merge(
|
511
|
+
step_id: step.workflow_step_id,
|
512
|
+
step_name: step.name,
|
513
|
+
backoff_seconds: backoff_seconds,
|
514
|
+
backoff_type: backoff_type
|
515
|
+
)
|
516
|
+
|
517
|
+
payload = build_step_payload(step, :backoff, context)
|
518
|
+
publish_event_with_logging(Tasker::Constants::ObservabilityEvents::Step::BACKOFF, payload) do
|
519
|
+
log_step_event(step, :backoff,
|
520
|
+
backoff_seconds: backoff_seconds,
|
521
|
+
backoff_type: backoff_type,
|
522
|
+
**context.slice(:retry_attempt, :max_retries))
|
523
|
+
end
|
524
|
+
end
|
525
|
+
|
526
|
+
# ========================================================================
|
527
|
+
# TASK OBSERVABILITY EVENTS - NEW CLEAN HELPERS
|
528
|
+
# ========================================================================
|
529
|
+
|
530
|
+
# Publish task enqueue event (for job scheduling observability)
|
531
|
+
# Automatically resolves to ObservabilityEvents::Task::ENQUEUE
|
532
|
+
#
|
533
|
+
# @param task [Task] The task being enqueued
|
534
|
+
# @param context [Hash] Additional enqueue context
|
535
|
+
# @return [void]
|
536
|
+
def publish_task_enqueue(task, **context)
|
537
|
+
context = context.merge(
|
538
|
+
task_id: task.task_id,
|
539
|
+
task_name: task.name,
|
540
|
+
task_context: task.context
|
541
|
+
)
|
542
|
+
|
543
|
+
payload = build_task_payload(task, :enqueue, context)
|
544
|
+
publish_event_with_logging(Tasker::Constants::ObservabilityEvents::Task::ENQUEUE, payload) do
|
545
|
+
log_task_event(task, :enqueued, **context.slice(:queue_name, :job_class, :priority))
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
# ========================================================================
|
550
|
+
# CUSTOM EVENT PUBLISHING - DEVELOPER-FACING API
|
551
|
+
# ========================================================================
|
552
|
+
|
553
|
+
# Publish a custom event with standard metadata
|
554
|
+
# Assumes the event is already registered
|
555
|
+
#
|
556
|
+
# @param event_name [String] Event name
|
557
|
+
# @param payload [Hash] Event payload
|
558
|
+
# @return [void]
|
559
|
+
def publish_custom_event(event_name, payload = {})
|
560
|
+
# Add standard metadata
|
561
|
+
enhanced_payload = payload.merge(
|
562
|
+
event_type: 'custom',
|
563
|
+
timestamp: Time.current
|
564
|
+
)
|
565
|
+
|
566
|
+
publish_event_with_logging(event_name, enhanced_payload) do
|
567
|
+
log_structured(:info, 'Custom event published',
|
568
|
+
event_name: event_name,
|
569
|
+
event_type: 'custom',
|
570
|
+
**payload.slice(:task_id, :step_id, :operation, :context))
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
# ========================================================================
|
575
|
+
# CONTEXT-AWARE EVENT PUBLISHING (Advanced - for special cases)
|
576
|
+
# ========================================================================
|
577
|
+
|
578
|
+
# Automatically determine and publish the appropriate step event based on step state
|
579
|
+
# This method uses the step's current state to infer the most appropriate event type
|
580
|
+
#
|
581
|
+
# @param step [WorkflowStep] The step object
|
582
|
+
# @param context_hint [Symbol, nil] Optional hint about the context
|
583
|
+
# @param context [Hash] Additional context to merge into payload
|
584
|
+
# @return [void]
|
585
|
+
def publish_step_event_for_context(step, context_hint: nil, **context)
|
586
|
+
event_type = context_hint || infer_step_event_type_from_state(step)
|
587
|
+
|
588
|
+
case event_type
|
589
|
+
when :started, :execution_requested
|
590
|
+
publish_step_started(step, **context)
|
591
|
+
when :completed, :success
|
592
|
+
publish_step_completed(step, **context)
|
593
|
+
when :failed, :failure, :error
|
594
|
+
publish_step_failed(step, **context)
|
595
|
+
when :retry, :retry_requested
|
596
|
+
publish_step_retry_requested(step, **context)
|
597
|
+
when :cancelled
|
598
|
+
publish_step_cancelled(step, **context)
|
599
|
+
else
|
600
|
+
Rails.logger.warn("Unknown step event context: #{event_type} for step #{step.workflow_step_id}")
|
601
|
+
end
|
602
|
+
end
|
603
|
+
|
604
|
+
# Infer step event type from step state and context
|
605
|
+
#
|
606
|
+
# @param step [WorkflowStep] The step object
|
607
|
+
# @return [Symbol] The inferred event type
|
608
|
+
def infer_step_event_type_from_state(step)
|
609
|
+
case step.status
|
610
|
+
when Tasker::Constants::WorkflowStepStatuses::IN_PROGRESS
|
611
|
+
:started
|
612
|
+
when Tasker::Constants::WorkflowStepStatuses::COMPLETE
|
613
|
+
:completed
|
614
|
+
when Tasker::Constants::WorkflowStepStatuses::ERROR
|
615
|
+
:failed
|
616
|
+
when Tasker::Constants::WorkflowStepStatuses::CANCELLED
|
617
|
+
:cancelled
|
618
|
+
else
|
619
|
+
:started # Default fallback
|
620
|
+
end
|
621
|
+
end
|
622
|
+
|
623
|
+
private
|
624
|
+
|
625
|
+
# Core publish method with structured logging integration
|
626
|
+
#
|
627
|
+
# @param event_constant [String] The event constant
|
628
|
+
# @param payload [Hash] The event payload
|
629
|
+
# @param block [Proc] Optional block for structured logging
|
630
|
+
# @return [void]
|
631
|
+
def publish_event_with_logging(event_constant, payload = {})
|
632
|
+
# Add timestamp if not present
|
633
|
+
payload[:timestamp] ||= Time.current
|
634
|
+
|
635
|
+
# Execute structured logging if block provided
|
636
|
+
if block_given?
|
637
|
+
begin
|
638
|
+
yield
|
639
|
+
rescue StandardError => e
|
640
|
+
Rails.logger.debug { "EventPublisher: Structured logging failed for #{event_constant}: #{e.message}" }
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
# Publish through the unified publisher
|
645
|
+
Tasker::Events::Publisher.instance.publish(event_constant, payload)
|
646
|
+
rescue StandardError => e
|
647
|
+
# Trap publishing errors so they don't break core system flow
|
648
|
+
Rails.logger.error { "Error publishing event #{event_constant}: #{e.message}" }
|
649
|
+
end
|
650
|
+
|
651
|
+
# Core publish method - used internally by domain-specific methods
|
652
|
+
#
|
653
|
+
# @param event_constant [String] The event constant
|
654
|
+
# @param payload [Hash] The event payload
|
655
|
+
# @return [void]
|
656
|
+
def publish_event(event_constant, payload = {})
|
657
|
+
publish_event_with_logging(event_constant, payload)
|
658
|
+
end
|
659
|
+
|
660
|
+
# Extract duration from step timing information
|
661
|
+
#
|
662
|
+
# @param step [WorkflowStep] The step to extract duration from
|
663
|
+
# @return [Float, nil] Duration in seconds or nil if not available
|
664
|
+
def extract_duration_from_step(step)
|
665
|
+
return nil unless step.updated_at && step.created_at
|
666
|
+
|
667
|
+
# Simple duration calculation - can be enhanced with more precise timing
|
668
|
+
(step.updated_at - step.created_at).to_f
|
669
|
+
end
|
670
|
+
|
671
|
+
# Build standardized step payload automatically
|
672
|
+
# Method name determines event type, no redundant parameters needed
|
673
|
+
#
|
674
|
+
# @param step [WorkflowStep] The step object
|
675
|
+
# @param event_type [Symbol] The event type (inferred from calling method)
|
676
|
+
# @param context [Hash] Additional context to merge
|
677
|
+
# @return [Hash] Standardized event payload
|
678
|
+
def build_step_payload(step, event_type, context = {})
|
679
|
+
Tasker::Events::EventPayloadBuilder.build_step_payload(
|
680
|
+
step,
|
681
|
+
step.task,
|
682
|
+
event_type: event_type,
|
683
|
+
additional_context: context
|
684
|
+
)
|
685
|
+
end
|
686
|
+
|
687
|
+
# Build standardized task payload automatically
|
688
|
+
# Method name determines event type, no redundant parameters needed
|
689
|
+
#
|
690
|
+
# @param task [Task] The task object
|
691
|
+
# @param event_type [Symbol] The event type (inferred from calling method)
|
692
|
+
# @param context [Hash] Additional context to merge
|
693
|
+
# @return [Hash] Standardized event payload
|
694
|
+
def build_task_payload(task, event_type, context = {})
|
695
|
+
Tasker::Events::EventPayloadBuilder.build_task_payload(
|
696
|
+
task,
|
697
|
+
event_type: event_type,
|
698
|
+
additional_context: context
|
699
|
+
)
|
700
|
+
end
|
701
|
+
|
702
|
+
# Build standardized orchestration payload automatically
|
703
|
+
# Method name determines event type, no redundant parameters needed
|
704
|
+
#
|
705
|
+
# @param event_type [Symbol] The orchestration event type
|
706
|
+
# @param context [Hash] The orchestration context
|
707
|
+
# @return [Hash] Standardized orchestration payload
|
708
|
+
def build_orchestration_payload(event_type, context = {})
|
709
|
+
Tasker::Events::EventPayloadBuilder.build_orchestration_payload(
|
710
|
+
event_type: event_type,
|
711
|
+
context: context
|
712
|
+
)
|
713
|
+
end
|
714
|
+
end
|
715
|
+
end
|
716
|
+
end
|