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,82 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # == Schema Information
5
+ #
6
+ # Table name: named_tasks_named_steps
7
+ #
8
+ # id :integer not null, primary key
9
+ # default_retry_limit :integer default(3), not null
10
+ # default_retryable :boolean default(TRUE), not null
11
+ # skippable :boolean default(FALSE), not null
12
+ # created_at :datetime not null
13
+ # updated_at :datetime not null
14
+ # named_step_id :integer not null
15
+ # named_task_id :integer not null
16
+ #
17
+ # Indexes
18
+ #
19
+ # named_tasks_named_steps_named_step_id_index (named_step_id)
20
+ # named_tasks_named_steps_named_task_id_index (named_task_id)
21
+ # named_tasks_steps_ids_unique (named_task_id,named_step_id) UNIQUE
22
+ #
23
+ # Foreign Keys
24
+ #
25
+ # named_tasks_named_steps_named_step_id_foreign (named_step_id => named_steps.named_step_id)
26
+ # named_tasks_named_steps_named_task_id_foreign (named_task_id => named_tasks.named_task_id)
27
+ #
28
+ module Tasker
29
+ class NamedTasksNamedStep < ApplicationRecord
30
+ belongs_to :named_task
31
+ belongs_to :named_step
32
+ validates :named_task_id, uniqueness: { scope: :named_step_id }
33
+ validates :named_step_id, uniqueness: { scope: :named_task_id }
34
+
35
+ scope :named_steps_for_named_task, lambda { |named_task_id|
36
+ where(named_task_id: named_task_id).includes(:named_task).includes(:named_step)
37
+ }
38
+
39
+ def self.find_or_create(
40
+ named_task,
41
+ named_step,
42
+ options = {
43
+ default_retry_limit: 3,
44
+ default_retryable: true,
45
+ skippable: false
46
+ }
47
+ )
48
+ inst = where(named_task_id: named_task.named_task_id, named_step_id: named_step.named_step_id).first
49
+
50
+ inst ||= create({ named_task_id: named_task.named_task_id,
51
+ named_step_id: named_step.named_step_id }.merge(options))
52
+
53
+ inst
54
+ end
55
+
56
+ def self.associate_named_step_with_named_task(named_task, template, named_step)
57
+ ntns = named_steps_for_named_task(named_task.named_task_id).where(named_step: { name: named_step.name }).first
58
+ return ntns if ntns
59
+
60
+ dependent_system = Tasker::DependentSystem.find_or_create_by!(name: template.dependent_system)
61
+ named_step = Tasker::NamedStep.find_or_create_by!(name: template.name,
62
+ dependent_system_id: dependent_system.dependent_system_id)
63
+ find_or_create(
64
+ named_task,
65
+ named_step,
66
+ {
67
+ default_retry_limit: template.default_retry_limit,
68
+ default_retryable: template.default_retryable,
69
+ skippable: template.skippable
70
+ }
71
+ )
72
+ end
73
+
74
+ def task_name
75
+ named_task.name
76
+ end
77
+
78
+ def step_name
79
+ named_step.name
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,65 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ class StepDagRelationship < ApplicationRecord
5
+ self.table_name = 'tasker_step_dag_relationships'
6
+ self.primary_key = 'workflow_step_id'
7
+
8
+ # Read-only model backed by database view
9
+ def readonly?
10
+ true
11
+ end
12
+
13
+ # Associations to actual models for additional data
14
+ belongs_to :workflow_step
15
+ belongs_to :task
16
+
17
+ # Scopes for common DAG queries
18
+ scope :for_task, ->(task_id) { where(task_id: task_id) }
19
+ scope :root_steps, -> { where(is_root_step: true) }
20
+ scope :leaf_steps, -> { where(is_leaf_step: true) }
21
+ scope :with_parents, -> { where('parent_count > 0') }
22
+ scope :with_children, -> { where('child_count > 0') }
23
+
24
+ # Efficient siblings scope leveraging existing WorkflowStepEdge logic
25
+ # Uses the sophisticated sibling_sql that finds steps with exactly the same parent set
26
+ scope :siblings_of, lambda { |workflow_step_id|
27
+ # Get sibling step IDs using the existing, well-tested WorkflowStepEdge logic
28
+ sibling_edges = WorkflowStepEdge.siblings_of(WorkflowStep.find(workflow_step_id))
29
+ sibling_step_ids = sibling_edges.pluck(:to_step_id).uniq
30
+
31
+ # Return StepDagRelationship records for these siblings
32
+ where(workflow_step_id: sibling_step_ids)
33
+ }
34
+
35
+ # Helper methods for DAG navigation
36
+ def root_step?
37
+ is_root_step
38
+ end
39
+
40
+ def leaf_step?
41
+ is_leaf_step
42
+ end
43
+
44
+ def has_parents?
45
+ parent_count.positive?
46
+ end
47
+
48
+ def has_children?
49
+ child_count.positive?
50
+ end
51
+
52
+ # Parse JSONB arrays for relationship access
53
+ def parent_step_ids_array
54
+ return [] if parent_step_ids.blank?
55
+
56
+ parent_step_ids.is_a?(Array) ? parent_step_ids : JSON.parse(parent_step_ids)
57
+ end
58
+
59
+ def child_step_ids_array
60
+ return [] if child_step_ids.blank?
61
+
62
+ child_step_ids.is_a?(Array) ? child_step_ids : JSON.parse(child_step_ids)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Tasker
4
+ # StepReadinessStatus now uses SQL functions for high-performance queries
5
+ # This class explicitly delegates to the function-based implementation for better maintainability
6
+ class StepReadinessStatus
7
+ # Explicit delegation of class methods to function-based implementation
8
+ def self.for_task(task_id, step_ids = nil)
9
+ Tasker::Functions::FunctionBasedStepReadinessStatus.for_task(task_id, step_ids)
10
+ end
11
+
12
+ def self.for_steps(task_id, step_ids)
13
+ Tasker::Functions::FunctionBasedStepReadinessStatus.for_steps(task_id, step_ids)
14
+ end
15
+
16
+ def self.for_tasks(task_ids)
17
+ Tasker::Functions::FunctionBasedStepReadinessStatus.for_tasks(task_ids)
18
+ end
19
+
20
+ # Task-scoped methods that require task_id parameter
21
+ def self.ready_for_task(task_id)
22
+ Tasker::Functions::FunctionBasedStepReadinessStatus.ready_for_task(task_id)
23
+ end
24
+
25
+ def self.blocked_by_dependencies_for_task(task_id)
26
+ Tasker::Functions::FunctionBasedStepReadinessStatus.blocked_by_dependencies_for_task(task_id)
27
+ end
28
+
29
+ def self.blocked_by_retry_for_task(task_id)
30
+ Tasker::Functions::FunctionBasedStepReadinessStatus.blocked_by_retry_for_task(task_id)
31
+ end
32
+
33
+ def self.pending_for_task(task_id)
34
+ Tasker::Functions::FunctionBasedStepReadinessStatus.pending_for_task(task_id)
35
+ end
36
+
37
+ def self.failed_for_task(task_id)
38
+ Tasker::Functions::FunctionBasedStepReadinessStatus.failed_for_task(task_id)
39
+ end
40
+
41
+ def self.in_progress_for_task(task_id)
42
+ Tasker::Functions::FunctionBasedStepReadinessStatus.in_progress_for_task(task_id)
43
+ end
44
+
45
+ def self.complete_for_task(task_id)
46
+ Tasker::Functions::FunctionBasedStepReadinessStatus.complete_for_task(task_id)
47
+ end
48
+
49
+ # For backward compatibility, maintain the active method but point to function-based implementation
50
+ def self.active
51
+ Tasker::Functions::FunctionBasedStepReadinessStatus
52
+ end
53
+
54
+ def self.all_steps_complete_for_task?(task)
55
+ complete = Tasker::Functions::FunctionBasedStepReadinessStatus.complete_for_task(task.task_id)
56
+ complete.length == task.workflow_steps.count
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,424 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ require 'digest'
5
+ require_relative '../../../lib/tasker/state_machine/task_state_machine'
6
+
7
+ # == Schema Information
8
+ #
9
+ # Table name: tasks
10
+ #
11
+ # bypass_steps :json
12
+ # complete :boolean default(FALSE), not null
13
+ # context :jsonb
14
+ # identity_hash :string(128) not null
15
+ # initiator :string(128)
16
+ # reason :string(128)
17
+ # requested_at :datetime not null
18
+ # source_system :string(128)
19
+ # tags :jsonb
20
+ # created_at :datetime not null
21
+ # updated_at :datetime not null
22
+ # named_task_id :integer not null
23
+ # task_id :bigint not null, primary key
24
+ #
25
+ # Indexes
26
+ #
27
+ # index_tasks_on_identity_hash (identity_hash) UNIQUE
28
+ # tasks_context_idx (context) USING gin
29
+ # tasks_context_idx1 (context) USING gin
30
+ # tasks_identity_hash_index (identity_hash)
31
+ # tasks_named_task_id_index (named_task_id)
32
+ # tasks_requested_at_index (requested_at)
33
+ # tasks_source_system_index (source_system)
34
+ # tasks_tags_idx (tags) USING gin
35
+ # tasks_tags_idx1 (tags) USING gin
36
+ #
37
+ # Foreign Keys
38
+ #
39
+ # tasks_named_task_id_foreign (named_task_id => named_tasks.named_task_id)
40
+ #
41
+ module Tasker
42
+ # Task represents a workflow process that contains multiple workflow steps.
43
+ # Each Task is identified by a name and has a context which defines the parameters for the task.
44
+ # Tasks track their status via state machine transitions, initiator, source system, and other metadata.
45
+ #
46
+ # @example Creating a task from a task request
47
+ # task_request = Tasker::Types::TaskRequest.new(name: 'process_order', context: { order_id: 123 })
48
+ # task = Tasker::Task.create_with_defaults!(task_request)
49
+ #
50
+ class Task < ApplicationRecord
51
+ # Regular expression to sanitize strings for database operations
52
+ ALPHANUM_PLUS_HYPHEN_DASH = /[^0-9a-z\-_]/i
53
+
54
+ self.primary_key = :task_id
55
+ after_initialize :init_defaults, if: :new_record?
56
+ belongs_to :named_task
57
+ has_many :workflow_steps, dependent: :destroy
58
+ has_many :task_annotations, dependent: :destroy
59
+ has_many :annotation_types, through: :task_annotations
60
+ has_many :task_transitions, inverse_of: :task, dependent: :destroy
61
+
62
+ validates :context, presence: true
63
+ validates :requested_at, presence: true
64
+ validate :unique_identity_hash, on: :create
65
+
66
+ delegate :name, to: :named_task
67
+ delegate :to_mermaid, to: :diagram
68
+ delegate :workflow_summary, to: :task_execution_context
69
+
70
+ # State machine integration
71
+ def state_machine
72
+ @state_machine ||= Tasker::StateMachine::TaskStateMachine.new(
73
+ self,
74
+ transition_class: Tasker::TaskTransition,
75
+ association_name: :task_transitions
76
+ )
77
+ end
78
+
79
+ # Status is now entirely managed by the state machine
80
+ def status
81
+ if new_record?
82
+ # For new records, return the initial state
83
+ Tasker::Constants::TaskStatuses::PENDING
84
+ else
85
+ # For persisted records, use state machine
86
+ state_machine.current_state
87
+ end
88
+ end
89
+
90
+ # Scopes a query to find tasks with a specific annotation value
91
+ #
92
+ # @scope class
93
+ # @param name [String] The annotation type name
94
+ # @param key [String, Symbol] The key within the annotation to match
95
+ # @param value [String] The value to match against
96
+ # @return [ActiveRecord::Relation] Tasks matching the annotation criteria
97
+ scope :by_annotation,
98
+ lambda { |name, key, value|
99
+ clean_key = key.to_s.gsub(ALPHANUM_PLUS_HYPHEN_DASH, '')
100
+ joins(:task_annotations, :annotation_types)
101
+ .where({ annotation_types: { name: name.to_s.strip } })
102
+ .where("tasker_task_annotations.annotation->>'#{clean_key}' = :value", value: value)
103
+ }
104
+
105
+ # Scopes a query to find tasks by their current state using state machine transitions
106
+ #
107
+ # @scope class
108
+ # @param state [String, nil] The state to filter by. If nil, returns all tasks with current state information
109
+ # @return [ActiveRecord::Relation] Tasks with current state, optionally filtered by specific state
110
+ scope :by_current_state,
111
+ lambda { |state = nil|
112
+ relation = joins(<<-SQL.squish)
113
+ INNER JOIN (
114
+ SELECT DISTINCT ON (task_id) task_id, to_state
115
+ FROM tasker_task_transitions
116
+ ORDER BY task_id, sort_key DESC
117
+ ) current_transitions ON current_transitions.task_id = tasker_tasks.task_id
118
+ SQL
119
+
120
+ if state.present?
121
+ relation.where(current_transitions: { to_state: state })
122
+ else
123
+ relation
124
+ end
125
+ }
126
+
127
+ # Includes all associated models for efficient querying
128
+ #
129
+ # @return [ActiveRecord::Relation] Tasks with all associated records preloaded
130
+ scope :with_all_associated, lambda {
131
+ includes(named_task: [:task_namespace])
132
+ .includes(workflow_steps: %i[named_step parents children])
133
+ .includes(task_annotations: %i[annotation_type])
134
+ .includes(:task_transitions)
135
+ }
136
+
137
+ # Analytics scopes for performance metrics
138
+
139
+ # Scopes tasks created within a specific time period
140
+ #
141
+ # @scope class
142
+ # @param since_time [Time] The earliest creation time to include
143
+ # @return [ActiveRecord::Relation] Tasks created since the specified time
144
+ scope :created_since, lambda { |since_time|
145
+ where('tasker_tasks.created_at > ?', since_time)
146
+ }
147
+
148
+ # Scopes tasks completed within a specific time period
149
+ #
150
+ # @scope class
151
+ # @param since_time [Time] The earliest completion time to include
152
+ # @return [ActiveRecord::Relation] Tasks completed since the specified time
153
+ scope :completed_since, lambda { |since_time|
154
+ joins(workflow_steps: :workflow_step_transitions)
155
+ .where('tasker_workflow_step_transitions.to_state = ? AND tasker_workflow_step_transitions.most_recent = ?', 'complete', true)
156
+ .where('tasker_workflow_step_transitions.created_at > ?', since_time)
157
+ .distinct
158
+ }
159
+
160
+ # Scopes tasks that have failed within a specific time period
161
+ # This scope identifies tasks that are actually in a failed state (task status = 'error'),
162
+ # not just tasks that have some failed steps but may still be progressing.
163
+ #
164
+ # @scope class
165
+ # @param since_time [Time] The earliest failure time to include
166
+ # @return [ActiveRecord::Relation] Tasks that have transitioned to error state since the specified time
167
+ scope :failed_since, lambda { |since_time|
168
+ joins(<<-SQL.squish)
169
+ INNER JOIN (
170
+ SELECT DISTINCT ON (task_id) task_id, to_state, created_at
171
+ FROM tasker_task_transitions
172
+ ORDER BY task_id, sort_key DESC
173
+ ) current_transitions ON current_transitions.task_id = tasker_tasks.task_id
174
+ SQL
175
+ .where(current_transitions: { to_state: Tasker::Constants::TaskStatuses::ERROR })
176
+ .where('current_transitions.created_at > ?', since_time)
177
+ }
178
+
179
+ # Scopes tasks that are currently active (not in terminal states)
180
+ #
181
+ # @scope class
182
+ # @return [ActiveRecord::Relation] Tasks that are not complete, error, or cancelled
183
+ scope :active, lambda {
184
+ # Active tasks are those with at least one workflow step whose most recent transition
185
+ # is NOT in a terminal state. Using EXISTS subquery for clarity and performance.
186
+ where(<<-SQL.squish)
187
+ EXISTS (
188
+ SELECT 1
189
+ FROM tasker_workflow_steps ws
190
+ INNER JOIN tasker_workflow_step_transitions wst ON wst.workflow_step_id = ws.workflow_step_id
191
+ WHERE ws.task_id = tasker_tasks.task_id
192
+ AND wst.most_recent = true
193
+ AND wst.to_state NOT IN ('complete', 'error', 'skipped', 'resolved_manually')
194
+ )
195
+ SQL
196
+ }
197
+
198
+ # Scopes tasks by namespace name through the named_task association
199
+ #
200
+ # @scope class
201
+ # @param namespace_name [String] The namespace name to filter by
202
+ # @return [ActiveRecord::Relation] Tasks in the specified namespace
203
+ scope :in_namespace, lambda { |namespace_name|
204
+ joins(named_task: :task_namespace)
205
+ .where(tasker_task_namespaces: { name: namespace_name })
206
+ }
207
+
208
+ # Scopes tasks by task name through the named_task association
209
+ #
210
+ # @scope class
211
+ # @param task_name [String] The task name to filter by
212
+ # @return [ActiveRecord::Relation] Tasks with the specified name
213
+ scope :with_task_name, lambda { |task_name|
214
+ joins(:named_task)
215
+ .where(tasker_named_tasks: { name: task_name })
216
+ }
217
+
218
+ # Scopes tasks by version through the named_task association
219
+ #
220
+ # @scope class
221
+ # @param version [String] The version to filter by
222
+ # @return [ActiveRecord::Relation] Tasks with the specified version
223
+ scope :with_version, lambda { |version|
224
+ joins(:named_task)
225
+ .where(tasker_named_tasks: { version: version })
226
+ }
227
+
228
+ # Class method for counting unique task types
229
+ #
230
+ # @return [Integer] Count of unique task names
231
+ def self.unique_task_types_count
232
+ joins(:named_task).distinct.count('tasker_named_tasks.name')
233
+ end
234
+
235
+ # Creates a task with default values from a task request and saves it to the database
236
+ #
237
+ # @param task_request [Tasker::Types::TaskRequest] The task request containing task parameters
238
+ # @return [Tasker::Task] The created and saved task
239
+ # @raise [ActiveRecord::RecordInvalid] If the task is invalid
240
+ def self.create_with_defaults!(task_request)
241
+ task = from_task_request(task_request)
242
+ task.save!
243
+ task
244
+ end
245
+
246
+ # Creates a new unsaved task instance from a task request
247
+ #
248
+ # @param task_request [Tasker::Types::TaskRequest] The task request containing task parameters
249
+ # @return [Tasker::Task] A new unsaved task instance
250
+ def self.from_task_request(task_request)
251
+ named_task = Tasker::NamedTask.find_or_create_by_full_name!(name: task_request.name,
252
+ namespace_name: task_request.namespace, version: task_request.version)
253
+ # Extract values from task_request, removing nils
254
+ request_values = get_request_options(task_request)
255
+ # Merge defaults with request values
256
+ options = get_default_task_request_options(named_task).merge(request_values)
257
+
258
+ task = new(options)
259
+ task.named_task = named_task
260
+ task
261
+ end
262
+
263
+ # Extracts and compacts options from a task request
264
+ #
265
+ # @param task_request [Tasker::Types::TaskRequest] The task request to extract options from
266
+ # @return [Hash] Hash of non-nil task options from the request
267
+ def self.get_request_options(task_request)
268
+ {
269
+ initiator: task_request.initiator,
270
+ source_system: task_request.source_system,
271
+ reason: task_request.reason,
272
+ tags: task_request.tags,
273
+ bypass_steps: task_request.bypass_steps,
274
+ requested_at: task_request.requested_at,
275
+ context: task_request.context
276
+ }.compact
277
+ end
278
+
279
+ # Provides default options for a task
280
+ #
281
+ # @param named_task [Tasker::NamedTask] The named task to associate with the task
282
+ # @return [Hash] Hash of default task options
283
+ def self.get_default_task_request_options(named_task)
284
+ {
285
+ initiator: Tasker::Constants::UNKNOWN,
286
+ source_system: Constants::UNKNOWN,
287
+ reason: Tasker::Constants::UNKNOWN,
288
+ complete: false,
289
+ tags: [],
290
+ bypass_steps: [],
291
+ requested_at: Time.zone.now,
292
+ named_task_id: named_task.named_task_id
293
+ }
294
+ end
295
+
296
+ # Finds a workflow step by its name
297
+ #
298
+ # @param name [String] The name of the step to find
299
+ # @return [Tasker::WorkflowStep, nil] The workflow step with the given name, or nil if not found
300
+ def get_step_by_name(name)
301
+ workflow_steps.includes(:named_step).where(named_step: { name: name }).first
302
+ end
303
+
304
+ # Gets or creates a diagram representation of this task
305
+ #
306
+ # @param base_url [String, nil] The base URL to use for links in the diagram, defaults to nil
307
+ # @return [Tasker::TaskDiagram] The diagram representation of this task
308
+ def diagram(base_url = nil)
309
+ @diagram ||= Tasker::TaskDiagram.new(self, base_url)
310
+ end
311
+
312
+ def runtime_analyzer
313
+ @runtime_analyzer ||= Tasker::Analysis::RuntimeGraphAnalyzer.new(task: self)
314
+ end
315
+
316
+ # Provides runtime dependency graph analysis
317
+ # Delegates to RuntimeGraphAnalyzer for graph-based analysis
318
+ #
319
+ # @return [Hash] Runtime dependency graph analysis
320
+ def dependency_graph
321
+ runtime_analyzer.analyze
322
+ end
323
+
324
+ # Checks if all steps in the task are complete
325
+ #
326
+ # @return [Boolean] True if all steps are complete, false otherwise
327
+ def all_steps_complete?
328
+ Tasker::StepReadinessStatus.all_steps_complete_for_task?(self)
329
+ end
330
+
331
+ def task_execution_context
332
+ @task_execution_context ||= Tasker::TaskExecutionContext.new(task_id)
333
+ end
334
+
335
+ def reload
336
+ super
337
+ @task_execution_context = nil
338
+ @diagram = nil
339
+ end
340
+
341
+ delegate :namespace_name, to: :named_task
342
+
343
+ delegate :version, to: :named_task
344
+
345
+ private
346
+
347
+ # Validates that the task has a unique identity hash
348
+ # Sets the identity hash and checks if a task with the same hash exists
349
+ #
350
+ # @return [void]
351
+ def unique_identity_hash
352
+ return errors.add(:named_task_id, 'no task name found') unless named_task
353
+
354
+ set_identity_hash
355
+ inst = self.class.where(identity_hash: identity_hash).where.not(task_id: task_id).first
356
+ errors.add(:identity_hash, 'is identical to a request made in the last minute') if inst
357
+ end
358
+
359
+ # Returns a hash of values that uniquely identify this task
360
+ #
361
+ # @return [Hash] Hash of identifying values
362
+ def identity_options
363
+ # a task can be described as identical to a prior request if
364
+ # it has the same name, initiator, source system, reason
365
+ # bypass steps, and critically, the same identical context for the request
366
+ # if all of these are the same, and it was requested within the same minute
367
+ # then we can assume some client side or queue side duplication is happening
368
+ {
369
+ name: name,
370
+ initiator: initiator,
371
+ source_system: source_system,
372
+ context: context,
373
+ reason: reason,
374
+ bypass_steps: bypass_steps || [],
375
+ # not allowing structurally identical requests within the same minute
376
+ # this is a fuzzy match of course, at the 59 / 00 mark there could be overlap
377
+ # but this feels like a pretty good level of identity checking
378
+ # without being exhaustive
379
+ requested_at: requested_at.strftime('%Y-%m-%d %H:%M')
380
+ }
381
+ end
382
+
383
+ # Initializes default values for a new task
384
+ #
385
+ # @return [void]
386
+ def init_defaults
387
+ return unless new_record?
388
+
389
+ # Apply defaults only for attributes that haven't been set
390
+ task_defaults.each do |attribute, default_value|
391
+ self[attribute] = default_value if self[attribute].nil?
392
+ end
393
+ end
394
+
395
+ # Returns a hash of default values for a task
396
+ #
397
+ # @return [Hash] Hash of default values
398
+ def task_defaults
399
+ @task_defaults ||= {
400
+ requested_at: Time.zone.now,
401
+ initiator: Tasker::Constants::UNKNOWN,
402
+ source_system: Tasker::Constants::UNKNOWN,
403
+ reason: Tasker::Constants::UNKNOWN,
404
+ complete: false,
405
+ tags: [],
406
+ bypass_steps: []
407
+ }
408
+ end
409
+
410
+ # Gets the identity strategy instance from configuration
411
+ #
412
+ # @return [Object] The identity strategy instance
413
+ def identity_strategy
414
+ @identity_strategy ||= Tasker.configuration.engine.identity_strategy_instance
415
+ end
416
+
417
+ # Sets the identity hash for this task using the configured identity strategy
418
+ #
419
+ # @return [String] The generated identity hash
420
+ def set_identity_hash
421
+ self.identity_hash = identity_strategy.generate_identity_hash(self, identity_options)
422
+ end
423
+ end
424
+ end
@@ -0,0 +1,36 @@
1
+ # typed: false
2
+ # frozen_string_literal: true
3
+
4
+ # == Schema Information
5
+ #
6
+ # Table name: task_annotations
7
+ #
8
+ # annotation :jsonb
9
+ # created_at :datetime not null
10
+ # updated_at :datetime not null
11
+ # annotation_type_id :integer not null
12
+ # task_annotation_id :bigint not null, primary key
13
+ # task_id :bigint not null
14
+ #
15
+ # Indexes
16
+ #
17
+ # task_annotations_annotation_idx (annotation) USING gin
18
+ # task_annotations_annotation_idx1 (annotation) USING gin
19
+ # task_annotations_annotation_type_id_index (annotation_type_id)
20
+ # task_annotations_task_id_index (task_id)
21
+ #
22
+ # Foreign Keys
23
+ #
24
+ # task_annotations_annotation_type_id_foreign (annotation_type_id => annotation_types.annotation_type_id)
25
+ # task_annotations_task_id_foreign (task_id => tasks.task_id)
26
+ #
27
+
28
+ module Tasker
29
+ class TaskAnnotation < ApplicationRecord
30
+ self.primary_key = :task_annotation_id
31
+ belongs_to :task
32
+ belongs_to :annotation_type
33
+
34
+ delegate :name, to: :annotation_type, prefix: true
35
+ end
36
+ end