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,128 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tasker
|
4
|
+
module Concerns
|
5
|
+
# IdempotentStateTransitions provides helper methods for safely transitioning
|
6
|
+
# state machine objects without throwing errors on same-state transitions.
|
7
|
+
#
|
8
|
+
# This concern extracts the common pattern of checking current state before
|
9
|
+
# attempting transitions to handle Statesman's restriction on same-state transitions.
|
10
|
+
module IdempotentStateTransitions
|
11
|
+
extend ActiveSupport::Concern
|
12
|
+
|
13
|
+
# Safely transition a state machine object to a target state
|
14
|
+
#
|
15
|
+
# Checks the current state first and only attempts transition if different.
|
16
|
+
# This prevents Statesman's "Cannot transition from X to X" errors.
|
17
|
+
#
|
18
|
+
# @param state_machine_object [Object] Object with a state_machine method
|
19
|
+
# @param target_state [String] The desired target state
|
20
|
+
# @param metadata [Hash] Optional metadata for the transition
|
21
|
+
# @return [Boolean] True if transition occurred, false if already in target state
|
22
|
+
def safe_transition_to(state_machine_object, target_state, metadata = {})
|
23
|
+
current_state = state_machine_object.state_machine.current_state
|
24
|
+
|
25
|
+
if current_state == target_state
|
26
|
+
Rails.logger.debug do
|
27
|
+
"#{self.class.name}: #{state_machine_object.class.name} #{state_machine_object.id} " \
|
28
|
+
"already in #{target_state}, skipping transition"
|
29
|
+
end
|
30
|
+
return false
|
31
|
+
end
|
32
|
+
|
33
|
+
Rails.logger.debug do
|
34
|
+
"#{self.class.name}: Transitioning #{state_machine_object.class.name} #{state_machine_object.id} " \
|
35
|
+
"from #{current_state} to #{target_state}"
|
36
|
+
end
|
37
|
+
|
38
|
+
state_machine_object.state_machine.transition_to!(target_state, metadata)
|
39
|
+
true
|
40
|
+
rescue Statesman::GuardFailedError => e
|
41
|
+
Rails.logger.debug do
|
42
|
+
"#{self.class.name}: Guard clause prevented transition of #{state_machine_object.class.name} " \
|
43
|
+
"#{state_machine_object.id} from '#{current_state}' to '#{target_state}': #{e.message}"
|
44
|
+
end
|
45
|
+
false
|
46
|
+
rescue Statesman::TransitionFailedError => e
|
47
|
+
Rails.logger.warn do
|
48
|
+
"#{self.class.name}: Invalid transition for #{state_machine_object.class.name} " \
|
49
|
+
"#{state_machine_object.id} from '#{current_state}' to '#{target_state}': #{e.message}"
|
50
|
+
end
|
51
|
+
false
|
52
|
+
rescue StandardError => e
|
53
|
+
Rails.logger.error do
|
54
|
+
"#{self.class.name}: Failed to transition #{state_machine_object.class.name} #{state_machine_object.id} " \
|
55
|
+
"to #{target_state}: #{e.message}"
|
56
|
+
end
|
57
|
+
raise
|
58
|
+
end
|
59
|
+
|
60
|
+
# Safely transition to target state only if current state matches one of the allowed from states
|
61
|
+
#
|
62
|
+
# @param state_machine_object [Object] Object with a state_machine method
|
63
|
+
# @param target_state [String] The desired target state
|
64
|
+
# @param allowed_from_states [Array<String>] States from which transition is allowed
|
65
|
+
# @param metadata [Hash] Optional metadata for the transition
|
66
|
+
# @return [Symbol] :transitioned, :already_target, :invalid_from_state
|
67
|
+
def conditional_transition_to(state_machine_object, target_state, allowed_from_states, metadata = {})
|
68
|
+
current_state = state_machine_object.state_machine.current_state
|
69
|
+
|
70
|
+
# Already in target state - idempotent
|
71
|
+
return :already_target if current_state == target_state
|
72
|
+
|
73
|
+
# Check if current state allows this transition
|
74
|
+
unless allowed_from_states.include?(current_state)
|
75
|
+
allowed_states_list = allowed_from_states.join(', ')
|
76
|
+
Rails.logger.debug do
|
77
|
+
"#{self.class.name}: Cannot transition #{state_machine_object.class.name} #{state_machine_object.id} " \
|
78
|
+
"from #{current_state} to #{target_state}. Allowed from states: #{allowed_states_list}"
|
79
|
+
end
|
80
|
+
return :invalid_from_state
|
81
|
+
end
|
82
|
+
|
83
|
+
# Perform the transition
|
84
|
+
state_machine_object.state_machine.transition_to!(target_state, metadata)
|
85
|
+
Rails.logger.debug do
|
86
|
+
"#{self.class.name}: Successfully transitioned" \
|
87
|
+
"#{state_machine_object.class.name} #{state_machine_object.id} " \
|
88
|
+
"from #{current_state} to #{target_state}"
|
89
|
+
end
|
90
|
+
:transitioned
|
91
|
+
rescue StandardError => e
|
92
|
+
Rails.logger.error do
|
93
|
+
"#{self.class.name}: Failed to transition #{state_machine_object.class.name} #{state_machine_object.id} " \
|
94
|
+
"to #{target_state}: #{e.message}"
|
95
|
+
end
|
96
|
+
raise
|
97
|
+
end
|
98
|
+
|
99
|
+
# Get current state safely, handling cases where state machine might not exist
|
100
|
+
#
|
101
|
+
# @param state_machine_object [Object] Object with a state_machine method
|
102
|
+
# @return [String, nil] Current state or nil if no state machine
|
103
|
+
def safe_current_state(state_machine_object)
|
104
|
+
return nil unless state_machine_object.respond_to?(:state_machine)
|
105
|
+
|
106
|
+
state_machine_object.state_machine.current_state
|
107
|
+
rescue StandardError => e
|
108
|
+
Rails.logger.warn do
|
109
|
+
"#{self.class.name}: Could not get current state for #{state_machine_object.class.name} " \
|
110
|
+
"#{state_machine_object.id}: #{e.message}"
|
111
|
+
end
|
112
|
+
nil
|
113
|
+
end
|
114
|
+
|
115
|
+
# Check if an object is in any of the specified states
|
116
|
+
#
|
117
|
+
# @param state_machine_object [Object] Object with a state_machine method
|
118
|
+
# @param states [Array<String>] States to check against
|
119
|
+
# @return [Boolean] True if current state is in the provided states
|
120
|
+
def in_any_state?(state_machine_object, states)
|
121
|
+
current_state = safe_current_state(state_machine_object)
|
122
|
+
return false if current_state.nil?
|
123
|
+
|
124
|
+
states.include?(current_state)
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'event_publisher'
|
4
|
+
|
5
|
+
module Tasker
|
6
|
+
module Concerns
|
7
|
+
# StateMachineBase provides shared functionality for all Tasker state machines
|
8
|
+
#
|
9
|
+
# This concern consolidates common patterns used by TaskStateMachine and StepStateMachine:
|
10
|
+
# - Idempotent transition handling
|
11
|
+
# - Event publishing through unified publisher
|
12
|
+
# - Consistent transition logging
|
13
|
+
# - Helper methods for state checking
|
14
|
+
#
|
15
|
+
# It replaces the legacy LifecycleEvents system with direct integration to Events::Publisher
|
16
|
+
module StateMachineBase
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
include EventPublisher
|
19
|
+
|
20
|
+
included do
|
21
|
+
# Common before_transition callback for idempotent handling
|
22
|
+
before_transition do |object, transition|
|
23
|
+
# Handle idempotent transitions using unified helper
|
24
|
+
if StateMachineBase.idempotent_transition?(object, transition.to_state)
|
25
|
+
raise Statesman::GuardFailedError, "Already in target state #{transition.to_state}"
|
26
|
+
end
|
27
|
+
|
28
|
+
# Log the transition for debugging
|
29
|
+
effective_current_state = StateMachineBase.effective_current_state(object)
|
30
|
+
object_id = StateMachineBase.object_id(object)
|
31
|
+
Rails.logger.debug do
|
32
|
+
"#{object.class.name} #{object_id} transitioning from #{effective_current_state} to #{transition.to_state}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Common after_transition callback for event publishing
|
37
|
+
after_transition do |object, transition|
|
38
|
+
# Determine the appropriate event name based on the transition
|
39
|
+
event_name = determine_transition_event_name(transition.from_state, transition.to_state)
|
40
|
+
|
41
|
+
# Only fire the event if we have a valid event name
|
42
|
+
if event_name
|
43
|
+
# Build context appropriate for the object type
|
44
|
+
context = StateMachineBase.build_event_context(object, transition)
|
45
|
+
|
46
|
+
# Fire the event through unified publisher
|
47
|
+
StateMachineBase.publish_event(event_name, context)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
module ClassMethods
|
53
|
+
# Check if a transition is idempotent (current state == target state)
|
54
|
+
#
|
55
|
+
# @param object [Object] The object with state_machine
|
56
|
+
# @param target_state [String] The target state
|
57
|
+
# @return [Boolean] True if this is an idempotent transition
|
58
|
+
def idempotent_transition?(object, target_state)
|
59
|
+
effective_state = effective_current_state(object)
|
60
|
+
is_idempotent = effective_state == target_state
|
61
|
+
|
62
|
+
if is_idempotent
|
63
|
+
Rails.logger.debug do
|
64
|
+
"#{object.class.name}: Detected idempotent transition to #{target_state} for #{object_id(object)}"
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
is_idempotent
|
69
|
+
end
|
70
|
+
|
71
|
+
# Get the effective current state, handling blank/empty states
|
72
|
+
#
|
73
|
+
# @param object [Object] The object to check
|
74
|
+
# @return [String] The effective current state (blank states become default)
|
75
|
+
def effective_current_state(object)
|
76
|
+
current_state = object.state_machine.current_state
|
77
|
+
|
78
|
+
current_state.presence || case object.class.name
|
79
|
+
when /Task/
|
80
|
+
Constants::TaskStatuses::PENDING
|
81
|
+
when /WorkflowStep/
|
82
|
+
Constants::WorkflowStepStatuses::PENDING
|
83
|
+
else
|
84
|
+
current_state
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Get a consistent object identifier for logging
|
89
|
+
#
|
90
|
+
# @param object [Object] The object
|
91
|
+
# @return [String] The object identifier
|
92
|
+
def object_id(object)
|
93
|
+
case object.class.name
|
94
|
+
when /Task/
|
95
|
+
object.task_id
|
96
|
+
when /WorkflowStep/
|
97
|
+
object.workflow_step_id
|
98
|
+
else
|
99
|
+
object.id
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Build event context appropriate for the object type
|
104
|
+
#
|
105
|
+
# @param object [Object] The object being transitioned
|
106
|
+
# @param transition [Statesman::Transition] The transition
|
107
|
+
# @return [Hash] Event context
|
108
|
+
def build_event_context(object, transition)
|
109
|
+
base_context = {
|
110
|
+
from_state: transition.from_state,
|
111
|
+
to_state: transition.to_state,
|
112
|
+
transitioned_at: Time.zone.now
|
113
|
+
}
|
114
|
+
|
115
|
+
case object.class.name
|
116
|
+
when /Task/
|
117
|
+
base_context.merge(
|
118
|
+
task_id: object.task_id,
|
119
|
+
task_name: object.name,
|
120
|
+
task_context: object.respond_to?(:context) ? object.context : nil
|
121
|
+
)
|
122
|
+
when /WorkflowStep/
|
123
|
+
base_context.merge(
|
124
|
+
task_id: object.task_id,
|
125
|
+
step_id: object.workflow_step_id,
|
126
|
+
step_name: object.name
|
127
|
+
)
|
128
|
+
else
|
129
|
+
base_context.merge(
|
130
|
+
object_id: object.id,
|
131
|
+
object_type: object.class.name
|
132
|
+
)
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
# Publish event through unified Events::Publisher system
|
137
|
+
# Uses the EventPublisher concern for consistent implementation
|
138
|
+
#
|
139
|
+
# @param event_name [String] The event name
|
140
|
+
# @param context [Hash] The event context
|
141
|
+
# @return [void]
|
142
|
+
# Note: This method is provided by the EventPublisher concern
|
143
|
+
|
144
|
+
# Log an invalid from-state transition
|
145
|
+
#
|
146
|
+
# @param object [Object] The object
|
147
|
+
# @param current_state [String] The current state
|
148
|
+
# @param target_state [String] The target state
|
149
|
+
# @param reason [String] The reason for the restriction
|
150
|
+
def log_invalid_from_state(object, current_state, target_state, reason)
|
151
|
+
Rails.logger.debug do
|
152
|
+
"#{name}: Cannot transition to #{target_state} from '#{current_state}' " \
|
153
|
+
"(#{object.class.name} #{object_id(object)}). #{reason}."
|
154
|
+
end
|
155
|
+
end
|
156
|
+
|
157
|
+
# Log when dependencies/conditions are not met
|
158
|
+
#
|
159
|
+
# @param object [Object] The object
|
160
|
+
# @param target_state [String] The target state
|
161
|
+
# @param reason [String] The specific reason
|
162
|
+
def log_condition_not_met(object, target_state, reason)
|
163
|
+
Rails.logger.debug do
|
164
|
+
"#{name}: Cannot transition #{object.class.name} #{object_id(object)} to #{target_state} - #{reason}"
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
# Log the result of a transition check
|
169
|
+
#
|
170
|
+
# @param object [Object] The object
|
171
|
+
# @param target_state [String] The target state
|
172
|
+
# @param result [Boolean] Whether the transition is allowed
|
173
|
+
# @param reason [String] The reason for the result
|
174
|
+
def log_transition_result(object, target_state, result, reason)
|
175
|
+
object_identifier = "#{object.class.name} #{object_id(object)}"
|
176
|
+
if result
|
177
|
+
Rails.logger.debug do
|
178
|
+
"#{name}: Allowing transition to #{target_state} for #{object_identifier} (#{reason})"
|
179
|
+
end
|
180
|
+
else
|
181
|
+
Rails.logger.debug do
|
182
|
+
"#{name}: Blocking transition to #{target_state} for #{object_identifier} (#{reason} failed)"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# Access to class methods from instance methods
|
189
|
+
module StateMachineBase
|
190
|
+
module ClassMethods
|
191
|
+
delegate :idempotent_transition?, to: :StateMachineBase
|
192
|
+
|
193
|
+
delegate :effective_current_state, to: :StateMachineBase
|
194
|
+
|
195
|
+
delegate :object_id, to: :StateMachineBase
|
196
|
+
|
197
|
+
# Use EventPublisher for consistent event publishing
|
198
|
+
def publish_event(event_name, context = {})
|
199
|
+
# Create a temporary object to access the concern method
|
200
|
+
publisher = Object.new.extend(EventPublisher)
|
201
|
+
publisher.send(:publish_event, event_name, context)
|
202
|
+
end
|
203
|
+
end
|
204
|
+
end
|
205
|
+
|
206
|
+
private
|
207
|
+
|
208
|
+
# Instance method is provided by EventPublisher concern
|
209
|
+
# No need to override here
|
210
|
+
|
211
|
+
# Instance method wrapper for determining transition event name
|
212
|
+
# (To be implemented by including classes)
|
213
|
+
def determine_transition_event_name(from_state, to_state)
|
214
|
+
self.class.determine_transition_event_name(from_state, to_state)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|