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,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