tasker-engine 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/README.md +443 -0
- data/Rakefile +10 -0
- data/app/controllers/tasker/analytics_controller.rb +179 -0
- data/app/controllers/tasker/application_controller.rb +45 -0
- data/app/controllers/tasker/graphql_controller.rb +193 -0
- data/app/controllers/tasker/handlers_controller.rb +217 -0
- data/app/controllers/tasker/health_controller.rb +229 -0
- data/app/controllers/tasker/metrics_controller.rb +111 -0
- data/app/controllers/tasker/page_sort.rb +97 -0
- data/app/controllers/tasker/task_diagrams_controller.rb +30 -0
- data/app/controllers/tasker/tasks_controller.rb +123 -0
- data/app/controllers/tasker/workflow_steps_controller.rb +69 -0
- data/app/graphql/examples/all_tasks.graphql +22 -0
- data/app/graphql/examples/pending_tasks.graphql +23 -0
- data/app/graphql/tasker/graph_ql_types/annotation_type.rb +14 -0
- data/app/graphql/tasker/graph_ql_types/base_argument.rb +9 -0
- data/app/graphql/tasker/graph_ql_types/base_connection.rb +11 -0
- data/app/graphql/tasker/graph_ql_types/base_edge.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_enum.rb +9 -0
- data/app/graphql/tasker/graph_ql_types/base_field.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_input_object.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_interface.rb +14 -0
- data/app/graphql/tasker/graph_ql_types/base_object.rb +10 -0
- data/app/graphql/tasker/graph_ql_types/base_scalar.rb +9 -0
- data/app/graphql/tasker/graph_ql_types/base_union.rb +11 -0
- data/app/graphql/tasker/graph_ql_types/dependent_system_object_map_type.rb +18 -0
- data/app/graphql/tasker/graph_ql_types/dependent_system_type.rb +13 -0
- data/app/graphql/tasker/graph_ql_types/mutation_type.rb +16 -0
- data/app/graphql/tasker/graph_ql_types/named_step_type.rb +16 -0
- data/app/graphql/tasker/graph_ql_types/named_task_type.rb +14 -0
- data/app/graphql/tasker/graph_ql_types/named_tasks_named_step_type.rb +19 -0
- data/app/graphql/tasker/graph_ql_types/node_type.rb +12 -0
- data/app/graphql/tasker/graph_ql_types/query_type.rb +20 -0
- data/app/graphql/tasker/graph_ql_types/task_annotation_type.rb +17 -0
- data/app/graphql/tasker/graph_ql_types/task_interface.rb +17 -0
- data/app/graphql/tasker/graph_ql_types/task_type.rb +26 -0
- data/app/graphql/tasker/graph_ql_types/workflow_step_type.rb +154 -0
- data/app/graphql/tasker/graph_ql_types.rb +42 -0
- data/app/graphql/tasker/mutations/base_mutation.rb +13 -0
- data/app/graphql/tasker/mutations/cancel_step.rb +29 -0
- data/app/graphql/tasker/mutations/cancel_task.rb +29 -0
- data/app/graphql/tasker/mutations/create_task.rb +52 -0
- data/app/graphql/tasker/mutations/update_step.rb +36 -0
- data/app/graphql/tasker/mutations/update_task.rb +41 -0
- data/app/graphql/tasker/queries/all_annotation_types.rb +17 -0
- data/app/graphql/tasker/queries/all_tasks.rb +23 -0
- data/app/graphql/tasker/queries/base_query.rb +9 -0
- data/app/graphql/tasker/queries/helpers.rb +16 -0
- data/app/graphql/tasker/queries/one_step.rb +24 -0
- data/app/graphql/tasker/queries/one_task.rb +18 -0
- data/app/graphql/tasker/queries/tasks_by_annotation.rb +31 -0
- data/app/graphql/tasker/queries/tasks_by_status.rb +30 -0
- data/app/graphql/tasker/tasker_rails_schema.rb +52 -0
- data/app/jobs/tasker/application_job.rb +8 -0
- data/app/jobs/tasker/metrics_export_job.rb +252 -0
- data/app/jobs/tasker/task_runner_job.rb +224 -0
- data/app/models/tasker/annotation_type.rb +26 -0
- data/app/models/tasker/application_record.rb +70 -0
- data/app/models/tasker/dependent_system.rb +26 -0
- data/app/models/tasker/dependent_system_object_map.rb +64 -0
- data/app/models/tasker/diagram/edge.rb +106 -0
- data/app/models/tasker/diagram/flowchart.rb +137 -0
- data/app/models/tasker/diagram/node.rb +99 -0
- data/app/models/tasker/named_step.rb +41 -0
- data/app/models/tasker/named_task.rb +121 -0
- data/app/models/tasker/named_tasks_named_step.rb +82 -0
- data/app/models/tasker/step_dag_relationship.rb +65 -0
- data/app/models/tasker/step_readiness_status.rb +59 -0
- data/app/models/tasker/task.rb +424 -0
- data/app/models/tasker/task_annotation.rb +36 -0
- data/app/models/tasker/task_diagram.rb +332 -0
- data/app/models/tasker/task_execution_context.rb +29 -0
- data/app/models/tasker/task_namespace.rb +41 -0
- data/app/models/tasker/task_transition.rb +235 -0
- data/app/models/tasker/workflow_step.rb +461 -0
- data/app/models/tasker/workflow_step_edge.rb +94 -0
- data/app/models/tasker/workflow_step_transition.rb +434 -0
- data/app/serializers/tasker/annotation_type_serializer.rb +8 -0
- data/app/serializers/tasker/handler_serializer.rb +109 -0
- data/app/serializers/tasker/task_annotation_serializer.rb +32 -0
- data/app/serializers/tasker/task_serializer.rb +168 -0
- data/app/serializers/tasker/workflow_step_serializer.rb +27 -0
- data/app/services/tasker/analytics_service.rb +409 -0
- data/app/views/tasker/task/_diagram.html.erb +32 -0
- data/config/initializers/dry_struct.rb +11 -0
- data/config/initializers/statesman.rb +6 -0
- data/config/initializers/tasker_orchestration.rb +17 -0
- data/config/initializers/time_formats.rb +4 -0
- data/config/routes.rb +34 -0
- data/config/tasker/subscriptions/example_integrations.yml +67 -0
- data/config/tasker/system_events.yml +305 -0
- data/db/functions/calculate_dependency_levels_v01.sql +45 -0
- data/db/functions/get_analytics_metrics_v01.sql +137 -0
- data/db/functions/get_slowest_steps_v01.sql +82 -0
- data/db/functions/get_slowest_tasks_v01.sql +96 -0
- data/db/functions/get_step_readiness_status_batch_v01.sql +140 -0
- data/db/functions/get_step_readiness_status_v01.sql +139 -0
- data/db/functions/get_system_health_counts_v01.sql +108 -0
- data/db/functions/get_task_execution_context_v01.sql +108 -0
- data/db/functions/get_task_execution_contexts_batch_v01.sql +104 -0
- data/db/init/schema.sql +2277 -0
- data/db/migrate/20250701165431_initial_tasker_schema.rb +116 -0
- data/db/views/tasker_step_dag_relationships_v01.sql +69 -0
- data/docs/APPLICATION_GENERATOR.md +384 -0
- data/docs/AUTH.md +1780 -0
- data/docs/CIRCUIT_BREAKER.md +224 -0
- data/docs/DEVELOPER_GUIDE.md +2665 -0
- data/docs/EVENT_SYSTEM.md +637 -0
- data/docs/EXECUTION_CONFIGURATION.md +341 -0
- data/docs/FLOW_CHART.md +149 -0
- data/docs/HEALTH.md +542 -0
- data/docs/METRICS.md +731 -0
- data/docs/OPTIMIZATION_PLAN.md +1479 -0
- data/docs/OVERVIEW.md +552 -0
- data/docs/QUICK_START.md +270 -0
- data/docs/REGISTRY_SYSTEMS.md +373 -0
- data/docs/REST_API.md +632 -0
- data/docs/ROADMAP.md +221 -0
- data/docs/SQL_FUNCTIONS.md +1408 -0
- data/docs/TASK_DIAGRAM.md +252 -0
- data/docs/TASK_EXECUTION_CONTROL_FLOW.md +237 -0
- data/docs/TELEMETRY.md +795 -0
- data/docs/TROUBLESHOOTING.md +756 -0
- data/docs/TaskHandlerGenerator.html +255 -0
- data/docs/Tasker/Analysis/RuntimeGraphAnalyzer.html +907 -0
- data/docs/Tasker/Analysis/TemplateGraphAnalyzer.html +1236 -0
- data/docs/Tasker/Analysis.html +117 -0
- data/docs/Tasker/AnalyticsController.html +450 -0
- data/docs/Tasker/AnalyticsService/BottleneckAnalytics.html +816 -0
- data/docs/Tasker/AnalyticsService/PerformanceAnalytics.html +586 -0
- data/docs/Tasker/AnalyticsService.html +2221 -0
- data/docs/Tasker/AnnotationType.html +137 -0
- data/docs/Tasker/AnnotationTypeSerializer.html +124 -0
- data/docs/Tasker/ApplicationController.html +147 -0
- data/docs/Tasker/ApplicationJob.html +128 -0
- data/docs/Tasker/ApplicationRecord.html +378 -0
- data/docs/Tasker/Authentication/AuthenticationError.html +124 -0
- data/docs/Tasker/Authentication/ConfigurationError.html +124 -0
- data/docs/Tasker/Authentication/Coordinator.html +242 -0
- data/docs/Tasker/Authentication/Interface.html +560 -0
- data/docs/Tasker/Authentication/InterfaceError.html +124 -0
- data/docs/Tasker/Authentication/NoneAuthenticator.html +338 -0
- data/docs/Tasker/Authentication.html +119 -0
- data/docs/Tasker/Authorization/AuthorizationError.html +139 -0
- data/docs/Tasker/Authorization/BaseCoordinator.html +927 -0
- data/docs/Tasker/Authorization/ConfigurationError.html +153 -0
- data/docs/Tasker/Authorization/ResourceConstants/ACTIONS.html +428 -0
- data/docs/Tasker/Authorization/ResourceConstants/RESOURCES.html +365 -0
- data/docs/Tasker/Authorization/ResourceConstants.html +146 -0
- data/docs/Tasker/Authorization/ResourceRegistry.html +882 -0
- data/docs/Tasker/Authorization/UnauthorizedError.html +153 -0
- data/docs/Tasker/Authorization.html +582 -0
- data/docs/Tasker/CacheCapabilities.html +167 -0
- data/docs/Tasker/CacheStrategy.html +1297 -0
- data/docs/Tasker/Concerns/Authenticatable.html +116 -0
- data/docs/Tasker/Concerns/Authorizable/AdminStatusChecker.html +256 -0
- data/docs/Tasker/Concerns/Authorizable.html +816 -0
- data/docs/Tasker/Concerns/ControllerAuthorizable.html +157 -0
- data/docs/Tasker/Concerns/EventPublisher.html +4023 -0
- data/docs/Tasker/Concerns/IdempotentStateTransitions.html +806 -0
- data/docs/Tasker/Concerns/LifecycleEventHelpers.html +129 -0
- data/docs/Tasker/Concerns/OrchestrationPublisher.html +129 -0
- data/docs/Tasker/Concerns/StateMachineBase/ClassMethods.html +1075 -0
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase/ClassMethods.html +191 -0
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase.html +126 -0
- data/docs/Tasker/Concerns/StateMachineBase.html +153 -0
- data/docs/Tasker/Concerns/StructuredLogging.html +1413 -0
- data/docs/Tasker/Concerns.html +117 -0
- data/docs/Tasker/Configuration/AuthConfiguration.html +1023 -0
- data/docs/Tasker/Configuration/ConfigurationProxy.html +581 -0
- data/docs/Tasker/Configuration/DatabaseConfiguration.html +475 -0
- data/docs/Tasker/Configuration/EngineConfiguration.html +1265 -0
- data/docs/Tasker/Configuration/HealthConfiguration.html +791 -0
- data/docs/Tasker/Configuration/TelemetryConfiguration.html +1308 -0
- data/docs/Tasker/Configuration/TelemetryConfigurationProxy.html +388 -0
- data/docs/Tasker/Configuration.html +1669 -0
- data/docs/Tasker/ConfigurationError.html +143 -0
- data/docs/Tasker/ConfiguredTask.html +514 -0
- data/docs/Tasker/Constants/EventDefinitions.html +590 -0
- data/docs/Tasker/Constants/LifecycleEvents.html +137 -0
- data/docs/Tasker/Constants/ObservabilityEvents/Step.html +152 -0
- data/docs/Tasker/Constants/ObservabilityEvents/Task.html +142 -0
- data/docs/Tasker/Constants/ObservabilityEvents.html +126 -0
- data/docs/Tasker/Constants/RegistryEvents.html +285 -0
- data/docs/Tasker/Constants/StepEvents.html +177 -0
- data/docs/Tasker/Constants/TaskEvents.html +167 -0
- data/docs/Tasker/Constants/TaskExecution/ExecutionStatus.html +207 -0
- data/docs/Tasker/Constants/TaskExecution/HealthStatus.html +191 -0
- data/docs/Tasker/Constants/TaskExecution/RecommendedAction.html +207 -0
- data/docs/Tasker/Constants/TaskExecution.html +126 -0
- data/docs/Tasker/Constants/TaskFinalization/ErrorMessages.html +132 -0
- data/docs/Tasker/Constants/TaskFinalization/PendingReasons.html +207 -0
- data/docs/Tasker/Constants/TaskFinalization/ReenqueueReasons.html +239 -0
- data/docs/Tasker/Constants/TaskFinalization.html +126 -0
- data/docs/Tasker/Constants/TaskStatuses.html +223 -0
- data/docs/Tasker/Constants/TestEvents.html +163 -0
- data/docs/Tasker/Constants/WorkflowEvents.html +222 -0
- data/docs/Tasker/Constants/WorkflowStepStatuses.html +223 -0
- data/docs/Tasker/Constants.html +561 -0
- data/docs/Tasker/DependentSystem.html +137 -0
- data/docs/Tasker/DependentSystemObjectMap.html +250 -0
- data/docs/Tasker/DetectorRegistry.html +598 -0
- data/docs/Tasker/Diagram/Edge.html +1191 -0
- data/docs/Tasker/Diagram/Flowchart.html +1539 -0
- data/docs/Tasker/Diagram/Node.html +1165 -0
- data/docs/Tasker/Diagram.html +117 -0
- data/docs/Tasker/Engine.html +215 -0
- data/docs/Tasker/Error.html +139 -0
- data/docs/Tasker/Events/Bus.html +1226 -0
- data/docs/Tasker/Events/Catalog/CatalogPrinter.html +258 -0
- data/docs/Tasker/Events/Catalog/CustomEventRegistrar.html +276 -0
- data/docs/Tasker/Events/Catalog/ExamplePayloadGenerator.html +294 -0
- data/docs/Tasker/Events/Catalog.html +1291 -0
- data/docs/Tasker/Events/CustomRegistry.html +943 -0
- data/docs/Tasker/Events/DefinitionLoader.html +575 -0
- data/docs/Tasker/Events/EventPayloadBuilder/ErrorInfoExtractor.html +286 -0
- data/docs/Tasker/Events/EventPayloadBuilder/StepPayloadBuilder.html +312 -0
- data/docs/Tasker/Events/EventPayloadBuilder.html +664 -0
- data/docs/Tasker/Events/Publisher.html +365 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer/ErrorTypeClassifier.html +1128 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer.html +270 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/MetricTagsExtractor.html +266 -0
- data/docs/Tasker/Events/Subscribers/BaseSubscriber.html +2556 -0
- data/docs/Tasker/Events/Subscribers/MetricsSubscriber.html +723 -0
- data/docs/Tasker/Events/Subscribers/TelemetrySubscriber.html +2251 -0
- data/docs/Tasker/Events/Subscribers.html +117 -0
- data/docs/Tasker/Events/SubscriptionLoader.html +493 -0
- data/docs/Tasker/Events.html +294 -0
- data/docs/Tasker/EventsGenerator.html +459 -0
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics/AnalyticsMetrics.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics.html +412 -0
- data/docs/Tasker/Functions/FunctionBasedDependencyLevels.html +598 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps/SlowestStep.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps.html +453 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks/SlowestTask.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks.html +453 -0
- data/docs/Tasker/Functions/FunctionBasedStepReadinessStatus.html +1457 -0
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts/HealthMetrics.html +135 -0
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts.html +370 -0
- data/docs/Tasker/Functions/FunctionBasedTaskExecutionContext.html +1250 -0
- data/docs/Tasker/Functions/FunctionWrapper.html +479 -0
- data/docs/Tasker/Functions.html +117 -0
- data/docs/Tasker/Generators/AuthenticatorGenerator/UsageInstructionsFormatter.html +244 -0
- data/docs/Tasker/Generators/AuthenticatorGenerator.html +373 -0
- data/docs/Tasker/Generators/AuthorizationCoordinatorGenerator.html +430 -0
- data/docs/Tasker/Generators/SubscriberGenerator.html +377 -0
- data/docs/Tasker/Generators/TaskHandlerGenerator.html +263 -0
- data/docs/Tasker/Generators.html +117 -0
- data/docs/Tasker/GraphQLTypes/AnnotationType.html +132 -0
- data/docs/Tasker/GraphQLTypes/BaseArgument.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseConnection.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseEdge.html +130 -0
- data/docs/Tasker/GraphQLTypes/BaseEnum.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseField.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseInputObject.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseInterface.html +116 -0
- data/docs/Tasker/GraphQLTypes/BaseObject.html +128 -0
- data/docs/Tasker/GraphQLTypes/BaseScalar.html +124 -0
- data/docs/Tasker/GraphQLTypes/BaseUnion.html +124 -0
- data/docs/Tasker/GraphQLTypes/DependentSystemObjectMapType.html +132 -0
- data/docs/Tasker/GraphQLTypes/DependentSystemType.html +132 -0
- data/docs/Tasker/GraphQLTypes/MutationType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NamedStepType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NamedTaskType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NamedTasksNamedStepType.html +132 -0
- data/docs/Tasker/GraphQLTypes/NodeType.html +118 -0
- data/docs/Tasker/GraphQLTypes/QueryType.html +139 -0
- data/docs/Tasker/GraphQLTypes/TaskAnnotationType.html +132 -0
- data/docs/Tasker/GraphQLTypes/TaskInterface.html +111 -0
- data/docs/Tasker/GraphQLTypes/TaskType.html +201 -0
- data/docs/Tasker/GraphQLTypes/WorkflowStepType.html +694 -0
- data/docs/Tasker/GraphQLTypes.html +130 -0
- data/docs/Tasker/GraphqlController.html +251 -0
- data/docs/Tasker/HandlerFactory.html +1518 -0
- data/docs/Tasker/HandlerSerializer.html +682 -0
- data/docs/Tasker/HandlersController.html +574 -0
- data/docs/Tasker/HashIdentityStrategy.html +278 -0
- data/docs/Tasker/Health/ReadinessChecker.html +712 -0
- data/docs/Tasker/Health/StatusChecker.html +653 -0
- data/docs/Tasker/Health.html +117 -0
- data/docs/Tasker/HealthController.html +523 -0
- data/docs/Tasker/IdentityStrategy.html +276 -0
- data/docs/Tasker/InvalidTaskHandlerConfig.html +135 -0
- data/docs/Tasker/LifecycleEvents/Events/Step.html +162 -0
- data/docs/Tasker/LifecycleEvents/Events/Task.html +162 -0
- data/docs/Tasker/LifecycleEvents/Events.html +204 -0
- data/docs/Tasker/LifecycleEvents/Publisher.html +132 -0
- data/docs/Tasker/LifecycleEvents.html +799 -0
- data/docs/Tasker/Logging/CorrelationIdGenerator.html +688 -0
- data/docs/Tasker/Logging.html +115 -0
- data/docs/Tasker/MetricsController.html +293 -0
- data/docs/Tasker/MetricsExportJob.html +414 -0
- data/docs/Tasker/Mutations/BaseMutation.html +128 -0
- data/docs/Tasker/Mutations/CancelStep.html +219 -0
- data/docs/Tasker/Mutations/CancelTask.html +221 -0
- data/docs/Tasker/Mutations/CreateTask.html +243 -0
- data/docs/Tasker/Mutations/UpdateStep.html +243 -0
- data/docs/Tasker/Mutations/UpdateTask.html +243 -0
- data/docs/Tasker/Mutations.html +117 -0
- data/docs/Tasker/NamedStep.html +216 -0
- data/docs/Tasker/NamedTask.html +910 -0
- data/docs/Tasker/NamedTasksNamedStep.html +435 -0
- data/docs/Tasker/Orchestration/BackoffCalculator.html +404 -0
- data/docs/Tasker/Orchestration/ConnectionBuilder/ConfigValidator.html +258 -0
- data/docs/Tasker/Orchestration/ConnectionBuilder.html +435 -0
- data/docs/Tasker/Orchestration/ConnectionPoolIntelligence.html +513 -0
- data/docs/Tasker/Orchestration/Coordinator.html +641 -0
- data/docs/Tasker/Orchestration/FutureStateAnalyzer.html +1045 -0
- data/docs/Tasker/Orchestration/Orchestrator.html +679 -0
- data/docs/Tasker/Orchestration/PluginIntegration.html +1127 -0
- data/docs/Tasker/Orchestration/ResponseProcessor.html +504 -0
- data/docs/Tasker/Orchestration/RetryHeaderParser.html +304 -0
- data/docs/Tasker/Orchestration/StepExecutor.html +995 -0
- data/docs/Tasker/Orchestration/StepSequenceFactory.html +644 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/BlockageChecker.html +264 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/ContextManager.html +254 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/DelayCalculator.html +556 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationDecisionMaker.html +348 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationProcessor.html +286 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/ReasonDeterminer.html +432 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/ReenqueueManager.html +296 -0
- data/docs/Tasker/Orchestration/TaskFinalizer/UnclearStateHandler.html +314 -0
- data/docs/Tasker/Orchestration/TaskFinalizer.html +1212 -0
- data/docs/Tasker/Orchestration/TaskInitializer.html +766 -0
- data/docs/Tasker/Orchestration/TaskReenqueuer.html +506 -0
- data/docs/Tasker/Orchestration/ViableStepDiscovery.html +442 -0
- data/docs/Tasker/Orchestration/WorkflowCoordinator.html +510 -0
- data/docs/Tasker/Orchestration.html +130 -0
- data/docs/Tasker/PageSort/PageSortParamsBuilder.html +296 -0
- data/docs/Tasker/PageSort.html +247 -0
- data/docs/Tasker/PermanentError.html +518 -0
- data/docs/Tasker/ProceduralError.html +147 -0
- data/docs/Tasker/Queries/AllAnnotationTypes.html +217 -0
- data/docs/Tasker/Queries/AllTasks.html +221 -0
- data/docs/Tasker/Queries/BaseQuery.html +128 -0
- data/docs/Tasker/Queries/Helpers.html +187 -0
- data/docs/Tasker/Queries/OneStep.html +225 -0
- data/docs/Tasker/Queries/OneTask.html +217 -0
- data/docs/Tasker/Queries/TasksByAnnotation.html +231 -0
- data/docs/Tasker/Queries/TasksByStatus.html +233 -0
- data/docs/Tasker/Queries.html +119 -0
- data/docs/Tasker/Railtie.html +124 -0
- data/docs/Tasker/Registry/BaseRegistry.html +1690 -0
- data/docs/Tasker/Registry/EventPublisher.html +667 -0
- data/docs/Tasker/Registry/InterfaceValidator.html +569 -0
- data/docs/Tasker/Registry/RegistrationError.html +132 -0
- data/docs/Tasker/Registry/RegistryError.html +139 -0
- data/docs/Tasker/Registry/StatisticsCollector.html +841 -0
- data/docs/Tasker/Registry/SubscriberRegistry.html +1504 -0
- data/docs/Tasker/Registry/ValidationError.html +132 -0
- data/docs/Tasker/Registry.html +119 -0
- data/docs/Tasker/RetryableError.html +515 -0
- data/docs/Tasker/StateMachine/Compatibility.html +282 -0
- data/docs/Tasker/StateMachine/InvalidStateTransition.html +135 -0
- data/docs/Tasker/StateMachine/StepStateMachine/StandardizedPayloadBuilder.html +260 -0
- data/docs/Tasker/StateMachine/StepStateMachine.html +2215 -0
- data/docs/Tasker/StateMachine/TaskStateMachine.html +734 -0
- data/docs/Tasker/StateMachine.html +602 -0
- data/docs/Tasker/StepDagRelationship.html +657 -0
- data/docs/Tasker/StepHandler/Api/Config.html +1091 -0
- data/docs/Tasker/StepHandler/Api.html +884 -0
- data/docs/Tasker/StepHandler/AutomaticEventPublishing.html +321 -0
- data/docs/Tasker/StepHandler/Base.html +970 -0
- data/docs/Tasker/StepHandler.html +119 -0
- data/docs/Tasker/StepReadinessStatus.html +836 -0
- data/docs/Tasker/Task.html +2575 -0
- data/docs/Tasker/TaskAnnotation.html +137 -0
- data/docs/Tasker/TaskAnnotationSerializer.html +124 -0
- data/docs/Tasker/TaskBuilder/StepNameValidator.html +264 -0
- data/docs/Tasker/TaskBuilder/StepTemplateDefiner.html +264 -0
- data/docs/Tasker/TaskBuilder.html +764 -0
- data/docs/Tasker/TaskDiagram/StepToStepEdgeBuilder.html +260 -0
- data/docs/Tasker/TaskDiagram/TaskToRootStepEdgeBuilder.html +290 -0
- data/docs/Tasker/TaskDiagram.html +548 -0
- data/docs/Tasker/TaskDiagramsController.html +240 -0
- data/docs/Tasker/TaskExecutionContext.html +469 -0
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/ClassBasedEventRegistrar.html +238 -0
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/YamlEventRegistrar.html +254 -0
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner.html +988 -0
- data/docs/Tasker/TaskHandler/ClassMethods.html +357 -0
- data/docs/Tasker/TaskHandler/InstanceMethods.html +1396 -0
- data/docs/Tasker/TaskHandler/StepGroup.html +1748 -0
- data/docs/Tasker/TaskHandler.html +271 -0
- data/docs/Tasker/TaskNamespace.html +312 -0
- data/docs/Tasker/TaskRunnerJob.html +406 -0
- data/docs/Tasker/TaskSerializer.html +474 -0
- data/docs/Tasker/TaskTransition.html +1517 -0
- data/docs/Tasker/TaskWorkflowSummary.html +988 -0
- data/docs/Tasker/TaskerRailsSchema/InvalidObjectTypeError.html +132 -0
- data/docs/Tasker/TaskerRailsSchema/TypeResolutionError.html +139 -0
- data/docs/Tasker/TaskerRailsSchema/UnknownInterfaceError.html +132 -0
- data/docs/Tasker/TaskerRailsSchema.html +384 -0
- data/docs/Tasker/TasksController.html +595 -0
- data/docs/Tasker/Telemetry/EventMapping.html +1307 -0
- data/docs/Tasker/Telemetry/EventRouter.html +2178 -0
- data/docs/Tasker/Telemetry/Events/ExportEvents.html +246 -0
- data/docs/Tasker/Telemetry/Events.html +115 -0
- data/docs/Tasker/Telemetry/ExportCoordinator/DistributedLockTimeoutError.html +135 -0
- data/docs/Tasker/Telemetry/ExportCoordinator.html +2137 -0
- data/docs/Tasker/Telemetry/IntelligentCacheManager.html +1083 -0
- data/docs/Tasker/Telemetry/LogBackend.html +1088 -0
- data/docs/Tasker/Telemetry/MetricTypes/Counter.html +1054 -0
- data/docs/Tasker/Telemetry/MetricTypes/Gauge.html +1270 -0
- data/docs/Tasker/Telemetry/MetricTypes/Histogram.html +1492 -0
- data/docs/Tasker/Telemetry/MetricTypes.html +153 -0
- data/docs/Tasker/Telemetry/MetricsBackend.html +2510 -0
- data/docs/Tasker/Telemetry/MetricsExportService.html +578 -0
- data/docs/Tasker/Telemetry/PluginRegistry.html +1774 -0
- data/docs/Tasker/Telemetry/Plugins/BaseExporter.html +1835 -0
- data/docs/Tasker/Telemetry/Plugins/CsvExporter.html +768 -0
- data/docs/Tasker/Telemetry/Plugins/JsonExporter.html +747 -0
- data/docs/Tasker/Telemetry/Plugins.html +117 -0
- data/docs/Tasker/Telemetry/PrometheusExporter.html +481 -0
- data/docs/Tasker/Telemetry/TraceBackend.html +891 -0
- data/docs/Tasker/Telemetry.html +130 -0
- data/docs/Tasker/Types/AuthConfig.html +886 -0
- data/docs/Tasker/Types/BackoffConfig.html +1063 -0
- data/docs/Tasker/Types/BaseConfig.html +227 -0
- data/docs/Tasker/Types/CacheConfig.html +1731 -0
- data/docs/Tasker/Types/DatabaseConfig.html +388 -0
- data/docs/Tasker/Types/DependencyGraph.html +526 -0
- data/docs/Tasker/Types/DependencyGraphConfig.html +753 -0
- data/docs/Tasker/Types/EngineConfig.html +1181 -0
- data/docs/Tasker/Types/ExecutionConfig.html +1963 -0
- data/docs/Tasker/Types/GraphEdge.html +517 -0
- data/docs/Tasker/Types/GraphMetadata.html +781 -0
- data/docs/Tasker/Types/GraphNode.html +694 -0
- data/docs/Tasker/Types/HealthConfig.html +784 -0
- data/docs/Tasker/Types/StepSequence.html +353 -0
- data/docs/Tasker/Types/StepTemplate.html +1193 -0
- data/docs/Tasker/Types/TaskRequest.html +1179 -0
- data/docs/Tasker/Types/TelemetryConfig.html +2746 -0
- data/docs/Tasker/Types.html +154 -0
- data/docs/Tasker/WorkflowStep/StepFinder.html +282 -0
- data/docs/Tasker/WorkflowStep.html +2724 -0
- data/docs/Tasker/WorkflowStepEdge.html +304 -0
- data/docs/Tasker/WorkflowStepSerializer.html +305 -0
- data/docs/Tasker/WorkflowStepTransition/TransitionDescriptionFormatter.html +282 -0
- data/docs/Tasker/WorkflowStepTransition.html +2201 -0
- data/docs/Tasker/WorkflowStepsController.html +462 -0
- data/docs/Tasker.html +452 -0
- data/docs/VISION.md +584 -0
- data/docs/WHY.md +21 -0
- data/docs/_index.html +2375 -0
- data/docs/class_list.html +54 -0
- data/docs/css/common.css +1 -0
- data/docs/css/full_list.css +58 -0
- data/docs/css/style.css +503 -0
- data/docs/events/migration_plan_outcomes.md +80 -0
- data/docs/file.README.html +541 -0
- data/docs/file_list.html +59 -0
- data/docs/frames.html +22 -0
- data/docs/index.html +541 -0
- data/docs/js/app.js +344 -0
- data/docs/js/full_list.js +242 -0
- data/docs/js/jquery.js +4 -0
- data/docs/method_list.html +9182 -0
- data/docs/top-level-namespace.html +110 -0
- data/lib/generators/tasker/authenticator_generator.rb +301 -0
- data/lib/generators/tasker/authorization_coordinator_generator.rb +139 -0
- data/lib/generators/tasker/events_generator.rb +91 -0
- data/lib/generators/tasker/subscriber_generator.rb +107 -0
- data/lib/generators/tasker/task_handler_generator.rb +138 -0
- data/lib/generators/tasker/templates/api_token_authenticator.rb.erb +113 -0
- data/lib/generators/tasker/templates/api_token_authenticator_spec.rb.erb +144 -0
- data/lib/generators/tasker/templates/authorization_coordinator.rb.erb +95 -0
- data/lib/generators/tasker/templates/authorization_coordinator_spec.rb.erb +142 -0
- data/lib/generators/tasker/templates/custom_authenticator.rb.erb +108 -0
- data/lib/generators/tasker/templates/custom_authenticator_spec.rb.erb +162 -0
- data/lib/generators/tasker/templates/custom_events.yml.erb +62 -0
- data/lib/generators/tasker/templates/custom_subscriber.rb.erb +72 -0
- data/lib/generators/tasker/templates/devise_authenticator.rb.erb +101 -0
- data/lib/generators/tasker/templates/devise_authenticator_spec.rb.erb +126 -0
- data/lib/generators/tasker/templates/initialize.rb.erb +202 -0
- data/lib/generators/tasker/templates/jwt_authenticator.rb.erb +144 -0
- data/lib/generators/tasker/templates/jwt_authenticator_spec.rb.erb +298 -0
- data/lib/generators/tasker/templates/metrics_subscriber.rb.erb +258 -0
- data/lib/generators/tasker/templates/metrics_subscriber_spec.rb.erb +308 -0
- data/lib/generators/tasker/templates/omniauth_authenticator.rb.erb +135 -0
- data/lib/generators/tasker/templates/omniauth_authenticator_spec.rb.erb +196 -0
- data/lib/generators/tasker/templates/opentelemetry_initializer.rb +52 -0
- data/lib/generators/tasker/templates/subscriber.rb.erb +64 -0
- data/lib/generators/tasker/templates/subscriber_spec.rb.erb +80 -0
- data/lib/generators/tasker/templates/task_config.yaml.erb +117 -0
- data/lib/generators/tasker/templates/task_handler.rb.erb +59 -0
- data/lib/generators/tasker/templates/task_handler_spec.rb.erb +159 -0
- data/lib/tasker/analysis/runtime_graph_analyzer.rb +1168 -0
- data/lib/tasker/analysis/template_graph_analyzer.rb +328 -0
- data/lib/tasker/authentication/coordinator.rb +78 -0
- data/lib/tasker/authentication/errors.rb +9 -0
- data/lib/tasker/authentication/interface.rb +36 -0
- data/lib/tasker/authentication/none_authenticator.rb +26 -0
- data/lib/tasker/authorization/base_coordinator.rb +112 -0
- data/lib/tasker/authorization/errors.rb +26 -0
- data/lib/tasker/authorization/resource_constants.rb +74 -0
- data/lib/tasker/authorization/resource_registry.rb +143 -0
- data/lib/tasker/authorization.rb +75 -0
- data/lib/tasker/cache_capabilities.rb +131 -0
- data/lib/tasker/cache_strategy.rb +469 -0
- data/lib/tasker/concerns/authenticatable.rb +41 -0
- data/lib/tasker/concerns/authorizable.rb +204 -0
- data/lib/tasker/concerns/controller_authorizable.rb +124 -0
- data/lib/tasker/concerns/event_publisher.rb +716 -0
- data/lib/tasker/concerns/idempotent_state_transitions.rb +128 -0
- data/lib/tasker/concerns/state_machine_base.rb +218 -0
- data/lib/tasker/concerns/structured_logging.rb +387 -0
- data/lib/tasker/configuration.rb +325 -0
- data/lib/tasker/constants/event_definitions.rb +147 -0
- data/lib/tasker/constants/registry_events.rb +54 -0
- data/lib/tasker/constants.rb +417 -0
- data/lib/tasker/engine.rb +90 -0
- data/lib/tasker/errors.rb +90 -0
- data/lib/tasker/events/catalog.rb +432 -0
- data/lib/tasker/events/custom_registry.rb +175 -0
- data/lib/tasker/events/definition_loader.rb +199 -0
- data/lib/tasker/events/event_payload_builder.rb +461 -0
- data/lib/tasker/events/publisher.rb +149 -0
- data/lib/tasker/events/subscribers/base_subscriber.rb +601 -0
- data/lib/tasker/events/subscribers/metrics_subscriber.rb +120 -0
- data/lib/tasker/events/subscribers/telemetry_subscriber.rb +462 -0
- data/lib/tasker/events/subscription_loader.rb +161 -0
- data/lib/tasker/events.rb +37 -0
- data/lib/tasker/functions/function_based_analytics_metrics.rb +103 -0
- data/lib/tasker/functions/function_based_dependency_levels.rb +54 -0
- data/lib/tasker/functions/function_based_slowest_steps.rb +84 -0
- data/lib/tasker/functions/function_based_slowest_tasks.rb +84 -0
- data/lib/tasker/functions/function_based_step_readiness_status.rb +183 -0
- data/lib/tasker/functions/function_based_system_health_counts.rb +94 -0
- data/lib/tasker/functions/function_based_task_execution_context.rb +148 -0
- data/lib/tasker/functions/function_wrapper.rb +42 -0
- data/lib/tasker/functions.rb +12 -0
- data/lib/tasker/handler_factory.rb +322 -0
- data/lib/tasker/health/readiness_checker.rb +186 -0
- data/lib/tasker/health/status_checker.rb +203 -0
- data/lib/tasker/identity_strategy.rb +38 -0
- data/lib/tasker/logging/correlation_id_generator.rb +120 -0
- data/lib/tasker/orchestration/backoff_calculator.rb +184 -0
- data/lib/tasker/orchestration/connection_builder.rb +122 -0
- data/lib/tasker/orchestration/connection_pool_intelligence.rb +177 -0
- data/lib/tasker/orchestration/coordinator.rb +119 -0
- data/lib/tasker/orchestration/future_state_analyzer.rb +137 -0
- data/lib/tasker/orchestration/plugin_integration.rb +124 -0
- data/lib/tasker/orchestration/response_processor.rb +168 -0
- data/lib/tasker/orchestration/retry_header_parser.rb +78 -0
- data/lib/tasker/orchestration/step_executor.rb +941 -0
- data/lib/tasker/orchestration/step_sequence_factory.rb +67 -0
- data/lib/tasker/orchestration/task_finalizer.rb +564 -0
- data/lib/tasker/orchestration/task_initializer.rb +140 -0
- data/lib/tasker/orchestration/task_reenqueuer.rb +71 -0
- data/lib/tasker/orchestration/viable_step_discovery.rb +65 -0
- data/lib/tasker/orchestration/workflow_coordinator.rb +294 -0
- data/lib/tasker/orchestration.rb +45 -0
- data/lib/tasker/railtie.rb +9 -0
- data/lib/tasker/registry/base_registry.rb +177 -0
- data/lib/tasker/registry/event_publisher.rb +91 -0
- data/lib/tasker/registry/interface_validator.rb +140 -0
- data/lib/tasker/registry/statistics_collector.rb +381 -0
- data/lib/tasker/registry/subscriber_registry.rb +285 -0
- data/lib/tasker/registry.rb +22 -0
- data/lib/tasker/state_machine/step_state_machine.rb +508 -0
- data/lib/tasker/state_machine/task_state_machine.rb +192 -0
- data/lib/tasker/state_machine.rb +83 -0
- data/lib/tasker/step_handler/api.rb +410 -0
- data/lib/tasker/step_handler/base.rb +206 -0
- data/lib/tasker/task_builder.rb +432 -0
- data/lib/tasker/task_handler/class_methods.rb +324 -0
- data/lib/tasker/task_handler/instance_methods.rb +293 -0
- data/lib/tasker/task_handler/step_group.rb +182 -0
- data/lib/tasker/task_handler.rb +43 -0
- data/lib/tasker/telemetry/event_mapping.rb +126 -0
- data/lib/tasker/telemetry/event_router.rb +318 -0
- data/lib/tasker/telemetry/events/export_events.rb +38 -0
- data/lib/tasker/telemetry/export_coordinator.rb +497 -0
- data/lib/tasker/telemetry/intelligent_cache_manager.rb +508 -0
- data/lib/tasker/telemetry/log_backend.rb +224 -0
- data/lib/tasker/telemetry/metric_types.rb +368 -0
- data/lib/tasker/telemetry/metrics_backend.rb +1227 -0
- data/lib/tasker/telemetry/metrics_export_service.rb +392 -0
- data/lib/tasker/telemetry/plugin_registry.rb +333 -0
- data/lib/tasker/telemetry/plugins/base_exporter.rb +246 -0
- data/lib/tasker/telemetry/plugins/csv_exporter.rb +198 -0
- data/lib/tasker/telemetry/plugins/json_exporter.rb +141 -0
- data/lib/tasker/telemetry/prometheus_exporter.rb +249 -0
- data/lib/tasker/telemetry/trace_backend.rb +186 -0
- data/lib/tasker/telemetry.rb +59 -0
- data/lib/tasker/types/auth_config.rb +81 -0
- data/lib/tasker/types/backoff_config.rb +142 -0
- data/lib/tasker/types/cache_config.rb +257 -0
- data/lib/tasker/types/database_config.rb +39 -0
- data/lib/tasker/types/dependency_graph.rb +225 -0
- data/lib/tasker/types/dependency_graph_config.rb +149 -0
- data/lib/tasker/types/engine_config.rb +131 -0
- data/lib/tasker/types/execution_config.rb +289 -0
- data/lib/tasker/types/health_config.rb +84 -0
- data/lib/tasker/types/step_sequence.rb +24 -0
- data/lib/tasker/types/step_template.rb +63 -0
- data/lib/tasker/types/task_request.rb +60 -0
- data/lib/tasker/types/telemetry_config.rb +273 -0
- data/lib/tasker/types.rb +64 -0
- data/lib/tasker/version.rb +7 -0
- data/lib/tasker.rb +82 -0
- data/lib/tasks/tasker_tasks.rake +302 -0
- metadata +958 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
-- Slowest Tasks Analysis Function
|
2
|
+
-- Returns the slowest tasks within a specified time period with performance metrics
|
3
|
+
-- Input: since_timestamp, limit_count, and optional namespace/name/version filters
|
4
|
+
-- Output: Ranked list of slowest tasks with duration and context
|
5
|
+
|
6
|
+
CREATE OR REPLACE FUNCTION get_slowest_tasks_v01(
|
7
|
+
since_timestamp TIMESTAMPTZ DEFAULT NULL,
|
8
|
+
limit_count INTEGER DEFAULT 10,
|
9
|
+
namespace_filter TEXT DEFAULT NULL,
|
10
|
+
task_name_filter TEXT DEFAULT NULL,
|
11
|
+
version_filter TEXT DEFAULT NULL
|
12
|
+
)
|
13
|
+
RETURNS TABLE (
|
14
|
+
task_id BIGINT,
|
15
|
+
task_name VARCHAR(64),
|
16
|
+
namespace_name VARCHAR(64),
|
17
|
+
version VARCHAR(64),
|
18
|
+
duration_seconds NUMERIC(10,3),
|
19
|
+
step_count BIGINT,
|
20
|
+
completed_steps BIGINT,
|
21
|
+
error_steps BIGINT,
|
22
|
+
created_at TIMESTAMPTZ,
|
23
|
+
completed_at TIMESTAMPTZ,
|
24
|
+
initiator VARCHAR(128),
|
25
|
+
source_system VARCHAR(128)
|
26
|
+
) LANGUAGE plpgsql STABLE AS $$
|
27
|
+
DECLARE
|
28
|
+
analysis_start TIMESTAMPTZ;
|
29
|
+
BEGIN
|
30
|
+
-- Set analysis start time (default to 24 hours ago if not provided)
|
31
|
+
analysis_start := COALESCE(since_timestamp, NOW() - INTERVAL '24 hours');
|
32
|
+
|
33
|
+
RETURN QUERY
|
34
|
+
WITH task_durations AS (
|
35
|
+
SELECT
|
36
|
+
t.task_id,
|
37
|
+
nt.name as task_name,
|
38
|
+
tn.name as namespace_name,
|
39
|
+
nt.version,
|
40
|
+
t.created_at,
|
41
|
+
t.initiator,
|
42
|
+
t.source_system,
|
43
|
+
-- Find the latest completion time across all steps
|
44
|
+
MAX(wst.created_at) FILTER (
|
45
|
+
WHERE wst.to_state IN ('complete', 'error') AND wst.most_recent = true
|
46
|
+
) as latest_completion,
|
47
|
+
-- Calculate duration from task creation to latest step completion
|
48
|
+
EXTRACT(EPOCH FROM (
|
49
|
+
MAX(wst.created_at) FILTER (
|
50
|
+
WHERE wst.to_state IN ('complete', 'error') AND wst.most_recent = true
|
51
|
+
) - t.created_at
|
52
|
+
)) as duration_seconds,
|
53
|
+
COUNT(ws.workflow_step_id) as total_steps,
|
54
|
+
COUNT(ws.workflow_step_id) FILTER (
|
55
|
+
WHERE complete_wst.to_state = 'complete' AND complete_wst.most_recent = true
|
56
|
+
) as completed_step_count,
|
57
|
+
COUNT(ws.workflow_step_id) FILTER (
|
58
|
+
WHERE error_wst.to_state = 'error' AND error_wst.most_recent = true
|
59
|
+
) as error_step_count
|
60
|
+
FROM tasker_tasks t
|
61
|
+
INNER JOIN tasker_named_tasks nt ON nt.named_task_id = t.named_task_id
|
62
|
+
INNER JOIN tasker_task_namespaces tn ON tn.task_namespace_id = nt.task_namespace_id
|
63
|
+
INNER JOIN tasker_workflow_steps ws ON ws.task_id = t.task_id
|
64
|
+
LEFT JOIN tasker_workflow_step_transitions wst ON wst.workflow_step_id = ws.workflow_step_id
|
65
|
+
LEFT JOIN tasker_workflow_step_transitions complete_wst ON complete_wst.workflow_step_id = ws.workflow_step_id
|
66
|
+
AND complete_wst.to_state = 'complete' AND complete_wst.most_recent = true
|
67
|
+
LEFT JOIN tasker_workflow_step_transitions error_wst ON error_wst.workflow_step_id = ws.workflow_step_id
|
68
|
+
AND error_wst.to_state = 'error' AND error_wst.most_recent = true
|
69
|
+
WHERE t.created_at > analysis_start
|
70
|
+
AND (namespace_filter IS NULL OR tn.name = namespace_filter)
|
71
|
+
AND (task_name_filter IS NULL OR nt.name = task_name_filter)
|
72
|
+
AND (version_filter IS NULL OR nt.version = version_filter)
|
73
|
+
GROUP BY t.task_id, nt.name, tn.name, nt.version, t.created_at, t.initiator, t.source_system
|
74
|
+
HAVING MAX(wst.created_at) FILTER (
|
75
|
+
WHERE wst.to_state IN ('complete', 'error') AND wst.most_recent = true
|
76
|
+
) IS NOT NULL -- Only include tasks that have at least one completed/failed step
|
77
|
+
)
|
78
|
+
SELECT
|
79
|
+
td.task_id,
|
80
|
+
td.task_name,
|
81
|
+
td.namespace_name,
|
82
|
+
td.version,
|
83
|
+
ROUND(td.duration_seconds, 3),
|
84
|
+
td.total_steps,
|
85
|
+
td.completed_step_count,
|
86
|
+
td.error_step_count,
|
87
|
+
td.created_at,
|
88
|
+
td.latest_completion,
|
89
|
+
td.initiator,
|
90
|
+
td.source_system
|
91
|
+
FROM task_durations td
|
92
|
+
WHERE td.duration_seconds IS NOT NULL
|
93
|
+
ORDER BY td.duration_seconds DESC
|
94
|
+
LIMIT limit_count;
|
95
|
+
END;
|
96
|
+
$$;
|
@@ -0,0 +1,140 @@
|
|
1
|
+
-- Batch Step Readiness Status Function
|
2
|
+
-- Gets step readiness data for multiple tasks in a single query
|
3
|
+
-- Input: Array of task_ids (gets all steps for each task)
|
4
|
+
-- Output: Multiple rows with step readiness data, properly grouped by task
|
5
|
+
|
6
|
+
CREATE OR REPLACE FUNCTION get_step_readiness_status_batch(input_task_ids BIGINT[])
|
7
|
+
RETURNS TABLE(
|
8
|
+
workflow_step_id BIGINT,
|
9
|
+
task_id BIGINT,
|
10
|
+
named_step_id INTEGER,
|
11
|
+
name TEXT,
|
12
|
+
current_state TEXT,
|
13
|
+
dependencies_satisfied BOOLEAN,
|
14
|
+
retry_eligible BOOLEAN,
|
15
|
+
ready_for_execution BOOLEAN,
|
16
|
+
last_failure_at TIMESTAMP,
|
17
|
+
next_retry_at TIMESTAMP,
|
18
|
+
total_parents INTEGER,
|
19
|
+
completed_parents INTEGER,
|
20
|
+
attempts INTEGER,
|
21
|
+
retry_limit INTEGER,
|
22
|
+
backoff_request_seconds INTEGER,
|
23
|
+
last_attempted_at TIMESTAMP
|
24
|
+
) LANGUAGE plpgsql STABLE AS $$
|
25
|
+
BEGIN
|
26
|
+
RETURN QUERY
|
27
|
+
SELECT
|
28
|
+
ws.workflow_step_id,
|
29
|
+
ws.task_id,
|
30
|
+
ws.named_step_id,
|
31
|
+
ns.name::TEXT,
|
32
|
+
|
33
|
+
-- Current State Information (optimized using most_recent flag)
|
34
|
+
COALESCE(current_state.to_state, 'pending')::TEXT as current_state,
|
35
|
+
|
36
|
+
-- Dependency Analysis (calculated from direct joins)
|
37
|
+
CASE
|
38
|
+
WHEN dep_edges.to_step_id IS NULL THEN true -- Root steps (no parents)
|
39
|
+
WHEN COUNT(dep_edges.from_step_id) = 0 THEN true -- Steps with zero dependencies
|
40
|
+
WHEN COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id) THEN true
|
41
|
+
ELSE false
|
42
|
+
END as dependencies_satisfied,
|
43
|
+
|
44
|
+
-- Simplified Retry & Backoff Analysis
|
45
|
+
CASE
|
46
|
+
WHEN ws.attempts >= COALESCE(ws.retry_limit, 3) THEN false
|
47
|
+
WHEN ws.attempts > 0 AND COALESCE(ws.retryable, true) = false THEN false
|
48
|
+
WHEN last_failure.created_at IS NULL THEN true
|
49
|
+
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
50
|
+
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second') <= NOW()
|
51
|
+
WHEN last_failure.created_at IS NOT NULL THEN
|
52
|
+
last_failure.created_at + (
|
53
|
+
LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds')
|
54
|
+
) <= NOW()
|
55
|
+
ELSE true
|
56
|
+
END as retry_eligible,
|
57
|
+
|
58
|
+
-- Simplified Final Readiness Calculation
|
59
|
+
CASE
|
60
|
+
WHEN COALESCE(current_state.to_state, 'pending') IN ('pending', 'error')
|
61
|
+
AND (ws.processed = false OR ws.processed IS NULL) -- CRITICAL: Only unprocessed steps can be ready
|
62
|
+
AND (dep_edges.to_step_id IS NULL OR
|
63
|
+
COUNT(dep_edges.from_step_id) = 0 OR
|
64
|
+
COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id))
|
65
|
+
AND (ws.attempts < COALESCE(ws.retry_limit, 3))
|
66
|
+
AND (COALESCE(ws.retryable, true) = true)
|
67
|
+
AND (ws.in_process = false OR ws.in_process IS NULL)
|
68
|
+
AND (
|
69
|
+
-- Check explicit backoff timing (most restrictive)
|
70
|
+
-- If backoff is set, the backoff period must have expired
|
71
|
+
CASE
|
72
|
+
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
73
|
+
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second') <= NOW()
|
74
|
+
ELSE true -- No explicit backoff set
|
75
|
+
END
|
76
|
+
AND
|
77
|
+
-- Then check failure-based backoff
|
78
|
+
(last_failure.created_at IS NULL OR
|
79
|
+
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds')) <= NOW())
|
80
|
+
)
|
81
|
+
THEN true
|
82
|
+
ELSE false
|
83
|
+
END as ready_for_execution,
|
84
|
+
|
85
|
+
-- Timing Information
|
86
|
+
last_failure.created_at as last_failure_at,
|
87
|
+
CASE
|
88
|
+
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
89
|
+
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second')
|
90
|
+
WHEN last_failure.created_at IS NOT NULL THEN
|
91
|
+
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds'))
|
92
|
+
ELSE NULL
|
93
|
+
END as next_retry_at,
|
94
|
+
|
95
|
+
-- Dependency Context (calculated from joins)
|
96
|
+
COALESCE(COUNT(dep_edges.from_step_id), 0)::INTEGER as total_parents,
|
97
|
+
COALESCE(COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END), 0)::INTEGER as completed_parents,
|
98
|
+
|
99
|
+
-- Retry Context
|
100
|
+
ws.attempts,
|
101
|
+
COALESCE(ws.retry_limit, 3) as retry_limit,
|
102
|
+
ws.backoff_request_seconds,
|
103
|
+
ws.last_attempted_at
|
104
|
+
|
105
|
+
FROM tasker_workflow_steps ws
|
106
|
+
JOIN tasker_named_steps ns ON ns.named_step_id = ws.named_step_id
|
107
|
+
|
108
|
+
-- OPTIMIZED: Current State using most_recent flag instead of DISTINCT ON
|
109
|
+
LEFT JOIN tasker_workflow_step_transitions current_state
|
110
|
+
ON current_state.workflow_step_id = ws.workflow_step_id
|
111
|
+
AND current_state.most_recent = true
|
112
|
+
|
113
|
+
-- OPTIMIZED: Dependency check using direct joins (no subquery)
|
114
|
+
LEFT JOIN tasker_workflow_step_edges dep_edges
|
115
|
+
ON dep_edges.to_step_id = ws.workflow_step_id
|
116
|
+
LEFT JOIN tasker_workflow_step_transitions parent_states
|
117
|
+
ON parent_states.workflow_step_id = dep_edges.from_step_id
|
118
|
+
AND parent_states.most_recent = true
|
119
|
+
|
120
|
+
-- OPTIMIZED: Last failure using index-optimized approach
|
121
|
+
LEFT JOIN tasker_workflow_step_transitions last_failure
|
122
|
+
ON last_failure.workflow_step_id = ws.workflow_step_id
|
123
|
+
AND last_failure.to_state = 'error'
|
124
|
+
AND last_failure.most_recent = true
|
125
|
+
|
126
|
+
-- KEY PERFORMANCE IMPROVEMENT: Filter by multiple tasks at once
|
127
|
+
-- CRITICAL FIX: Include ALL steps for task execution context calculation
|
128
|
+
-- Only filter by processed status when specifically querying for ready steps
|
129
|
+
WHERE ws.task_id = ANY(input_task_ids)
|
130
|
+
|
131
|
+
GROUP BY
|
132
|
+
ws.workflow_step_id, ws.task_id, ws.named_step_id, ns.name,
|
133
|
+
current_state.to_state, last_failure.created_at,
|
134
|
+
ws.attempts, ws.retry_limit, ws.backoff_request_seconds, ws.last_attempted_at,
|
135
|
+
ws.in_process, ws.processed, ws.retryable, dep_edges.to_step_id
|
136
|
+
|
137
|
+
-- IMPORTANT: Order by task_id, then workflow_step_id for consistent grouping
|
138
|
+
ORDER BY ws.task_id, ws.workflow_step_id;
|
139
|
+
END;
|
140
|
+
$$;
|
@@ -0,0 +1,139 @@
|
|
1
|
+
-- Step Readiness Status Function
|
2
|
+
-- Converts the view logic to a parameterized function for targeted queries
|
3
|
+
-- Input: Array of workflow_step_ids
|
4
|
+
-- Output: Readiness data for specified steps only
|
5
|
+
|
6
|
+
CREATE OR REPLACE FUNCTION get_step_readiness_status(input_task_id BIGINT, step_ids BIGINT[] DEFAULT NULL)
|
7
|
+
RETURNS TABLE(
|
8
|
+
workflow_step_id BIGINT,
|
9
|
+
task_id BIGINT,
|
10
|
+
named_step_id INTEGER,
|
11
|
+
name TEXT,
|
12
|
+
current_state TEXT,
|
13
|
+
dependencies_satisfied BOOLEAN,
|
14
|
+
retry_eligible BOOLEAN,
|
15
|
+
ready_for_execution BOOLEAN,
|
16
|
+
last_failure_at TIMESTAMP,
|
17
|
+
next_retry_at TIMESTAMP,
|
18
|
+
total_parents INTEGER,
|
19
|
+
completed_parents INTEGER,
|
20
|
+
attempts INTEGER,
|
21
|
+
retry_limit INTEGER,
|
22
|
+
backoff_request_seconds INTEGER,
|
23
|
+
last_attempted_at TIMESTAMP
|
24
|
+
) LANGUAGE plpgsql STABLE AS $$
|
25
|
+
BEGIN
|
26
|
+
RETURN QUERY
|
27
|
+
SELECT
|
28
|
+
ws.workflow_step_id,
|
29
|
+
ws.task_id,
|
30
|
+
ws.named_step_id,
|
31
|
+
ns.name::TEXT,
|
32
|
+
|
33
|
+
-- Current State Information (optimized using most_recent flag)
|
34
|
+
COALESCE(current_state.to_state, 'pending')::TEXT as current_state,
|
35
|
+
|
36
|
+
-- Dependency Analysis (calculated from direct joins)
|
37
|
+
CASE
|
38
|
+
WHEN dep_edges.to_step_id IS NULL THEN true -- Root steps (no parents)
|
39
|
+
WHEN COUNT(dep_edges.from_step_id) = 0 THEN true -- Steps with zero dependencies
|
40
|
+
WHEN COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id) THEN true
|
41
|
+
ELSE false
|
42
|
+
END as dependencies_satisfied,
|
43
|
+
|
44
|
+
-- Simplified Retry & Backoff Analysis
|
45
|
+
CASE
|
46
|
+
WHEN ws.attempts >= COALESCE(ws.retry_limit, 3) THEN false
|
47
|
+
WHEN ws.attempts > 0 AND COALESCE(ws.retryable, true) = false THEN false
|
48
|
+
WHEN last_failure.created_at IS NULL THEN true
|
49
|
+
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
50
|
+
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second') <= NOW()
|
51
|
+
WHEN last_failure.created_at IS NOT NULL THEN
|
52
|
+
last_failure.created_at + (
|
53
|
+
LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds')
|
54
|
+
) <= NOW()
|
55
|
+
ELSE true
|
56
|
+
END as retry_eligible,
|
57
|
+
|
58
|
+
-- Simplified Final Readiness Calculation
|
59
|
+
CASE
|
60
|
+
WHEN COALESCE(current_state.to_state, 'pending') IN ('pending', 'error')
|
61
|
+
AND (ws.processed = false OR ws.processed IS NULL) -- CRITICAL: Only unprocessed steps can be ready
|
62
|
+
AND (dep_edges.to_step_id IS NULL OR
|
63
|
+
COUNT(dep_edges.from_step_id) = 0 OR
|
64
|
+
COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id))
|
65
|
+
AND (ws.attempts < COALESCE(ws.retry_limit, 3))
|
66
|
+
AND (COALESCE(ws.retryable, true) = true)
|
67
|
+
AND (ws.in_process = false OR ws.in_process IS NULL)
|
68
|
+
AND (
|
69
|
+
-- Check explicit backoff timing (most restrictive)
|
70
|
+
-- If backoff is set, the backoff period must have expired
|
71
|
+
CASE
|
72
|
+
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
73
|
+
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second') <= NOW()
|
74
|
+
ELSE true -- No explicit backoff set
|
75
|
+
END
|
76
|
+
AND
|
77
|
+
-- Then check failure-based backoff
|
78
|
+
(last_failure.created_at IS NULL OR
|
79
|
+
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds')) <= NOW())
|
80
|
+
)
|
81
|
+
THEN true
|
82
|
+
ELSE false
|
83
|
+
END as ready_for_execution,
|
84
|
+
|
85
|
+
-- Timing Information
|
86
|
+
last_failure.created_at as last_failure_at,
|
87
|
+
CASE
|
88
|
+
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
89
|
+
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second')
|
90
|
+
WHEN last_failure.created_at IS NOT NULL THEN
|
91
|
+
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds'))
|
92
|
+
ELSE NULL
|
93
|
+
END as next_retry_at,
|
94
|
+
|
95
|
+
-- Dependency Context (calculated from joins)
|
96
|
+
COALESCE(COUNT(dep_edges.from_step_id), 0)::INTEGER as total_parents,
|
97
|
+
COALESCE(COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END), 0)::INTEGER as completed_parents,
|
98
|
+
|
99
|
+
-- Retry Context
|
100
|
+
ws.attempts,
|
101
|
+
COALESCE(ws.retry_limit, 3) as retry_limit,
|
102
|
+
ws.backoff_request_seconds,
|
103
|
+
ws.last_attempted_at
|
104
|
+
|
105
|
+
FROM tasker_workflow_steps ws
|
106
|
+
JOIN tasker_named_steps ns ON ns.named_step_id = ws.named_step_id
|
107
|
+
|
108
|
+
-- OPTIMIZED: Current State using most_recent flag instead of DISTINCT ON
|
109
|
+
LEFT JOIN tasker_workflow_step_transitions current_state
|
110
|
+
ON current_state.workflow_step_id = ws.workflow_step_id
|
111
|
+
AND current_state.most_recent = true
|
112
|
+
|
113
|
+
-- OPTIMIZED: Dependency check using direct joins (no subquery)
|
114
|
+
LEFT JOIN tasker_workflow_step_edges dep_edges
|
115
|
+
ON dep_edges.to_step_id = ws.workflow_step_id
|
116
|
+
LEFT JOIN tasker_workflow_step_transitions parent_states
|
117
|
+
ON parent_states.workflow_step_id = dep_edges.from_step_id
|
118
|
+
AND parent_states.most_recent = true
|
119
|
+
|
120
|
+
-- OPTIMIZED: Last failure using index-optimized approach
|
121
|
+
LEFT JOIN tasker_workflow_step_transitions last_failure
|
122
|
+
ON last_failure.workflow_step_id = ws.workflow_step_id
|
123
|
+
AND last_failure.to_state = 'error'
|
124
|
+
AND last_failure.most_recent = true
|
125
|
+
|
126
|
+
-- KEY PERFORMANCE IMPROVEMENT: Filter by task first, then optionally by step IDs
|
127
|
+
-- CRITICAL FIX: Include ALL steps for task execution context calculation
|
128
|
+
-- Only filter by processed status when specifically querying for ready steps
|
129
|
+
WHERE ws.task_id = input_task_id
|
130
|
+
AND (step_ids IS NULL OR ws.workflow_step_id = ANY(step_ids))
|
131
|
+
|
132
|
+
GROUP BY
|
133
|
+
ws.workflow_step_id, ws.task_id, ws.named_step_id, ns.name,
|
134
|
+
current_state.to_state, last_failure.created_at,
|
135
|
+
ws.attempts, ws.retry_limit, ws.backoff_request_seconds, ws.last_attempted_at,
|
136
|
+
ws.in_process, ws.processed, ws.retryable, dep_edges.to_step_id,
|
137
|
+
current_state.workflow_step_id, last_failure.workflow_step_id;
|
138
|
+
END;
|
139
|
+
$$;
|
@@ -0,0 +1,108 @@
|
|
1
|
+
-- System Health Counts Function
|
2
|
+
-- Returns comprehensive system health metrics in a single query
|
3
|
+
-- No input parameters needed - returns system-wide counts
|
4
|
+
-- Output: Single row with all health counts and metrics
|
5
|
+
|
6
|
+
CREATE OR REPLACE FUNCTION get_system_health_counts_v01()
|
7
|
+
RETURNS TABLE (
|
8
|
+
-- Task counts
|
9
|
+
total_tasks BIGINT,
|
10
|
+
pending_tasks BIGINT,
|
11
|
+
in_progress_tasks BIGINT,
|
12
|
+
complete_tasks BIGINT,
|
13
|
+
error_tasks BIGINT,
|
14
|
+
cancelled_tasks BIGINT,
|
15
|
+
|
16
|
+
-- Step counts
|
17
|
+
total_steps BIGINT,
|
18
|
+
pending_steps BIGINT,
|
19
|
+
in_progress_steps BIGINT,
|
20
|
+
complete_steps BIGINT,
|
21
|
+
error_steps BIGINT,
|
22
|
+
|
23
|
+
-- Retry-specific counts
|
24
|
+
retryable_error_steps BIGINT,
|
25
|
+
exhausted_retry_steps BIGINT,
|
26
|
+
in_backoff_steps BIGINT,
|
27
|
+
|
28
|
+
-- Database metrics
|
29
|
+
active_connections BIGINT,
|
30
|
+
max_connections BIGINT
|
31
|
+
) LANGUAGE plpgsql STABLE AS $$
|
32
|
+
BEGIN
|
33
|
+
RETURN QUERY
|
34
|
+
WITH task_counts AS (
|
35
|
+
SELECT
|
36
|
+
COUNT(*) as total_tasks,
|
37
|
+
COUNT(*) FILTER (WHERE task_state.to_state = 'pending') as pending_tasks,
|
38
|
+
COUNT(*) FILTER (WHERE task_state.to_state = 'in_progress') as in_progress_tasks,
|
39
|
+
COUNT(*) FILTER (WHERE task_state.to_state = 'complete') as complete_tasks,
|
40
|
+
COUNT(*) FILTER (WHERE task_state.to_state = 'error') as error_tasks,
|
41
|
+
COUNT(*) FILTER (WHERE task_state.to_state = 'cancelled') as cancelled_tasks
|
42
|
+
FROM tasker_tasks t
|
43
|
+
LEFT JOIN tasker_task_transitions task_state ON task_state.task_id = t.task_id
|
44
|
+
AND task_state.most_recent = true
|
45
|
+
),
|
46
|
+
step_counts AS (
|
47
|
+
SELECT
|
48
|
+
COUNT(*) as total_steps,
|
49
|
+
COUNT(*) FILTER (WHERE step_state.to_state = 'pending') as pending_steps,
|
50
|
+
COUNT(*) FILTER (WHERE step_state.to_state = 'in_progress') as in_progress_steps,
|
51
|
+
COUNT(*) FILTER (WHERE step_state.to_state = 'complete') as complete_steps,
|
52
|
+
COUNT(*) FILTER (WHERE step_state.to_state = 'error') as error_steps,
|
53
|
+
|
54
|
+
-- Retry-specific logic - retryable errors
|
55
|
+
COUNT(*) FILTER (
|
56
|
+
WHERE step_state.to_state = 'error'
|
57
|
+
AND ws.attempts < ws.retry_limit
|
58
|
+
AND COALESCE(ws.retryable, true) = true
|
59
|
+
) as retryable_error_steps,
|
60
|
+
|
61
|
+
-- Exhausted retries
|
62
|
+
COUNT(*) FILTER (
|
63
|
+
WHERE step_state.to_state = 'error'
|
64
|
+
AND ws.attempts >= ws.retry_limit
|
65
|
+
) as exhausted_retry_steps,
|
66
|
+
|
67
|
+
-- In backoff (error state but not exhausted retries and has last_attempted_at)
|
68
|
+
COUNT(*) FILTER (
|
69
|
+
WHERE step_state.to_state = 'error'
|
70
|
+
AND ws.attempts < ws.retry_limit
|
71
|
+
AND COALESCE(ws.retryable, true) = true
|
72
|
+
AND ws.last_attempted_at IS NOT NULL
|
73
|
+
) as in_backoff_steps
|
74
|
+
|
75
|
+
FROM tasker_workflow_steps ws
|
76
|
+
LEFT JOIN tasker_workflow_step_transitions step_state ON step_state.workflow_step_id = ws.workflow_step_id
|
77
|
+
AND step_state.most_recent = true
|
78
|
+
),
|
79
|
+
connection_info AS (
|
80
|
+
SELECT
|
81
|
+
COUNT(*) as active_connections,
|
82
|
+
COALESCE((SELECT setting::BIGINT FROM pg_settings WHERE name = 'max_connections'), 0) as max_connections
|
83
|
+
FROM pg_stat_activity
|
84
|
+
WHERE datname = current_database()
|
85
|
+
AND state = 'active'
|
86
|
+
)
|
87
|
+
SELECT
|
88
|
+
tc.total_tasks,
|
89
|
+
tc.pending_tasks,
|
90
|
+
tc.in_progress_tasks,
|
91
|
+
tc.complete_tasks,
|
92
|
+
tc.error_tasks,
|
93
|
+
tc.cancelled_tasks,
|
94
|
+
sc.total_steps,
|
95
|
+
sc.pending_steps,
|
96
|
+
sc.in_progress_steps,
|
97
|
+
sc.complete_steps,
|
98
|
+
sc.error_steps,
|
99
|
+
sc.retryable_error_steps,
|
100
|
+
sc.exhausted_retry_steps,
|
101
|
+
sc.in_backoff_steps,
|
102
|
+
ci.active_connections,
|
103
|
+
ci.max_connections
|
104
|
+
FROM task_counts tc
|
105
|
+
CROSS JOIN step_counts sc
|
106
|
+
CROSS JOIN connection_info ci;
|
107
|
+
END;
|
108
|
+
$$;
|
@@ -0,0 +1,108 @@
|
|
1
|
+
-- Task Execution Context Function
|
2
|
+
-- Uses the step readiness function to build aggregated task context
|
3
|
+
-- Input: Single task_id
|
4
|
+
-- Output: Single row with task execution context
|
5
|
+
|
6
|
+
CREATE OR REPLACE FUNCTION get_task_execution_context(input_task_id BIGINT)
|
7
|
+
RETURNS TABLE(
|
8
|
+
task_id BIGINT,
|
9
|
+
named_task_id INTEGER,
|
10
|
+
status TEXT,
|
11
|
+
total_steps BIGINT,
|
12
|
+
pending_steps BIGINT,
|
13
|
+
in_progress_steps BIGINT,
|
14
|
+
completed_steps BIGINT,
|
15
|
+
failed_steps BIGINT,
|
16
|
+
ready_steps BIGINT,
|
17
|
+
execution_status TEXT,
|
18
|
+
recommended_action TEXT,
|
19
|
+
completion_percentage DECIMAL,
|
20
|
+
health_status TEXT
|
21
|
+
) LANGUAGE plpgsql STABLE AS $$
|
22
|
+
BEGIN
|
23
|
+
-- Use the step readiness function to get step data, then aggregate
|
24
|
+
-- The step readiness function handles the case where no steps exist
|
25
|
+
RETURN QUERY
|
26
|
+
WITH step_data AS (
|
27
|
+
SELECT * FROM get_step_readiness_status(input_task_id, NULL)
|
28
|
+
),
|
29
|
+
task_info AS (
|
30
|
+
SELECT
|
31
|
+
t.task_id,
|
32
|
+
t.named_task_id,
|
33
|
+
COALESCE(task_state.to_state, 'pending')::TEXT as current_status
|
34
|
+
FROM tasker_tasks t
|
35
|
+
LEFT JOIN tasker_task_transitions task_state
|
36
|
+
ON task_state.task_id = t.task_id
|
37
|
+
AND task_state.most_recent = true
|
38
|
+
WHERE t.task_id = input_task_id
|
39
|
+
),
|
40
|
+
aggregated_stats AS (
|
41
|
+
SELECT
|
42
|
+
COUNT(*) as total_steps,
|
43
|
+
COUNT(CASE WHEN sd.current_state = 'pending' THEN 1 END) as pending_steps,
|
44
|
+
COUNT(CASE WHEN sd.current_state = 'in_progress' THEN 1 END) as in_progress_steps,
|
45
|
+
COUNT(CASE WHEN sd.current_state IN ('complete', 'resolved_manually') THEN 1 END) as completed_steps,
|
46
|
+
COUNT(CASE WHEN sd.current_state = 'error' THEN 1 END) as failed_steps,
|
47
|
+
COUNT(CASE WHEN sd.ready_for_execution = true THEN 1 END) as ready_steps,
|
48
|
+
-- Count PERMANENTLY blocked failures (exhausted retries OR explicitly marked as not retryable)
|
49
|
+
COUNT(CASE WHEN sd.current_state = 'error'
|
50
|
+
AND (sd.attempts >= sd.retry_limit) THEN 1 END) as permanently_blocked_steps
|
51
|
+
FROM step_data sd
|
52
|
+
)
|
53
|
+
SELECT
|
54
|
+
ti.task_id,
|
55
|
+
ti.named_task_id,
|
56
|
+
ti.current_status as status,
|
57
|
+
|
58
|
+
-- Step Statistics
|
59
|
+
COALESCE(ast.total_steps, 0) as total_steps,
|
60
|
+
COALESCE(ast.pending_steps, 0) as pending_steps,
|
61
|
+
COALESCE(ast.in_progress_steps, 0) as in_progress_steps,
|
62
|
+
COALESCE(ast.completed_steps, 0) as completed_steps,
|
63
|
+
COALESCE(ast.failed_steps, 0) as failed_steps,
|
64
|
+
COALESCE(ast.ready_steps, 0) as ready_steps,
|
65
|
+
|
66
|
+
-- FIXED: Execution State Logic
|
67
|
+
CASE
|
68
|
+
WHEN COALESCE(ast.ready_steps, 0) > 0 THEN 'has_ready_steps'
|
69
|
+
WHEN COALESCE(ast.in_progress_steps, 0) > 0 THEN 'processing'
|
70
|
+
-- OLD BUG: WHEN COALESCE(ast.failed_steps, 0) > 0 AND COALESCE(ast.ready_steps, 0) = 0 THEN 'blocked_by_failures'
|
71
|
+
-- NEW FIX: Only blocked if failed steps are NOT retry-eligible
|
72
|
+
WHEN COALESCE(ast.permanently_blocked_steps, 0) > 0 AND COALESCE(ast.ready_steps, 0) = 0 THEN 'blocked_by_failures'
|
73
|
+
WHEN COALESCE(ast.completed_steps, 0) = COALESCE(ast.total_steps, 0) AND COALESCE(ast.total_steps, 0) > 0 THEN 'all_complete'
|
74
|
+
ELSE 'waiting_for_dependencies'
|
75
|
+
END as execution_status,
|
76
|
+
|
77
|
+
-- FIXED: Recommended Action Logic
|
78
|
+
CASE
|
79
|
+
WHEN COALESCE(ast.ready_steps, 0) > 0 THEN 'execute_ready_steps'
|
80
|
+
WHEN COALESCE(ast.in_progress_steps, 0) > 0 THEN 'wait_for_completion'
|
81
|
+
-- OLD BUG: WHEN COALESCE(ast.failed_steps, 0) > 0 AND COALESCE(ast.ready_steps, 0) = 0 THEN 'handle_failures'
|
82
|
+
-- NEW FIX: Only handle failures if they're truly blocked
|
83
|
+
WHEN COALESCE(ast.permanently_blocked_steps, 0) > 0 AND COALESCE(ast.ready_steps, 0) = 0 THEN 'handle_failures'
|
84
|
+
WHEN COALESCE(ast.completed_steps, 0) = COALESCE(ast.total_steps, 0) AND COALESCE(ast.total_steps, 0) > 0 THEN 'finalize_task'
|
85
|
+
ELSE 'wait_for_dependencies'
|
86
|
+
END as recommended_action,
|
87
|
+
|
88
|
+
-- Progress Metrics
|
89
|
+
CASE
|
90
|
+
WHEN COALESCE(ast.total_steps, 0) = 0 THEN 0.0
|
91
|
+
ELSE ROUND((COALESCE(ast.completed_steps, 0)::decimal / COALESCE(ast.total_steps, 1)::decimal) * 100, 2)
|
92
|
+
END as completion_percentage,
|
93
|
+
|
94
|
+
-- FIXED: Health Status Logic
|
95
|
+
CASE
|
96
|
+
WHEN COALESCE(ast.failed_steps, 0) = 0 THEN 'healthy'
|
97
|
+
WHEN COALESCE(ast.failed_steps, 0) > 0 AND COALESCE(ast.ready_steps, 0) > 0 THEN 'recovering'
|
98
|
+
-- NEW FIX: Only blocked if failures are truly not retry-eligible
|
99
|
+
WHEN COALESCE(ast.permanently_blocked_steps, 0) > 0 AND COALESCE(ast.ready_steps, 0) = 0 THEN 'blocked'
|
100
|
+
-- NEW: Waiting state for retry-eligible failures with backoff
|
101
|
+
WHEN COALESCE(ast.failed_steps, 0) > 0 AND COALESCE(ast.permanently_blocked_steps, 0) = 0 AND COALESCE(ast.ready_steps, 0) = 0 THEN 'recovering'
|
102
|
+
ELSE 'unknown'
|
103
|
+
END as health_status
|
104
|
+
|
105
|
+
FROM task_info ti
|
106
|
+
CROSS JOIN aggregated_stats ast;
|
107
|
+
END;
|
108
|
+
$$;
|