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,324 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json-schema'
|
5
|
+
require 'concurrent'
|
6
|
+
require_relative '../events/custom_registry'
|
7
|
+
|
8
|
+
module Tasker
|
9
|
+
module TaskHandler
|
10
|
+
# Class methods for task handlers
|
11
|
+
#
|
12
|
+
# This module provides class-level functionality for task handlers,
|
13
|
+
# including step template definition and handler registration.
|
14
|
+
module ClassMethods
|
15
|
+
# Helper class for defining step templates in task handlers
|
16
|
+
class StepTemplateDefiner
|
17
|
+
# @return [Array<Tasker::Types::StepTemplate>] The defined step templates
|
18
|
+
attr_reader :step_templates
|
19
|
+
|
20
|
+
# @return [Class] The class where templates are being defined
|
21
|
+
attr_reader :klass
|
22
|
+
|
23
|
+
# @return [Hash<String, String>] Mapping of step names to handler class names
|
24
|
+
attr_reader :step_handler_class_map
|
25
|
+
|
26
|
+
# @return [Hash<String, Object>] Mapping of step names to handler configs
|
27
|
+
attr_reader :step_handler_config_map
|
28
|
+
|
29
|
+
# Create a new step template definer
|
30
|
+
#
|
31
|
+
# @param klass [Class] The class where templates are being defined
|
32
|
+
# @return [StepTemplateDefiner] A new step template definer
|
33
|
+
def initialize(klass)
|
34
|
+
@klass = klass
|
35
|
+
@step_templates = []
|
36
|
+
@step_handler_class_map = {}
|
37
|
+
@step_handler_config_map = {}
|
38
|
+
end
|
39
|
+
|
40
|
+
# Define a new step template
|
41
|
+
#
|
42
|
+
# @param kwargs [Hash] The step template attributes
|
43
|
+
# @option kwargs [String] :dependent_system The system that this step depends on
|
44
|
+
# @option kwargs [String] :name The name identifier for this step
|
45
|
+
# @option kwargs [String] :description A description of what this step does
|
46
|
+
# @option kwargs [Boolean] :default_retryable Whether this step can be retried
|
47
|
+
# @option kwargs [Integer] :default_retry_limit The maximum number of retry attempts
|
48
|
+
# @option kwargs [Boolean] :skippable Whether this step can be skipped
|
49
|
+
# @option kwargs [Class] :handler_class The class that implements the step's logic
|
50
|
+
# @option kwargs [String, nil] :depends_on_step Name of a step this depends on
|
51
|
+
# @option kwargs [Array<String>] :depends_on_steps Names of steps this depends on
|
52
|
+
# @option kwargs [Object, nil] :handler_config Configuration for the step handler
|
53
|
+
# @option kwargs [Array<Hash>] :custom_events Custom events this step can publish
|
54
|
+
# @return [void]
|
55
|
+
def define(**kwargs)
|
56
|
+
dependent_system = kwargs.fetch(:dependent_system, Tasker::Constants::UNKNOWN)
|
57
|
+
name = kwargs.fetch(:name)
|
58
|
+
handler_class = kwargs.fetch(:handler_class)
|
59
|
+
description = kwargs.fetch(:description, name)
|
60
|
+
default_retryable = kwargs.fetch(:default_retryable, true)
|
61
|
+
default_retry_limit = kwargs.fetch(:default_retry_limit, 3)
|
62
|
+
skippable = kwargs.fetch(:skippable, false)
|
63
|
+
depends_on_step = kwargs.fetch(:depends_on_step, nil)
|
64
|
+
depends_on_steps = kwargs.fetch(:depends_on_steps, [])
|
65
|
+
handler_config = kwargs.fetch(:handler_config, nil)
|
66
|
+
custom_events = kwargs.fetch(:custom_events, [])
|
67
|
+
|
68
|
+
# Register custom events (both YAML-based and class-based) when step template is defined
|
69
|
+
register_custom_events_for_handler(custom_events, handler_class)
|
70
|
+
|
71
|
+
@step_templates << Tasker::Types::StepTemplate.new(
|
72
|
+
dependent_system: dependent_system,
|
73
|
+
name: name,
|
74
|
+
description: description,
|
75
|
+
default_retryable: default_retryable,
|
76
|
+
default_retry_limit: default_retry_limit,
|
77
|
+
skippable: skippable,
|
78
|
+
handler_class: handler_class,
|
79
|
+
depends_on_step: depends_on_step,
|
80
|
+
depends_on_steps: depends_on_steps,
|
81
|
+
handler_config: handler_config,
|
82
|
+
custom_events: custom_events
|
83
|
+
)
|
84
|
+
end
|
85
|
+
|
86
|
+
# Register the mapping of step names to handler classes and configs
|
87
|
+
#
|
88
|
+
# @return [void]
|
89
|
+
def register_class_map
|
90
|
+
@step_templates.each do |template|
|
91
|
+
@step_handler_class_map[template.name] = template.handler_class.to_s
|
92
|
+
@step_handler_config_map[template.name] = template.handler_config
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
# Register both YAML-based and class-based custom events from the step handler
|
99
|
+
#
|
100
|
+
# @param custom_events [Array<Hash>] Array of custom event configurations from YAML
|
101
|
+
# @param handler_class [Class] The handler class that can fire these events
|
102
|
+
# @return [void]
|
103
|
+
def register_custom_events_for_handler(custom_events, handler_class)
|
104
|
+
YamlEventRegistrar.register(custom_events, handler_class)
|
105
|
+
register_class_based_custom_events(handler_class)
|
106
|
+
end
|
107
|
+
|
108
|
+
# Register class-based custom events from a step handler class
|
109
|
+
#
|
110
|
+
# @param handler_class [Class] The step handler class to scan for custom events
|
111
|
+
# @return [void]
|
112
|
+
def register_class_based_custom_events(handler_class)
|
113
|
+
ClassBasedEventRegistrar.register(handler_class)
|
114
|
+
end
|
115
|
+
|
116
|
+
# Service class to register YAML-based custom events
|
117
|
+
# Reduces complexity by organizing YAML event registration logic
|
118
|
+
class YamlEventRegistrar
|
119
|
+
class << self
|
120
|
+
# Register YAML-based custom events
|
121
|
+
#
|
122
|
+
# @param custom_events [Array<Hash>] Array of custom event configurations from YAML
|
123
|
+
# @param handler_class [Class] The handler class that can fire these events
|
124
|
+
# @return [void]
|
125
|
+
def register(custom_events, handler_class)
|
126
|
+
custom_events.each do |event_config|
|
127
|
+
register_single_yaml_event(event_config, handler_class)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
# Register a single YAML-based custom event
|
134
|
+
#
|
135
|
+
# @param event_config [Hash] Event configuration
|
136
|
+
# @param handler_class [Class] Handler class
|
137
|
+
# @return [void]
|
138
|
+
def register_single_yaml_event(event_config, handler_class)
|
139
|
+
event_name = extract_event_name(event_config)
|
140
|
+
return unless event_name
|
141
|
+
|
142
|
+
description = extract_event_description(event_config, handler_class)
|
143
|
+
fired_by = [handler_class.name]
|
144
|
+
|
145
|
+
safely_register_event(event_name, description, fired_by, handler_class)
|
146
|
+
end
|
147
|
+
|
148
|
+
# Extract event name from configuration
|
149
|
+
#
|
150
|
+
# @param event_config [Hash] Event configuration
|
151
|
+
# @return [String, nil] Event name
|
152
|
+
def extract_event_name(event_config)
|
153
|
+
event_config[:name] || event_config['name']
|
154
|
+
end
|
155
|
+
|
156
|
+
# Extract event description from configuration
|
157
|
+
#
|
158
|
+
# @param event_config [Hash] Event configuration
|
159
|
+
# @param handler_class [Class] Handler class
|
160
|
+
# @return [String] Event description
|
161
|
+
def extract_event_description(event_config, handler_class)
|
162
|
+
event_config[:description] ||
|
163
|
+
event_config['description'] ||
|
164
|
+
"Custom event from #{handler_class.name}"
|
165
|
+
end
|
166
|
+
|
167
|
+
# Register event - fail fast on configuration errors
|
168
|
+
#
|
169
|
+
# @param event_name [String] Event name
|
170
|
+
# @param description [String] Event description
|
171
|
+
# @param fired_by [Array] Array of handler class names
|
172
|
+
# @param handler_class [Class] Handler class for error context
|
173
|
+
# @return [void]
|
174
|
+
# @raise [StandardError] If event registration fails (fail fast)
|
175
|
+
def safely_register_event(event_name, description, fired_by, _handler_class)
|
176
|
+
Tasker::Events::CustomRegistry.instance.register_event(
|
177
|
+
event_name,
|
178
|
+
description: description,
|
179
|
+
fired_by: fired_by
|
180
|
+
)
|
181
|
+
# Configuration errors should be visible, not silently logged
|
182
|
+
end
|
183
|
+
|
184
|
+
# Log registration failure
|
185
|
+
#
|
186
|
+
# @param event_name [String] Event name that failed
|
187
|
+
# @param handler_class [Class] Handler class
|
188
|
+
# @param error [StandardError] Error that occurred
|
189
|
+
# @return [void]
|
190
|
+
def log_registration_failure(event_name, handler_class, error)
|
191
|
+
return unless defined?(Rails)
|
192
|
+
|
193
|
+
Rails.logger.warn "Failed to register custom event #{event_name} from #{handler_class}: #{error.message}"
|
194
|
+
end
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Service class to register class-based custom events
|
199
|
+
# Reduces complexity by organizing event registration logic
|
200
|
+
class ClassBasedEventRegistrar
|
201
|
+
class << self
|
202
|
+
# Register class-based custom events from a step handler class
|
203
|
+
#
|
204
|
+
# @param handler_class [Class] The step handler class to scan for custom events
|
205
|
+
# @return [void]
|
206
|
+
def register(handler_class)
|
207
|
+
return unless has_custom_event_configuration?(handler_class)
|
208
|
+
|
209
|
+
safely_register_events(handler_class)
|
210
|
+
end
|
211
|
+
|
212
|
+
private
|
213
|
+
|
214
|
+
# Check if handler class has custom event configuration
|
215
|
+
#
|
216
|
+
# @param handler_class [Class] The step handler class
|
217
|
+
# @return [Boolean] True if class has custom event configuration
|
218
|
+
def has_custom_event_configuration?(handler_class)
|
219
|
+
handler_class.respond_to?(:custom_event_configuration)
|
220
|
+
end
|
221
|
+
|
222
|
+
# Register all custom events from handler class - fail fast on configuration errors
|
223
|
+
#
|
224
|
+
# @param handler_class [Class] The step handler class
|
225
|
+
# @return [void]
|
226
|
+
# @raise [StandardError] If custom event configuration fails (fail fast)
|
227
|
+
def safely_register_events(handler_class)
|
228
|
+
class_events = get_class_events(handler_class)
|
229
|
+
class_events.each { |event_config| register_single_event(event_config, handler_class) }
|
230
|
+
# Configuration errors should be visible, not silently logged
|
231
|
+
end
|
232
|
+
|
233
|
+
# Get custom events from handler class configuration
|
234
|
+
#
|
235
|
+
# @param handler_class [Class] The step handler class
|
236
|
+
# @return [Array] Array of event configurations
|
237
|
+
def get_class_events(handler_class)
|
238
|
+
handler_class.custom_event_configuration
|
239
|
+
end
|
240
|
+
|
241
|
+
# Register a single custom event
|
242
|
+
#
|
243
|
+
# @param event_config [Hash] The event configuration
|
244
|
+
# @param handler_class [Class] The step handler class
|
245
|
+
# @return [void]
|
246
|
+
def register_single_event(event_config, handler_class)
|
247
|
+
event_name = extract_event_name(event_config)
|
248
|
+
return unless event_name
|
249
|
+
|
250
|
+
description = extract_event_description(event_config, handler_class)
|
251
|
+
fired_by = [handler_class.name]
|
252
|
+
|
253
|
+
Tasker::Events::CustomRegistry.instance.register_event(
|
254
|
+
event_name,
|
255
|
+
description: description,
|
256
|
+
fired_by: fired_by
|
257
|
+
)
|
258
|
+
end
|
259
|
+
|
260
|
+
# Extract event name from configuration
|
261
|
+
#
|
262
|
+
# @param event_config [Hash] The event configuration
|
263
|
+
# @return [String, nil] The event name
|
264
|
+
def extract_event_name(event_config)
|
265
|
+
event_config[:name] || event_config['name']
|
266
|
+
end
|
267
|
+
|
268
|
+
# Extract event description from configuration
|
269
|
+
#
|
270
|
+
# @param event_config [Hash] The event configuration
|
271
|
+
# @param handler_class [Class] The step handler class
|
272
|
+
# @return [String] The event description
|
273
|
+
def extract_event_description(event_config, handler_class)
|
274
|
+
event_config[:description] ||
|
275
|
+
event_config['description'] ||
|
276
|
+
"Custom event from #{handler_class.name}"
|
277
|
+
end
|
278
|
+
|
279
|
+
# Log registration failure
|
280
|
+
#
|
281
|
+
# @param handler_class [Class] The step handler class
|
282
|
+
# @param error [StandardError] The error that occurred
|
283
|
+
# @return [void]
|
284
|
+
def log_registration_failure(handler_class, error)
|
285
|
+
return unless defined?(Rails)
|
286
|
+
|
287
|
+
Rails.logger.warn "Failed to register class-based custom events from #{handler_class}: #{error.message}"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
# Define step templates for a task handler
|
294
|
+
#
|
295
|
+
# @yield [StepTemplateDefiner] A block to define step templates
|
296
|
+
# @return [void]
|
297
|
+
def define_step_templates
|
298
|
+
definer = StepTemplateDefiner.new(self)
|
299
|
+
yield(definer)
|
300
|
+
definer.klass.define_method(:step_templates) do
|
301
|
+
definer.step_templates
|
302
|
+
end
|
303
|
+
definer.register_class_map
|
304
|
+
definer.klass.define_method(:step_handler_class_map) do
|
305
|
+
definer.step_handler_class_map
|
306
|
+
end
|
307
|
+
definer.klass.define_method(:step_handler_config_map) do
|
308
|
+
definer.step_handler_config_map
|
309
|
+
end
|
310
|
+
end
|
311
|
+
|
312
|
+
# Register a task handler with the handler factory
|
313
|
+
#
|
314
|
+
# @param name [String, Symbol] The name to register the handler under
|
315
|
+
# @param concurrent [Boolean] Whether to use concurrent processing
|
316
|
+
# @return [void]
|
317
|
+
def register_handler(name, namespace_name: 'default', version: '0.1.0', concurrent: true)
|
318
|
+
# Register the handler with the factory
|
319
|
+
Tasker::HandlerFactory.instance.register(name, self, namespace_name: namespace_name, version: version,
|
320
|
+
replace: true)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
324
|
+
end
|
@@ -0,0 +1,293 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'json-schema'
|
5
|
+
require 'tasker/constants'
|
6
|
+
require 'tasker/types/step_sequence'
|
7
|
+
require 'tasker/events/event_payload_builder'
|
8
|
+
require_relative '../concerns/event_publisher'
|
9
|
+
require_relative '../orchestration/workflow_coordinator'
|
10
|
+
require_relative '../analysis/template_graph_analyzer'
|
11
|
+
|
12
|
+
module Tasker
|
13
|
+
module TaskHandler
|
14
|
+
# Instance methods for task handlers
|
15
|
+
#
|
16
|
+
# Provides the core task processing logic including the main execution loop,
|
17
|
+
# step handling, and finalization. Delegates to orchestration components
|
18
|
+
# for implementation details while maintaining proven loop-based approach.
|
19
|
+
#
|
20
|
+
# @author TaskHandler Authors
|
21
|
+
module InstanceMethods
|
22
|
+
include Tasker::Concerns::EventPublisher
|
23
|
+
|
24
|
+
# List of attributes to pass from the task request to the task
|
25
|
+
#
|
26
|
+
# These are the attributes that will be copied from the task request
|
27
|
+
# to the task when initializing a new task.
|
28
|
+
#
|
29
|
+
# @return [Array<Symbol>] List of attribute names
|
30
|
+
TASK_REQUEST_ATTRIBUTES = %i[name context initiator reason source_system].freeze
|
31
|
+
|
32
|
+
# Initialize a task
|
33
|
+
#
|
34
|
+
# Validates input and creates initial workflow steps via orchestration.
|
35
|
+
#
|
36
|
+
# @param task_request [TaskRequest] The task request to initialize
|
37
|
+
# @return [Tasker::Task] The initialized task
|
38
|
+
def initialize_task!(task_request)
|
39
|
+
# Delegate to orchestration system
|
40
|
+
Tasker::Orchestration::TaskInitializer.initialize_task!(task_request, self)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Get the step sequence for a task
|
44
|
+
#
|
45
|
+
# Retrieves all workflow steps for the task and establishes their dependencies.
|
46
|
+
# Delegates to StepSequenceFactory for implementation + observability events.
|
47
|
+
#
|
48
|
+
# @param task [Tasker::Task] The task to get the sequence for
|
49
|
+
# @return [Tasker::Types::StepSequence] The sequence of workflow steps
|
50
|
+
def get_sequence(task)
|
51
|
+
# Delegate to orchestration system for implementation + events
|
52
|
+
Tasker::Orchestration::StepSequenceFactory.get_sequence(task, self)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Start a task's execution
|
56
|
+
#
|
57
|
+
# Updates the task status to IN_PROGRESS and fires the appropriate event.
|
58
|
+
#
|
59
|
+
# @param task [Tasker::Task] The task to start
|
60
|
+
# @return [Boolean] True if the task was started successfully
|
61
|
+
# @raise [Tasker::ProceduralError] If the task is already complete or not pending
|
62
|
+
def start_task(task)
|
63
|
+
# Delegate to orchestration system
|
64
|
+
Tasker::Orchestration::TaskInitializer.start_task!(task)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Handle a task's execution
|
68
|
+
#
|
69
|
+
# This is the main entry point for processing a task. Delegates to
|
70
|
+
# WorkflowCoordinator for the execution loop to enable strategy composition.
|
71
|
+
#
|
72
|
+
# @param task [Tasker::Task] The task to handle
|
73
|
+
# @return [void]
|
74
|
+
def handle(task)
|
75
|
+
start_task(task)
|
76
|
+
|
77
|
+
# DELEGATE: Use WorkflowCoordinator for execution loop
|
78
|
+
# This enables strategy pattern composition for testing
|
79
|
+
workflow_coordinator.execute_workflow(task, self)
|
80
|
+
end
|
81
|
+
|
82
|
+
# Establish step dependencies and defaults
|
83
|
+
#
|
84
|
+
# This is a hook method that can be overridden by implementing classes.
|
85
|
+
# This method is public so that orchestration components can call it.
|
86
|
+
#
|
87
|
+
# @param task [Tasker::Task] The task being processed
|
88
|
+
# @param steps [Array<Tasker::WorkflowStep>] The steps to establish dependencies for
|
89
|
+
# @return [void]
|
90
|
+
def establish_step_dependencies_and_defaults(task, steps); end
|
91
|
+
|
92
|
+
# Update annotations based on processed steps
|
93
|
+
#
|
94
|
+
# This is a hook method that can be overridden by implementing classes.
|
95
|
+
# This method is public so that orchestration components can call it.
|
96
|
+
#
|
97
|
+
# @param task [Tasker::Task] The task being processed
|
98
|
+
# @param sequence [Tasker::Types::StepSequence] The sequence of steps
|
99
|
+
# @param steps [Array<Tasker::WorkflowStep>] The processed steps
|
100
|
+
# @return [void]
|
101
|
+
def update_annotations(task, sequence, steps); end
|
102
|
+
|
103
|
+
# Get a step handler for a specific step
|
104
|
+
#
|
105
|
+
# This method is public so that orchestration components can access step handlers.
|
106
|
+
#
|
107
|
+
# @param step [Tasker::WorkflowStep] The step to get a handler for
|
108
|
+
# @return [Object] The step handler
|
109
|
+
# @raise [Tasker::ProceduralError] If no handler is registered for the step
|
110
|
+
def get_step_handler(step)
|
111
|
+
raise(Tasker::ProceduralError, "No registered class for #{step.name}") unless step_handler_class_map[step.name]
|
112
|
+
|
113
|
+
handler_config = step_handler_config_map[step.name]
|
114
|
+
handler_class = step_handler_class_map[step.name].to_s.camelize.constantize
|
115
|
+
|
116
|
+
return handler_class.new if handler_config.nil?
|
117
|
+
|
118
|
+
handler_class.new(config: handler_config)
|
119
|
+
end
|
120
|
+
|
121
|
+
# Handle execution of a single step
|
122
|
+
#
|
123
|
+
# This is a convenience method for testing that executes a single step.
|
124
|
+
# Delegates to StepExecutor for consistent behavior.
|
125
|
+
#
|
126
|
+
# @param task [Tasker::Task] The task being processed
|
127
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
128
|
+
# @param step [Tasker::WorkflowStep] The step to execute
|
129
|
+
# @return [Tasker::WorkflowStep] The processed step
|
130
|
+
def handle_one_step(task, sequence, step)
|
131
|
+
step_executor.execute_single_step(task, sequence, step, self)
|
132
|
+
end
|
133
|
+
|
134
|
+
# Get dependency graph analysis for this task handler's step templates
|
135
|
+
#
|
136
|
+
# Provides comprehensive analysis of step dependencies, including cycle detection,
|
137
|
+
# topological ordering, and dependency visualization. Useful for troubleshooting
|
138
|
+
# and understanding workflow structure.
|
139
|
+
#
|
140
|
+
# @return [Hash] Comprehensive dependency analysis containing:
|
141
|
+
# - :nodes - Array of step information with dependencies
|
142
|
+
# - :edges - Array of dependency relationships
|
143
|
+
# - :topology - Topologically sorted step names
|
144
|
+
# - :cycles - Array of detected circular dependencies
|
145
|
+
# - :levels - Hash mapping steps to their dependency depth levels
|
146
|
+
# - :roots - Array of steps with no dependencies
|
147
|
+
# - :leaves - Array of steps with no dependents
|
148
|
+
def dependency_graph
|
149
|
+
template_analyzer.analyze
|
150
|
+
end
|
151
|
+
|
152
|
+
private
|
153
|
+
|
154
|
+
# Memoized step executor for consistent reuse
|
155
|
+
#
|
156
|
+
# @return [Tasker::Orchestration::StepExecutor] The step executor instance
|
157
|
+
def step_executor
|
158
|
+
@step_executor ||= Tasker::Orchestration::StepExecutor.new
|
159
|
+
end
|
160
|
+
|
161
|
+
# Memoized task finalizer for consistent reuse
|
162
|
+
#
|
163
|
+
# @return [Tasker::Orchestration::TaskFinalizer] The task finalizer instance
|
164
|
+
def task_finalizer
|
165
|
+
@task_finalizer ||= Tasker::Orchestration::TaskFinalizer.new
|
166
|
+
end
|
167
|
+
|
168
|
+
# Memoized workflow coordinator for consistent reuse
|
169
|
+
#
|
170
|
+
# Uses strategy pattern to allow composition of different coordinators
|
171
|
+
# and reenqueuer strategies for testing vs production.
|
172
|
+
#
|
173
|
+
# @return [Tasker::Orchestration::WorkflowCoordinator] The workflow coordinator instance
|
174
|
+
def workflow_coordinator
|
175
|
+
@workflow_coordinator ||= workflow_coordinator_strategy.new(
|
176
|
+
reenqueuer_strategy: reenqueuer_strategy.new
|
177
|
+
)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Get the workflow coordinator strategy class
|
181
|
+
#
|
182
|
+
# Can be overridden for testing to inject TestWorkflowCoordinator
|
183
|
+
#
|
184
|
+
# @return [Class] The workflow coordinator strategy class
|
185
|
+
def workflow_coordinator_strategy
|
186
|
+
@workflow_coordinator_strategy || Tasker::Orchestration::WorkflowCoordinator
|
187
|
+
end
|
188
|
+
|
189
|
+
public
|
190
|
+
|
191
|
+
# Set the workflow coordinator strategy (for testing)
|
192
|
+
#
|
193
|
+
# @param strategy [Class] The workflow coordinator strategy class
|
194
|
+
def workflow_coordinator_strategy=(strategy)
|
195
|
+
@workflow_coordinator_strategy = strategy
|
196
|
+
@workflow_coordinator = nil # Reset memoized instance
|
197
|
+
end
|
198
|
+
|
199
|
+
# Set the reenqueuer strategy (for testing)
|
200
|
+
#
|
201
|
+
# @param strategy [Class] The reenqueuer strategy class
|
202
|
+
def reenqueuer_strategy=(strategy)
|
203
|
+
@reenqueuer_strategy = strategy
|
204
|
+
@workflow_coordinator = nil # Reset memoized instance
|
205
|
+
end
|
206
|
+
|
207
|
+
private
|
208
|
+
|
209
|
+
# Get the reenqueuer strategy class
|
210
|
+
#
|
211
|
+
# Can be overridden for testing to inject TestReenqueuer
|
212
|
+
#
|
213
|
+
# @return [Class] The reenqueuer strategy class
|
214
|
+
def reenqueuer_strategy
|
215
|
+
@reenqueuer_strategy || Tasker::Orchestration::TaskReenqueuer
|
216
|
+
end
|
217
|
+
|
218
|
+
# Find steps that are ready for execution
|
219
|
+
#
|
220
|
+
# This method finds workflow steps that are ready to be executed by checking
|
221
|
+
# their state and dependencies. It's a proven pattern that works reliably.
|
222
|
+
#
|
223
|
+
# @param task [Tasker::Task] The task being processed
|
224
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
225
|
+
# @return [Array<Tasker::WorkflowStep>] Steps ready for execution
|
226
|
+
def find_viable_steps(task, sequence)
|
227
|
+
Orchestration::ViableStepDiscovery.new.find_viable_steps(task, sequence)
|
228
|
+
end
|
229
|
+
|
230
|
+
# Handle execution of viable steps
|
231
|
+
#
|
232
|
+
# This method executes a collection of viable steps, delegating to the
|
233
|
+
# StepExecutor for implementation details.
|
234
|
+
#
|
235
|
+
# @param task [Tasker::Task] The task being processed
|
236
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
237
|
+
# @param viable_steps [Array<Tasker::WorkflowStep>] Steps ready for execution
|
238
|
+
# @return [Array<Tasker::WorkflowStep>] Processed steps
|
239
|
+
def handle_viable_steps(task, sequence, viable_steps)
|
240
|
+
step_executor.execute_steps(task, sequence, viable_steps, self)
|
241
|
+
end
|
242
|
+
|
243
|
+
# Check if task is blocked by errors
|
244
|
+
#
|
245
|
+
# @param task [Tasker::Task] The task to check
|
246
|
+
# @param sequence [Tasker::Types::StepSequence] The step sequence
|
247
|
+
# @param processed_steps [Array<Tasker::WorkflowStep>] Recently processed steps
|
248
|
+
# @return [Boolean] True if blocked by errors
|
249
|
+
def blocked_by_errors?(task, sequence, processed_steps)
|
250
|
+
task_finalizer.blocked_by_errors?(task, sequence, processed_steps)
|
251
|
+
end
|
252
|
+
|
253
|
+
# Finalize the task
|
254
|
+
#
|
255
|
+
# @param task [Tasker::Task] The task to finalize
|
256
|
+
# @param sequence [Tasker::Types::StepSequence] The final step sequence
|
257
|
+
# @param processed_steps [Array<Tasker::WorkflowStep>] All processed steps
|
258
|
+
def finalize(task, sequence, processed_steps)
|
259
|
+
# Call update_annotations hook before finalizing
|
260
|
+
update_annotations(task, sequence, processed_steps) if respond_to?(:update_annotations)
|
261
|
+
|
262
|
+
task_finalizer.finalize_task_with_steps(task, sequence, processed_steps)
|
263
|
+
end
|
264
|
+
|
265
|
+
# Get the schema for validating task context
|
266
|
+
#
|
267
|
+
# This is a hook method that can be overridden by implementing classes.
|
268
|
+
#
|
269
|
+
# @return [Hash, nil] The JSON schema for task context validation
|
270
|
+
def schema
|
271
|
+
nil
|
272
|
+
end
|
273
|
+
|
274
|
+
# Validate a task context against the schema
|
275
|
+
#
|
276
|
+
# @param context [Hash] The context to validate
|
277
|
+
# @return [Array<String>] Validation errors, if any
|
278
|
+
def validate_context(context)
|
279
|
+
return [] unless schema
|
280
|
+
|
281
|
+
data = context.to_hash.deep_symbolize_keys
|
282
|
+
JSON::Validator.fully_validate(schema, data, strict: true, insert_defaults: true)
|
283
|
+
end
|
284
|
+
|
285
|
+
# Get the template graph analyzer for this handler
|
286
|
+
#
|
287
|
+
# @return [Tasker::Analysis::TemplateGraphAnalyzer] The template analyzer
|
288
|
+
def template_analyzer
|
289
|
+
@template_analyzer ||= Tasker::Analysis::TemplateGraphAnalyzer.new(step_templates)
|
290
|
+
end
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|