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,199 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Tasker
|
6
|
+
module Events
|
7
|
+
# DefinitionLoader handles loading event metadata and state machine mappings from YAML files
|
8
|
+
#
|
9
|
+
# This class provides a clean loader for event metadata (descriptions, schemas, etc.)
|
10
|
+
# and state machine transition mappings. The actual event constants are defined
|
11
|
+
# in constants.rb as the single source of truth.
|
12
|
+
#
|
13
|
+
# Features:
|
14
|
+
# - Event metadata loading for runtime introspection
|
15
|
+
# - State machine transition mappings for declarative configuration
|
16
|
+
# - Support for custom application events and mappings
|
17
|
+
# - Hot reloading in development environments
|
18
|
+
class DefinitionLoader
|
19
|
+
include Singleton
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Load all event metadata for introspection
|
23
|
+
#
|
24
|
+
# @return [Hash] Event metadata keyed by constant reference
|
25
|
+
def load_event_metadata
|
26
|
+
metadata = {}
|
27
|
+
|
28
|
+
# Load system event metadata first
|
29
|
+
system_metadata = load_system_event_metadata
|
30
|
+
metadata.merge!(system_metadata)
|
31
|
+
|
32
|
+
# Load custom event metadata from applications
|
33
|
+
custom_metadata = load_custom_event_metadata
|
34
|
+
metadata.merge!(custom_metadata)
|
35
|
+
|
36
|
+
metadata
|
37
|
+
end
|
38
|
+
|
39
|
+
# Load state machine mappings from YAML
|
40
|
+
#
|
41
|
+
# @return [Hash] State machine mappings with task and step transitions
|
42
|
+
def load_state_machine_mappings
|
43
|
+
yaml_file = File.join(tasker_config_path, 'system_events.yml')
|
44
|
+
|
45
|
+
if File.exist?(yaml_file)
|
46
|
+
yaml_data = YAML.load_file(yaml_file)
|
47
|
+
yaml_data['state_machine_mappings'] || {}
|
48
|
+
else
|
49
|
+
Rails.logger.warn('Tasker: system_events.yml not found')
|
50
|
+
{}
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# Get event metadata for a specific constant
|
55
|
+
#
|
56
|
+
# @param constant_ref [String] The constant reference or actual constant value
|
57
|
+
# @return [Hash, nil] Event metadata or nil if not found
|
58
|
+
def find_event_metadata(constant_ref)
|
59
|
+
metadata = load_event_metadata
|
60
|
+
|
61
|
+
# Try direct lookup first
|
62
|
+
return metadata[constant_ref] if metadata[constant_ref]
|
63
|
+
|
64
|
+
# Try reverse lookup by constant value
|
65
|
+
metadata.find { |_key, data| data['constant_ref'] == constant_ref }&.last
|
66
|
+
end
|
67
|
+
|
68
|
+
# Get all events grouped by category for introspection
|
69
|
+
#
|
70
|
+
# @return [Hash] Events grouped by category (task, step, workflow, etc.)
|
71
|
+
def events_by_category
|
72
|
+
metadata = load_event_metadata
|
73
|
+
grouped = Hash.new { |h, k| h[k] = {} }
|
74
|
+
|
75
|
+
metadata.each do |event_key, event_data|
|
76
|
+
category = extract_category_from_key(event_key)
|
77
|
+
grouped[category][event_key] = event_data
|
78
|
+
end
|
79
|
+
|
80
|
+
grouped
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# Load system event metadata from Tasker gem
|
86
|
+
#
|
87
|
+
# @return [Hash] System event metadata
|
88
|
+
def load_system_event_metadata
|
89
|
+
system_file = File.join(tasker_config_path, 'system_events.yml')
|
90
|
+
|
91
|
+
if File.exist?(system_file)
|
92
|
+
load_metadata_from_file(system_file)
|
93
|
+
else
|
94
|
+
Rails.logger.warn("Tasker: System events file not found at #{system_file}")
|
95
|
+
{}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Load custom event metadata from application configuration
|
100
|
+
#
|
101
|
+
# @return [Hash] Custom event metadata
|
102
|
+
def load_custom_event_metadata
|
103
|
+
metadata = {}
|
104
|
+
|
105
|
+
# Load custom events from configured directories if they exist
|
106
|
+
Tasker.configuration.engine.custom_events_directories.each do |directory_path|
|
107
|
+
absolute_path = File.expand_path(directory_path, Rails.root)
|
108
|
+
|
109
|
+
if File.directory?(absolute_path)
|
110
|
+
load_metadata_from_directory(absolute_path, metadata)
|
111
|
+
elsif File.exist?(absolute_path) && absolute_path.end_with?('.yml', '.yaml')
|
112
|
+
file_metadata = load_metadata_from_file(absolute_path)
|
113
|
+
metadata.merge!(file_metadata)
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
metadata
|
118
|
+
end
|
119
|
+
|
120
|
+
# Load metadata from a single YAML file
|
121
|
+
#
|
122
|
+
# @param file_path [String] Path to the YAML file
|
123
|
+
# @return [Hash] Event metadata from the file
|
124
|
+
def load_metadata_from_file(file_path)
|
125
|
+
Rails.logger.debug { "Tasker: Loading event metadata from #{file_path}" }
|
126
|
+
|
127
|
+
begin
|
128
|
+
yaml_data = YAML.load_file(file_path)
|
129
|
+
return {} if yaml_data.blank?
|
130
|
+
|
131
|
+
# Extract event metadata section
|
132
|
+
event_metadata = yaml_data['event_metadata'] || {}
|
133
|
+
transform_metadata_structure(event_metadata, file_path)
|
134
|
+
rescue StandardError => e
|
135
|
+
Rails.logger.error("Tasker: Failed to load event metadata from #{file_path}: #{e.message}")
|
136
|
+
{}
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
# Transform nested YAML metadata structure to flat lookup
|
141
|
+
#
|
142
|
+
# @param metadata [Hash] Nested metadata structure from YAML
|
143
|
+
# @param source_file [String] Source file for metadata attribution
|
144
|
+
# @return [Hash] Flattened metadata hash
|
145
|
+
def transform_metadata_structure(metadata, source_file)
|
146
|
+
flattened = {}
|
147
|
+
|
148
|
+
metadata.each do |category, events|
|
149
|
+
events.each do |event_name, event_data|
|
150
|
+
# Create a composite key for easy lookup
|
151
|
+
lookup_key = "#{category}.#{event_name}"
|
152
|
+
|
153
|
+
# Enhance event data with source information
|
154
|
+
enhanced_data = event_data.merge(
|
155
|
+
'category' => category.to_s,
|
156
|
+
'event_name' => event_name.to_s,
|
157
|
+
'source_file' => source_file,
|
158
|
+
'lookup_key' => lookup_key
|
159
|
+
)
|
160
|
+
|
161
|
+
flattened[lookup_key] = enhanced_data
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
flattened
|
166
|
+
end
|
167
|
+
|
168
|
+
# Extract category from composite event key
|
169
|
+
#
|
170
|
+
# @param event_key [String] The composite event key (e.g., "task.completed")
|
171
|
+
# @return [String] The category portion
|
172
|
+
def extract_category_from_key(event_key)
|
173
|
+
event_key.split('.').first || 'unknown'
|
174
|
+
end
|
175
|
+
|
176
|
+
# Load metadata from a directory
|
177
|
+
#
|
178
|
+
# @param directory_path [String] Absolute path to the directory
|
179
|
+
# @param metadata [Hash] Hash to merge metadata into
|
180
|
+
# @return [void]
|
181
|
+
def load_metadata_from_directory(directory_path, metadata)
|
182
|
+
Rails.logger.debug { "Tasker: Scanning directory for metadata files: #{directory_path}" }
|
183
|
+
|
184
|
+
Dir.glob(File.join(directory_path, '*.{yml,yaml}')).each do |metadata_file|
|
185
|
+
file_metadata = load_metadata_from_file(metadata_file)
|
186
|
+
metadata.merge!(file_metadata)
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
# Get path to Tasker gem configuration
|
191
|
+
#
|
192
|
+
# @return [String] Path to Tasker config directory
|
193
|
+
def tasker_config_path
|
194
|
+
@tasker_config_path ||= File.join(Tasker::Engine.root, 'config', 'tasker')
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
@@ -0,0 +1,461 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tasker
|
4
|
+
module Events
|
5
|
+
# EventPayloadBuilder creates standardized event payloads for consistent telemetry
|
6
|
+
#
|
7
|
+
# This class solves the payload standardization issues identified during factory migration:
|
8
|
+
# - Missing :execution_duration keys in step completion events
|
9
|
+
# - Missing :error_message keys in step failure events
|
10
|
+
# - Missing :attempt_number keys for retry tracking
|
11
|
+
# - Inconsistent payload structure across different event publishers
|
12
|
+
#
|
13
|
+
# Usage:
|
14
|
+
# payload = EventPayloadBuilder.build_step_payload(step, task, event_type: :completed)
|
15
|
+
# Tasker::Events::Publisher.instance.publish('step.completed', payload)
|
16
|
+
class EventPayloadBuilder
|
17
|
+
class << self
|
18
|
+
# Build standardized payload for step events
|
19
|
+
#
|
20
|
+
# @param step [WorkflowStep] The step object
|
21
|
+
# @param task [Task] The associated task
|
22
|
+
# @param event_type [Symbol] The type of event (:started, :completed, :failed, :retry, etc.)
|
23
|
+
# @param additional_context [Hash] Additional context to merge in
|
24
|
+
# @return [Hash] Standardized event payload
|
25
|
+
def build_step_payload(step, task = nil, event_type: :completed, additional_context: {})
|
26
|
+
StepPayloadBuilder.build(step, task, event_type, additional_context)
|
27
|
+
end
|
28
|
+
|
29
|
+
# Build standardized payload for task events
|
30
|
+
#
|
31
|
+
# @param task [Task] The task object
|
32
|
+
# @param event_type [Symbol] The type of event (:started, :completed, :failed, etc.)
|
33
|
+
# @param additional_context [Hash] Additional context to merge in
|
34
|
+
# @return [Hash] Standardized event payload
|
35
|
+
def build_task_payload(task, event_type: :completed, additional_context: {})
|
36
|
+
# Get all completion stats in a single optimized query
|
37
|
+
stats = Tasker::WorkflowStep.task_completion_stats(task)
|
38
|
+
|
39
|
+
base_payload = {
|
40
|
+
# Core identifiers
|
41
|
+
task_id: task.task_id,
|
42
|
+
task_name: get_task_name(task),
|
43
|
+
|
44
|
+
# Timing information - only set completed_at for fully completed tasks
|
45
|
+
started_at: task.created_at&.iso8601,
|
46
|
+
completed_at: stats[:all_complete] ? stats[:latest_completion_time]&.iso8601 : nil,
|
47
|
+
|
48
|
+
# Task metadata
|
49
|
+
task_type: task.class.name,
|
50
|
+
event_type: event_type.to_s,
|
51
|
+
timestamp: Time.current.iso8601
|
52
|
+
}
|
53
|
+
|
54
|
+
# Add duration and step statistics to all task events
|
55
|
+
base_payload.merge!(build_task_timing_and_statistics(task, stats))
|
56
|
+
|
57
|
+
# Add event-specific fields
|
58
|
+
case event_type
|
59
|
+
when :completed
|
60
|
+
base_payload.merge!(build_task_completion_specific_payload(task))
|
61
|
+
when :failed
|
62
|
+
base_payload.merge!(build_task_failure_payload(task, additional_context))
|
63
|
+
when :started
|
64
|
+
base_payload.merge!(build_task_start_payload(task))
|
65
|
+
end
|
66
|
+
|
67
|
+
# Merge additional context, allowing overrides
|
68
|
+
base_payload.merge!(additional_context)
|
69
|
+
|
70
|
+
base_payload
|
71
|
+
end
|
72
|
+
|
73
|
+
# Build standardized payload for workflow orchestration events
|
74
|
+
#
|
75
|
+
# @param event_type [Symbol] The orchestration event type
|
76
|
+
# @param context [Hash] The orchestration context
|
77
|
+
# @return [Hash] Standardized orchestration payload
|
78
|
+
def build_orchestration_payload(event_type:, context: {})
|
79
|
+
{
|
80
|
+
# Event metadata
|
81
|
+
event_type: event_type.to_s,
|
82
|
+
orchestration_event: true,
|
83
|
+
timestamp: Time.current.iso8601,
|
84
|
+
|
85
|
+
# Merge provided context
|
86
|
+
**context
|
87
|
+
}
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# Get task name safely handling the named_task association
|
93
|
+
#
|
94
|
+
# @param task [Task] The task object
|
95
|
+
# @return [String] The task name
|
96
|
+
def get_task_name(task)
|
97
|
+
if task.respond_to?(:named_task) && task.named_task
|
98
|
+
task.named_task.name
|
99
|
+
elsif task.respond_to?(:name)
|
100
|
+
task.name
|
101
|
+
else
|
102
|
+
'unknown_task'
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Build completion-specific payload fields
|
107
|
+
#
|
108
|
+
# @param step [WorkflowStep] The completed step
|
109
|
+
# @return [Hash] Completion payload fields
|
110
|
+
def build_completion_payload(step)
|
111
|
+
payload = {}
|
112
|
+
|
113
|
+
# Calculate execution duration using last_attempted_at and processed_at
|
114
|
+
payload[:execution_duration] = if step.last_attempted_at && step.processed_at
|
115
|
+
(step.processed_at - step.last_attempted_at).round(3)
|
116
|
+
else
|
117
|
+
0.0
|
118
|
+
end
|
119
|
+
|
120
|
+
# Include step results if available
|
121
|
+
payload[:step_results] = step.results if step.results.present?
|
122
|
+
|
123
|
+
payload
|
124
|
+
end
|
125
|
+
|
126
|
+
# Build failure-specific payload fields
|
127
|
+
#
|
128
|
+
# @param step [WorkflowStep] The failed step
|
129
|
+
# @param additional_context [Hash] Additional context (may include error details)
|
130
|
+
# @return [Hash] Failure payload fields
|
131
|
+
def build_failure_payload(step, additional_context = {})
|
132
|
+
payload = {}
|
133
|
+
|
134
|
+
# Extract error information using the refactored service
|
135
|
+
error_info = ErrorInfoExtractor.extract(step, additional_context)
|
136
|
+
payload.merge!(error_info)
|
137
|
+
|
138
|
+
# Include step results
|
139
|
+
payload[:step_results] = step.results if step.results.present?
|
140
|
+
|
141
|
+
payload
|
142
|
+
end
|
143
|
+
|
144
|
+
# Build start-specific payload fields
|
145
|
+
#
|
146
|
+
# @param step [WorkflowStep] The starting step
|
147
|
+
# @return [Hash] Start payload fields
|
148
|
+
def build_start_payload(step)
|
149
|
+
{
|
150
|
+
step_inputs: step.inputs,
|
151
|
+
step_dependencies: step.respond_to?(:parents) ? step.parents.map(&:name) : []
|
152
|
+
}
|
153
|
+
end
|
154
|
+
|
155
|
+
# Build retry-specific payload fields
|
156
|
+
#
|
157
|
+
# @param step [WorkflowStep] The step being retried
|
158
|
+
# @return [Hash] Retry payload fields
|
159
|
+
def build_retry_payload(step)
|
160
|
+
{
|
161
|
+
previous_attempts: step.attempts - 1,
|
162
|
+
retry_reason: 'Step execution failed',
|
163
|
+
backoff_strategy: 'exponential' # Could be made configurable
|
164
|
+
}
|
165
|
+
end
|
166
|
+
|
167
|
+
# Build task timing and statistics (shared across all task event types)
|
168
|
+
#
|
169
|
+
# @param task [Task] The task
|
170
|
+
# @param stats [Hash] Pre-calculated task completion statistics from WorkflowStep.task_completion_stats
|
171
|
+
# @return [Hash] Timing and statistics payload fields
|
172
|
+
def build_task_timing_and_statistics(task, stats)
|
173
|
+
payload = {}
|
174
|
+
|
175
|
+
# Distinguish between total duration (all steps complete) and current duration (in progress)
|
176
|
+
if stats[:all_complete] && task.created_at && stats[:latest_completion_time]
|
177
|
+
# True total execution duration - complete workflow
|
178
|
+
payload[:total_execution_duration] = (stats[:latest_completion_time] - task.created_at).round(3)
|
179
|
+
payload[:current_execution_duration] = nil # Not applicable for completed tasks
|
180
|
+
elsif task.created_at
|
181
|
+
# Current execution duration - task still in progress
|
182
|
+
payload[:total_execution_duration] = nil # Not available until completion
|
183
|
+
payload[:current_execution_duration] = (Time.current - task.created_at).round(3)
|
184
|
+
else
|
185
|
+
# No timing information available
|
186
|
+
payload[:total_execution_duration] = nil
|
187
|
+
payload[:current_execution_duration] = nil
|
188
|
+
end
|
189
|
+
|
190
|
+
# Use pre-calculated step statistics (no additional queries needed)
|
191
|
+
payload[:total_steps] = stats[:total_steps]
|
192
|
+
payload[:completed_steps] = stats[:completed_steps]
|
193
|
+
payload[:failed_steps] = stats[:failed_steps]
|
194
|
+
payload[:pending_steps] = stats[:pending_steps]
|
195
|
+
|
196
|
+
payload
|
197
|
+
end
|
198
|
+
|
199
|
+
# Build task completion-specific payload fields (only for completed events)
|
200
|
+
#
|
201
|
+
# @param task [Task] The completed task
|
202
|
+
# @return [Hash] Completion-specific payload fields
|
203
|
+
def build_task_completion_specific_payload(_task)
|
204
|
+
{
|
205
|
+
# Could add completion-specific metadata here if needed
|
206
|
+
# For now, all the important data is in the timing/statistics method
|
207
|
+
}
|
208
|
+
end
|
209
|
+
|
210
|
+
# Build task failure payload fields
|
211
|
+
#
|
212
|
+
# @param task [Task] The failed task
|
213
|
+
# @param additional_context [Hash] Additional context
|
214
|
+
# @return [Hash] Task failure payload fields
|
215
|
+
def build_task_failure_payload(_task, additional_context = {})
|
216
|
+
payload = {}
|
217
|
+
|
218
|
+
# Extract error information
|
219
|
+
if additional_context[:error_steps].present?
|
220
|
+
payload[:error_steps] = additional_context[:error_steps]
|
221
|
+
payload[:error_step_results] = additional_context[:error_step_results]
|
222
|
+
end
|
223
|
+
|
224
|
+
# Default error message if not provided
|
225
|
+
payload[:error_message] = additional_context[:error_message] ||
|
226
|
+
additional_context[:error] ||
|
227
|
+
'Task execution failed'
|
228
|
+
|
229
|
+
payload
|
230
|
+
end
|
231
|
+
|
232
|
+
# Build task start payload fields
|
233
|
+
#
|
234
|
+
# @param task [Task] The starting task
|
235
|
+
# @return [Hash] Task start payload fields
|
236
|
+
def build_task_start_payload(task)
|
237
|
+
{
|
238
|
+
task_context: task.context,
|
239
|
+
total_steps: task.workflow_steps.count
|
240
|
+
}
|
241
|
+
end
|
242
|
+
|
243
|
+
# Check if a step is complete (reused from various helpers)
|
244
|
+
#
|
245
|
+
# @param step [WorkflowStep] The step to check
|
246
|
+
# @return [Boolean] True if step is complete
|
247
|
+
def step_complete?(step)
|
248
|
+
[
|
249
|
+
Tasker::Constants::WorkflowStepStatuses::COMPLETE,
|
250
|
+
Tasker::Constants::WorkflowStepStatuses::RESOLVED_MANUALLY
|
251
|
+
].include?(step.status)
|
252
|
+
end
|
253
|
+
|
254
|
+
# Check if a step is in error state
|
255
|
+
#
|
256
|
+
# @param step [WorkflowStep] The step to check
|
257
|
+
# @return [Boolean] True if step is in error
|
258
|
+
def step_in_error?(step)
|
259
|
+
step.status == Tasker::Constants::WorkflowStepStatuses::ERROR
|
260
|
+
end
|
261
|
+
|
262
|
+
# Service class to build step payloads for different event types
|
263
|
+
# Reduces complexity by organizing payload building logic
|
264
|
+
class StepPayloadBuilder
|
265
|
+
class << self
|
266
|
+
# Build complete step payload for specified event type
|
267
|
+
#
|
268
|
+
# @param step [WorkflowStep] The workflow step
|
269
|
+
# @param task [Task] The task (optional, will be retrieved from step if nil)
|
270
|
+
# @param event_type [Symbol] The event type
|
271
|
+
# @param additional_context [Hash] Additional context to merge
|
272
|
+
# @return [Hash] Complete event payload
|
273
|
+
def build(step, task, event_type, additional_context)
|
274
|
+
task ||= step.task
|
275
|
+
|
276
|
+
base_payload = build_base_payload(step, task, event_type)
|
277
|
+
event_specific_payload = build_event_specific_payload(step, event_type, additional_context)
|
278
|
+
|
279
|
+
# Merge additional context, allowing overrides
|
280
|
+
base_payload.merge(event_specific_payload).merge(additional_context)
|
281
|
+
end
|
282
|
+
|
283
|
+
private
|
284
|
+
|
285
|
+
# Build base payload common to all step events
|
286
|
+
#
|
287
|
+
# @param step [WorkflowStep] The workflow step
|
288
|
+
# @param task [Task] The task
|
289
|
+
# @param event_type [Symbol] The event type
|
290
|
+
# @return [Hash] Base payload
|
291
|
+
def build_base_payload(step, task, event_type)
|
292
|
+
{
|
293
|
+
# Core identifiers (always present)
|
294
|
+
task_id: task.task_id,
|
295
|
+
step_id: step.workflow_step_id,
|
296
|
+
step_name: step.name,
|
297
|
+
|
298
|
+
# Timing information - steps use last_attempted_at and processed_at
|
299
|
+
started_at: step.last_attempted_at&.iso8601,
|
300
|
+
completed_at: step.processed_at&.iso8601,
|
301
|
+
|
302
|
+
# Retry and attempt tracking
|
303
|
+
attempt_number: step.attempts || 1,
|
304
|
+
retry_limit: step.retry_limit,
|
305
|
+
|
306
|
+
# Event metadata
|
307
|
+
event_type: event_type.to_s,
|
308
|
+
timestamp: Time.current.iso8601
|
309
|
+
}
|
310
|
+
end
|
311
|
+
|
312
|
+
# Build event-specific payload fields
|
313
|
+
#
|
314
|
+
# @param step [WorkflowStep] The workflow step
|
315
|
+
# @param event_type [Symbol] The event type
|
316
|
+
# @param additional_context [Hash] Additional context
|
317
|
+
# @return [Hash] Event-specific payload
|
318
|
+
def build_event_specific_payload(step, event_type, additional_context)
|
319
|
+
case event_type
|
320
|
+
when :completed
|
321
|
+
build_completion_payload(step)
|
322
|
+
when :failed
|
323
|
+
build_failure_payload(step, additional_context)
|
324
|
+
when :started
|
325
|
+
build_start_payload(step)
|
326
|
+
when :retry
|
327
|
+
build_retry_payload(step)
|
328
|
+
else
|
329
|
+
{}
|
330
|
+
end
|
331
|
+
end
|
332
|
+
|
333
|
+
# Build completion-specific payload fields
|
334
|
+
#
|
335
|
+
# @param step [WorkflowStep] The completed step
|
336
|
+
# @return [Hash] Completion payload fields
|
337
|
+
def build_completion_payload(step)
|
338
|
+
payload = {}
|
339
|
+
|
340
|
+
# Calculate execution duration using last_attempted_at and processed_at
|
341
|
+
payload[:execution_duration] = if step.last_attempted_at && step.processed_at
|
342
|
+
(step.processed_at - step.last_attempted_at).round(3)
|
343
|
+
else
|
344
|
+
0.0
|
345
|
+
end
|
346
|
+
|
347
|
+
# Include step results if available
|
348
|
+
payload[:step_results] = step.results if step.results.present?
|
349
|
+
|
350
|
+
payload
|
351
|
+
end
|
352
|
+
|
353
|
+
# Build failure-specific payload fields
|
354
|
+
#
|
355
|
+
# @param step [WorkflowStep] The failed step
|
356
|
+
# @param additional_context [Hash] Additional context (may include error details)
|
357
|
+
# @return [Hash] Failure payload fields
|
358
|
+
def build_failure_payload(step, additional_context = {})
|
359
|
+
payload = {}
|
360
|
+
|
361
|
+
# Extract error information using the refactored service
|
362
|
+
error_info = ErrorInfoExtractor.extract(step, additional_context)
|
363
|
+
payload.merge!(error_info)
|
364
|
+
|
365
|
+
# Include step results
|
366
|
+
payload[:step_results] = step.results if step.results.present?
|
367
|
+
|
368
|
+
payload
|
369
|
+
end
|
370
|
+
|
371
|
+
# Build start-specific payload fields
|
372
|
+
#
|
373
|
+
# @param step [WorkflowStep] The starting step
|
374
|
+
# @return [Hash] Start payload fields
|
375
|
+
def build_start_payload(step)
|
376
|
+
{
|
377
|
+
step_inputs: step.inputs,
|
378
|
+
step_dependencies: step.respond_to?(:parents) ? step.parents.map(&:name) : []
|
379
|
+
}
|
380
|
+
end
|
381
|
+
|
382
|
+
# Build retry-specific payload fields
|
383
|
+
#
|
384
|
+
# @param step [WorkflowStep] The step being retried
|
385
|
+
# @return [Hash] Retry payload fields
|
386
|
+
def build_retry_payload(step)
|
387
|
+
{
|
388
|
+
previous_attempts: step.attempts - 1,
|
389
|
+
retry_reason: 'Step execution failed',
|
390
|
+
backoff_strategy: 'exponential' # Could be made configurable
|
391
|
+
}
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
# Service class to extract error information from step and context
|
398
|
+
# Reduces complexity by organizing error extraction logic
|
399
|
+
class ErrorInfoExtractor
|
400
|
+
class << self
|
401
|
+
# Extract error information from step and context
|
402
|
+
#
|
403
|
+
# @param step [WorkflowStep] The step with error
|
404
|
+
# @param additional_context [Hash] Additional context
|
405
|
+
# @return [Hash] Error information payload
|
406
|
+
def extract(step, additional_context = {})
|
407
|
+
error_payload = {}
|
408
|
+
|
409
|
+
error_payload[:error_message] = extract_error_message(step, additional_context)
|
410
|
+
error_payload[:exception_class] = extract_exception_class(additional_context)
|
411
|
+
|
412
|
+
backtrace = extract_backtrace(step, additional_context)
|
413
|
+
error_payload[:backtrace] = backtrace if backtrace
|
414
|
+
|
415
|
+
error_payload
|
416
|
+
end
|
417
|
+
|
418
|
+
private
|
419
|
+
|
420
|
+
# Extract the primary error message from various sources
|
421
|
+
#
|
422
|
+
# @param step [WorkflowStep] The step with error
|
423
|
+
# @param additional_context [Hash] Additional context
|
424
|
+
# @return [String] The error message
|
425
|
+
def extract_error_message(step, additional_context)
|
426
|
+
additional_context[:error_message] ||
|
427
|
+
additional_context[:error] ||
|
428
|
+
step.results&.dig('error') ||
|
429
|
+
step.results&.dig(:error) ||
|
430
|
+
'Unknown error'
|
431
|
+
end
|
432
|
+
|
433
|
+
# Extract the exception class name
|
434
|
+
#
|
435
|
+
# @param additional_context [Hash] Additional context
|
436
|
+
# @return [String] The exception class name
|
437
|
+
def extract_exception_class(additional_context)
|
438
|
+
if additional_context[:exception_object]
|
439
|
+
additional_context[:exception_object].class.name
|
440
|
+
elsif additional_context[:exception_class]
|
441
|
+
additional_context[:exception_class]
|
442
|
+
else
|
443
|
+
'StandardError'
|
444
|
+
end
|
445
|
+
end
|
446
|
+
|
447
|
+
# Extract backtrace information from various sources
|
448
|
+
#
|
449
|
+
# @param step [WorkflowStep] The step with error
|
450
|
+
# @param additional_context [Hash] Additional context
|
451
|
+
# @return [String, nil] The backtrace or nil if not available
|
452
|
+
def extract_backtrace(step, additional_context)
|
453
|
+
additional_context[:backtrace] ||
|
454
|
+
step.results&.dig('backtrace') ||
|
455
|
+
step.results&.dig(:backtrace)
|
456
|
+
end
|
457
|
+
end
|
458
|
+
end
|
459
|
+
end
|
460
|
+
end
|
461
|
+
end
|