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,182 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ module Tasker
5
+ module TaskHandler
6
+ # Manages and analyzes groups of workflow steps
7
+ #
8
+ # StepGroup is used to track the status of steps in a workflow and determine
9
+ # whether a task is complete, can be finalized, or needs further processing.
10
+ # It traverses the step dependency graph to find incomplete steps.
11
+ class StepGroup
12
+ # @return [Array<Tasker::WorkflowStep>] Steps that were incomplete before this processing pass
13
+ attr_accessor :prior_incomplete_steps
14
+
15
+ # @return [Array<Tasker::WorkflowStep>] Steps that were completed in this processing pass
16
+ attr_accessor :this_pass_complete_steps
17
+
18
+ # @return [Array<Tasker::WorkflowStep>] Steps that are still incomplete after this pass
19
+ attr_accessor :still_incomplete_steps
20
+
21
+ # @return [Array<Tasker::WorkflowStep>] Steps that are still in a working state (pending/in progress)
22
+ attr_accessor :still_working_steps
23
+
24
+ # @return [Array<Integer>] IDs of steps completed in this processing pass
25
+ attr_accessor :this_pass_complete_step_ids
26
+
27
+ # Build a StepGroup for the given task, sequence and steps
28
+ #
29
+ # @param task [Tasker::Task] The task being processed
30
+ # @param sequence [Tasker::Types::StepSequence] The sequence of steps
31
+ # @param steps [Array<Tasker::WorkflowStep>] The steps processed in the current pass
32
+ # @return [StepGroup] A fully built step group
33
+ def self.build(task, sequence, steps)
34
+ inst = new(task, sequence, steps)
35
+ inst.build
36
+ inst
37
+ end
38
+
39
+ # Initialize a new StepGroup
40
+ #
41
+ # @param task [Tasker::Task] The task being processed
42
+ # @param sequence [Tasker::Types::StepSequence] The sequence of steps
43
+ # @param steps [Array<Tasker::WorkflowStep>] The steps processed in the current pass
44
+ # @return [StepGroup] A new step group instance
45
+ def initialize(task, sequence, steps)
46
+ @task = task
47
+ @sequence = sequence
48
+ @steps = steps
49
+ end
50
+
51
+ # Build the step group by analyzing all step collections
52
+ #
53
+ # @return [void]
54
+ def build
55
+ build_prior_incomplete_steps
56
+ build_this_pass_complete_steps
57
+ build_still_incomplete_steps
58
+ build_still_working_steps
59
+ end
60
+
61
+ # Find all steps that were incomplete prior to this processing pass
62
+ #
63
+ # @return [void]
64
+ def build_prior_incomplete_steps
65
+ # determine which states were incomplete by traversing the entire DAG
66
+ self.prior_incomplete_steps = []
67
+
68
+ # Find all root steps (those without parents)
69
+ root_steps = @sequence.steps.select { |step| step.parents.empty? }
70
+
71
+ # Recursively traverse the DAG to find all incomplete steps
72
+ find_incomplete_steps(root_steps, [])
73
+ end
74
+
75
+ # Recursively traverse the DAG to find all incomplete steps
76
+ #
77
+ # @param steps [Array<Tasker::WorkflowStep>] Steps to check
78
+ # @param visited_step_ids [Array<Integer>] IDs of steps already visited
79
+ # @return [void]
80
+ def find_incomplete_steps(steps, visited_step_ids)
81
+ steps.each do |step|
82
+ # Skip if we've already visited this step (avoid cycles, though they shouldn't exist in a DAG)
83
+ next if visited_step_ids.include?(step.workflow_step_id)
84
+
85
+ # Add this step to visited
86
+ visited_step_ids << step.workflow_step_id
87
+
88
+ # Add to prior_incomplete_steps if this step is incomplete
89
+ prior_incomplete_steps << step if Tasker::Constants::VALID_STEP_COMPLETION_STATES.exclude?(step.status)
90
+
91
+ # Recursively check all children
92
+ find_incomplete_steps(step.children, visited_step_ids)
93
+ end
94
+ end
95
+
96
+ # Find steps that were completed in this processing pass
97
+ #
98
+ # @return [void]
99
+ def build_this_pass_complete_steps
100
+ # The steps passed into finalize are those processed in this pass
101
+ # Check which ones completed in a valid state
102
+ self.this_pass_complete_steps = []
103
+ @steps.each do |step|
104
+ this_pass_complete_steps << step if Tasker::Constants::VALID_STEP_COMPLETION_STATES.include?(step.status)
105
+ end
106
+ self.this_pass_complete_step_ids = this_pass_complete_steps.map(&:workflow_step_id)
107
+ end
108
+
109
+ # Find steps that are still incomplete after this processing pass
110
+ #
111
+ # @return [void]
112
+ def build_still_incomplete_steps
113
+ # What was incomplete from the prior DAG traversal that is still incomplete now
114
+ self.still_incomplete_steps = []
115
+ prior_incomplete_steps.each do |step|
116
+ still_incomplete_steps << step if this_pass_complete_step_ids.exclude?(step.workflow_step_id)
117
+ end
118
+ end
119
+
120
+ # Find steps that are still in a working state (pending/in progress)
121
+ #
122
+ # @return [void]
123
+ def build_still_working_steps
124
+ # What is still working from the incomplete steps but in a valid, retryable state
125
+ self.still_working_steps = []
126
+ still_incomplete_steps.each do |step|
127
+ still_working_steps << step if Tasker::Constants::VALID_STEP_STILL_WORKING_STATES.include?(step.status)
128
+ end
129
+ end
130
+
131
+ # Check if the task can be considered complete
132
+ #
133
+ # A task is complete if there were no incomplete steps in the prior iteration
134
+ # or if all previously incomplete steps are now complete.
135
+ #
136
+ # @return [Boolean] True if the task is complete
137
+ def complete?
138
+ prior_incomplete_steps.empty? || still_incomplete_steps.empty?
139
+ end
140
+
141
+ # Check if the task should be marked as pending for further processing
142
+ #
143
+ # A task is considered pending if there are still steps in a working state.
144
+ #
145
+ # @return [Boolean] True if the task should be pending
146
+ def pending?
147
+ still_working_steps.length.positive?
148
+ end
149
+
150
+ # Check if the task has any steps in error states
151
+ #
152
+ # A task has errors if any steps are in terminal error states that can't be retried.
153
+ #
154
+ # @return [Boolean] True if the task has error steps
155
+ def error?
156
+ # Use efficient database query with existing failed scope
157
+ step_ids = @sequence.steps.map(&:workflow_step_id)
158
+ return false if step_ids.empty?
159
+
160
+ # Query for any steps in error state using the failed scope
161
+ Tasker::WorkflowStep.failed.exists?(workflow_step_id: step_ids)
162
+ end
163
+
164
+ # Get debugging state information for the step group
165
+ #
166
+ # @return [Hash] Debug information about the step group state
167
+ def debug_state
168
+ {
169
+ total_steps: @sequence.steps.size,
170
+ prior_incomplete_count: prior_incomplete_steps.size,
171
+ complete_this_pass_count: this_pass_complete_steps.size,
172
+ still_incomplete_count: still_incomplete_steps.size,
173
+ still_working_count: still_working_steps.size,
174
+ step_statuses: @sequence.steps.map { |s| { id: s.workflow_step_id, name: s.name, status: s.status } },
175
+ is_complete: complete?,
176
+ is_pending: pending?,
177
+ has_errors: error?
178
+ }
179
+ end
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,43 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require 'json-schema'
5
+ require 'concurrent'
6
+ require_relative 'task_handler/class_methods'
7
+ require_relative 'task_handler/instance_methods'
8
+ require_relative 'task_handler/step_group'
9
+ require_relative 'task_builder'
10
+
11
+ module Tasker
12
+ # Main module for task handler functionality
13
+ #
14
+ # TaskHandler provides the core functionality for defining and executing
15
+ # workflows. When included in a class, it adds methods for:
16
+ #
17
+ # - Defining step templates with dependencies and configurations
18
+ # - Initializing and running tasks with proper error handling
19
+ # - Processing steps in sequence or concurrently
20
+ # - Managing retries and error recovery
21
+ #
22
+ # @example Creating a basic task handler
23
+ # class MyTaskHandler
24
+ # include Tasker::TaskHandler
25
+ #
26
+ # define_step_templates do |definer|
27
+ # definer.define(
28
+ # name: 'first_step',
29
+ # handler_class: SomeStepHandler
30
+ # )
31
+ # end
32
+ # end
33
+ module TaskHandler
34
+ # When included, extends the class with ClassMethods and includes InstanceMethods
35
+ #
36
+ # @param base [Class] The class including this module
37
+ # @return [void]
38
+ def self.included(base)
39
+ base.extend(ClassMethods)
40
+ base.include(InstanceMethods)
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,126 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ module Telemetry
5
+ # EventMapping represents a single event→telemetry routing configuration
6
+ #
7
+ # This class defines how a specific event should be routed to telemetry backends.
8
+ # It uses dry-struct for immutability and type safety, following the established
9
+ # pattern from Tasker::Types configuration classes.
10
+ #
11
+ # @example Basic event mapping
12
+ # mapping = EventMapping.new(
13
+ # event_name: 'task.completed',
14
+ # backends: [:trace, :metrics],
15
+ # enabled: true
16
+ # )
17
+ #
18
+ # @example Metrics-only mapping for operational data
19
+ # mapping = EventMapping.new(
20
+ # event_name: 'observability.task.enqueue',
21
+ # backends: [:metrics],
22
+ # sampling_rate: 1.0
23
+ # )
24
+ #
25
+ # @example Trace-only mapping for debugging
26
+ # mapping = EventMapping.new(
27
+ # event_name: 'step.before_handle',
28
+ # backends: [:trace],
29
+ # sampling_rate: 0.1 # Sample 10% for performance
30
+ # )
31
+ class EventMapping < Tasker::Types::BaseConfig
32
+ transform_keys(&:to_sym)
33
+
34
+ # The event name to route
35
+ #
36
+ # @!attribute [r] event_name
37
+ # @return [String] Event name in dot notation (e.g., 'task.completed')
38
+ attribute :event_name, Tasker::Types::String
39
+
40
+ # Which telemetry backends should receive this event
41
+ #
42
+ # @!attribute [r] backends
43
+ # @return [Array<Symbol>] List of backend types (:trace, :metrics, :logs)
44
+ attribute :backends, Tasker::Types::Array.of(Tasker::Types::Symbol).default([:trace].freeze)
45
+
46
+ # Override initialize to ensure backends array is frozen
47
+ def initialize(*)
48
+ super
49
+ backends.freeze
50
+ # Don't freeze here - BaseConfig already freezes the object
51
+ end
52
+
53
+ # Whether this mapping is currently enabled
54
+ #
55
+ # @!attribute [r] enabled
56
+ # @return [Boolean] True if this mapping should be processed
57
+ attribute :enabled, Tasker::Types::Bool.default(true)
58
+
59
+ # Sampling rate for this event (0.0 to 1.0)
60
+ #
61
+ # @!attribute [r] sampling_rate
62
+ # @return [Float] Sampling rate (1.0 = 100%, 0.1 = 10%)
63
+ attribute :sampling_rate, Tasker::Types::Float.default(1.0)
64
+
65
+ # Priority level for this event mapping
66
+ #
67
+ # @!attribute [r] priority
68
+ # @return [Symbol] Priority level (:low, :normal, :high, :critical)
69
+ attribute :priority, Tasker::Types::Symbol.default(:normal)
70
+
71
+ # Additional metadata for this mapping
72
+ #
73
+ # @!attribute [r] metadata
74
+ # @return [Hash] Additional configuration data
75
+ attribute :metadata, Tasker::Types::Hash.default({}.freeze)
76
+
77
+ # Check if this mapping routes to traces
78
+ #
79
+ # @return [Boolean] True if backends includes :trace
80
+ def routes_to_traces?
81
+ backends.include?(:trace)
82
+ end
83
+
84
+ # Check if this mapping routes to metrics
85
+ #
86
+ # @return [Boolean] True if backends includes :metrics
87
+ def routes_to_metrics?
88
+ backends.include?(:metrics)
89
+ end
90
+
91
+ # Check if this mapping routes to logs
92
+ #
93
+ # @return [Boolean] True if backends includes :logs
94
+ def routes_to_logs?
95
+ backends.include?(:logs)
96
+ end
97
+
98
+ # Check if this event should be sampled
99
+ #
100
+ # Uses a simple random sampling approach. For production, you might want
101
+ # to implement more sophisticated sampling strategies.
102
+ #
103
+ # @return [Boolean] True if this event should be processed
104
+ def should_sample?
105
+ return true if sampling_rate >= 1.0
106
+ return false if sampling_rate <= 0.0
107
+
108
+ Random.rand <= sampling_rate
109
+ end
110
+
111
+ # Check if this mapping is active (enabled and should be sampled)
112
+ #
113
+ # @return [Boolean] True if this mapping should be processed
114
+ def active?
115
+ enabled && should_sample?
116
+ end
117
+
118
+ # Get a description of this mapping for debugging
119
+ #
120
+ # @return [String] Human-readable description
121
+ def description
122
+ "#{event_name} → #{backends.join(', ')} (#{(sampling_rate * 100).round(1)}% sampled)"
123
+ end
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,318 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'metrics_backend'
4
+
5
+ module Tasker
6
+ module Telemetry
7
+ # EventRouter provides intelligent routing of events to appropriate telemetry backends
8
+ #
9
+ # This is the strategic core of Phase 4.2.1, enabling declarative event→telemetry mapping
10
+ # while preserving all existing TelemetrySubscriber functionality. It follows the singleton
11
+ # pattern established by HandlerFactory and Events::Publisher.
12
+ #
13
+ # Core Philosophy: PRESERVE all existing 8 TelemetrySubscriber events while adding
14
+ # intelligent routing for 35+ additional lifecycle events.
15
+ #
16
+ # @example Basic configuration
17
+ # Tasker::Telemetry::EventRouter.configure do |router|
18
+ # # PRESERVE: All current 8 events → both traces AND metrics
19
+ # router.map 'task.completed' => [:trace, :metrics]
20
+ # router.map 'step.failed' => [:trace, :metrics]
21
+ #
22
+ # # ENHANCE: Add missing lifecycle events with intelligent routing
23
+ # router.map 'workflow.viable_steps_discovered' => [:trace, :metrics]
24
+ # router.map 'observability.task.enqueue' => [:metrics] # Job queue metrics only
25
+ # router.map 'step.before_handle' => [:trace] # Handler execution spans
26
+ # end
27
+ #
28
+ # @example Production sampling configuration
29
+ # router.map 'step.before_handle' => [:trace], sampling_rate: 0.1 # 10% sampling
30
+ # router.map 'database.query_executed' => [:trace, :metrics], priority: :high
31
+ #
32
+ class EventRouter
33
+ include Singleton
34
+
35
+ # @return [Hash<String, EventMapping>] Registry of event mappings by event name
36
+ attr_reader :mappings
37
+
38
+ # @return [Array<String>] List of events that route to traces
39
+ attr_reader :trace_events
40
+
41
+ # @return [Array<String>] List of events that route to metrics
42
+ attr_reader :metrics_events
43
+
44
+ # @return [Array<String>] List of events that route to logs
45
+ attr_reader :log_events
46
+
47
+ # Initialize the event router with default mappings
48
+ def initialize
49
+ @mappings = {}
50
+ @trace_events = []
51
+ @metrics_events = []
52
+ @log_events = []
53
+
54
+ # Load default mappings that preserve existing TelemetrySubscriber functionality
55
+ load_default_mappings
56
+
57
+ # Register this router with MetricsBackend for automatic routing
58
+ MetricsBackend.instance.register_event_router(self)
59
+ end
60
+
61
+ # Configure event routing with a block
62
+ #
63
+ # @yield [EventRouter] The router instance for configuration
64
+ # @return [EventRouter] The configured router instance
65
+ def self.configure
66
+ instance.tap { |router| yield(router) if block_given? }
67
+ end
68
+
69
+ # Map an event to specific telemetry backends
70
+ #
71
+ # @param event_name [String, Hash] Event name in dot notation, or hash with event => backends
72
+ # @param backends [Array<Symbol>] List of backend types (:trace, :metrics, :logs)
73
+ # @param options [Hash] Additional mapping options
74
+ # @option options [Boolean] :enabled Whether this mapping is enabled
75
+ # @option options [Float] :sampling_rate Sampling rate (0.0 to 1.0)
76
+ # @option options [Symbol] :priority Priority level (:low, :normal, :high, :critical)
77
+ # @option options [Hash] :metadata Additional metadata
78
+ # @return [EventMapping] The created mapping
79
+ def map(event_name_or_hash, backends: [:trace], **)
80
+ # Handle hash syntax: map 'event' => [:trace, :metrics]
81
+ if event_name_or_hash.is_a?(Hash)
82
+ # Extract the first (and typically only) hash pair
83
+ event_name, extracted_backends = event_name_or_hash.first
84
+ backends = Array(extracted_backends)
85
+ else
86
+ event_name = event_name_or_hash
87
+ end
88
+
89
+ # Ensure we always have an event_name
90
+ raise ArgumentError, 'event_name cannot be nil' if event_name.nil?
91
+
92
+ mapping = EventMapping.new(
93
+ event_name: event_name.to_s,
94
+ backends: Array(backends),
95
+ **
96
+ )
97
+
98
+ register_mapping(mapping)
99
+ mapping
100
+ end
101
+
102
+ # Get the mapping for a specific event
103
+ #
104
+ # @param event_name [String] Event name
105
+ # @return [EventMapping, nil] The mapping or nil if not found
106
+ def mapping_for(event_name)
107
+ mappings[event_name.to_s]
108
+ end
109
+
110
+ # Check if a mapping exists for a specific event
111
+ #
112
+ # @param event_name [String] Event name
113
+ # @return [Boolean] True if mapping exists
114
+ def mapping_exists?(event_name)
115
+ mappings.key?(event_name.to_s)
116
+ end
117
+
118
+ # Check if an event routes to traces
119
+ #
120
+ # @param event_name [String] Event name
121
+ # @return [Boolean] True if the event routes to traces
122
+ def routes_to_traces?(event_name)
123
+ mapping = mapping_for(event_name)
124
+ return false unless mapping
125
+
126
+ mapping.active? && mapping.routes_to_traces?
127
+ end
128
+
129
+ # Check if an event routes to metrics
130
+ #
131
+ # @param event_name [String] Event name
132
+ # @return [Boolean] True if the event routes to metrics
133
+ def routes_to_metrics?(event_name)
134
+ mapping = mapping_for(event_name)
135
+ return false unless mapping
136
+
137
+ mapping.active? && mapping.routes_to_metrics?
138
+ end
139
+
140
+ # Check if an event routes to logs
141
+ #
142
+ # @param event_name [String] Event name
143
+ # @return [Boolean] True if the event routes to logs
144
+ def routes_to_logs?(event_name)
145
+ mapping = mapping_for(event_name)
146
+ return false unless mapping
147
+
148
+ mapping.active? && mapping.routes_to_logs?
149
+ end
150
+
151
+ # Get all events that should route to a specific backend
152
+ #
153
+ # @param backend [Symbol] Backend type (:trace, :metrics, :logs)
154
+ # @return [Array<String>] List of event names
155
+ # @raise [ArgumentError] If backend type is not recognized
156
+ def events_for_backend(backend)
157
+ case backend
158
+ when :trace, :traces
159
+ trace_events
160
+ when :metric, :metrics
161
+ metrics_events
162
+ when :log, :logs
163
+ log_events
164
+ else
165
+ raise ArgumentError, "Unknown backend type: #{backend.inspect}. Valid backends: :trace, :metrics, :logs"
166
+ end
167
+ end
168
+
169
+ # Get routing statistics for debugging
170
+ #
171
+ # @return [Hash] Statistics about current routing configuration
172
+ def routing_stats
173
+ {
174
+ total_mappings: mappings.size,
175
+ trace_events: trace_events.size,
176
+ metrics_events: metrics_events.size,
177
+ log_events: log_events.size,
178
+ enabled_mappings: mappings.values.count(&:enabled),
179
+ high_priority: mappings.values.count { |m| m.priority == :high },
180
+ sampled_mappings: mappings.values.count { |m| m.sampling_rate < 1.0 }
181
+ }
182
+ end
183
+
184
+ # Reset all mappings (primarily for testing)
185
+ #
186
+ # @return [void]
187
+ def reset!
188
+ @mappings.clear
189
+ @trace_events.clear
190
+ @metrics_events.clear
191
+ @log_events.clear
192
+ load_default_mappings
193
+ end
194
+
195
+ # Get a list of all configured event names
196
+ #
197
+ # @return [Array<String>] All configured event names
198
+ def configured_events
199
+ mappings.keys
200
+ end
201
+
202
+ # Route an event to appropriate backends based on configuration
203
+ #
204
+ # This is the core routing method that directs events to traces,
205
+ # metrics, and logs based on their configured mapping.
206
+ #
207
+ # @param event_name [String] The lifecycle event name
208
+ # @param payload [Hash] Event payload data
209
+ # @return [Hash] Results from each backend (backend => success boolean)
210
+ def route_event(event_name, payload = {})
211
+ results = {}
212
+ mapping = mapping_for(event_name)
213
+ return results unless mapping&.active?
214
+
215
+ # Route to metrics backend if configured
216
+ results[:metrics] = MetricsBackend.instance.handle_event(event_name, payload) if mapping.routes_to_metrics?
217
+
218
+ # Route to trace backend if configured
219
+ results[:traces] = TraceBackend.instance.handle_event(event_name, payload) if mapping.routes_to_traces?
220
+
221
+ # Route to log backend if configured
222
+ results[:logs] = LogBackend.instance.handle_event(event_name, payload) if mapping.routes_to_logs?
223
+
224
+ results
225
+ end
226
+
227
+ # Bulk configure multiple mappings
228
+ #
229
+ # @param mappings_config [Hash] Hash of event_name => backend_config
230
+ # @return [Array<EventMapping>] Array of created mappings
231
+ # @raise [ArgumentError] If any mapping configuration is invalid
232
+ def bulk_configure(mappings_config)
233
+ return [] if mappings_config.blank?
234
+
235
+ mappings_config.map do |event_name, config|
236
+ if config.is_a?(Array)
237
+ map(event_name, backends: config)
238
+ elsif config.is_a?(Hash)
239
+ map(event_name, **config)
240
+ elsif config.respond_to?(:to_sym)
241
+ map(event_name, backends: [config])
242
+ else
243
+ raise ArgumentError, "Invalid config for #{event_name}: #{config.inspect}. Must be Array, Hash, or Symbol"
244
+ end
245
+ end
246
+ end
247
+
248
+ private
249
+
250
+ # Register a mapping and update the backend event lists
251
+ #
252
+ # @param mapping [EventMapping] The mapping to register
253
+ # @return [void]
254
+ def register_mapping(mapping)
255
+ @mappings[mapping.event_name] = mapping
256
+
257
+ # Update backend-specific event lists
258
+ @trace_events << mapping.event_name if mapping.routes_to_traces? && @trace_events.exclude?(mapping.event_name)
259
+
260
+ if mapping.routes_to_metrics? && @metrics_events.exclude?(mapping.event_name)
261
+ @metrics_events << mapping.event_name
262
+ end
263
+
264
+ return unless mapping.routes_to_logs?
265
+
266
+ @log_events << mapping.event_name unless @log_events.include?(mapping.event_name)
267
+ end
268
+
269
+ # Load default mappings that preserve existing TelemetrySubscriber functionality
270
+ #
271
+ # This ensures ZERO BREAKING CHANGES by mapping all current 8 events to both
272
+ # traces and metrics, exactly as they currently work in production.
273
+ #
274
+ # @return [void]
275
+ def load_default_mappings
276
+ # PRESERVE: All current 8 TelemetrySubscriber events → both traces AND metrics
277
+ # This ensures zero breaking changes while enabling intelligent routing
278
+
279
+ # Task Events (4 current events)
280
+ map('task.initialize_requested', backends: %i[trace metrics])
281
+ map('task.start_requested', backends: %i[trace metrics])
282
+ map('task.completed', backends: %i[trace metrics])
283
+ map('task.failed', backends: %i[trace metrics])
284
+
285
+ # Step Events (4 current events)
286
+ map('step.execution_requested', backends: %i[trace metrics])
287
+ map('step.completed', backends: %i[trace metrics])
288
+ map('step.failed', backends: %i[trace metrics])
289
+ map('step.retry_requested', backends: %i[trace metrics])
290
+
291
+ # ENHANCE: Add missing lifecycle events with intelligent routing
292
+ # These are NEW events that weren't covered by the original TelemetrySubscriber
293
+
294
+ # Workflow Orchestration Events
295
+ map('workflow.viable_steps_discovered', backends: %i[trace metrics])
296
+
297
+ # Observability Events - Job Queue Metrics
298
+ map('observability.task.enqueue', backends: [:metrics], priority: :high)
299
+ map('observability.task.finalize', backends: [:trace])
300
+ map('observability.step.backoff', backends: %i[trace metrics])
301
+ map('observability.step.find_viable', backends: [:trace])
302
+ map('observability.step.handle', backends: [:trace])
303
+ map('observability.step.skip', backends: %i[trace metrics])
304
+ map('observability.step.max_retries_reached', backends: %i[trace metrics], priority: :high)
305
+
306
+ # Handler Execution Events
307
+ map('step.before_handle', backends: [:trace], sampling_rate: 1.0)
308
+
309
+ # Future events (for Phase 4.2.3 expansion)
310
+ map('database.query_executed', backends: %i[trace metrics], sampling_rate: 0.1)
311
+ map('dependency.resolved', backends: [:trace])
312
+ map('batch.step_execution', backends: %i[trace metrics])
313
+ map('memory.spike_detected', backends: [:metrics], priority: :critical)
314
+ map('performance.slow_operation', backends: %i[trace metrics], priority: :high)
315
+ end
316
+ end
317
+ end
318
+ end