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