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,177 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tasker
|
4
|
+
module Orchestration
|
5
|
+
# Rails-Framework-Aligned Connection Management
|
6
|
+
#
|
7
|
+
# Provides intelligent assessment of database connection pool health and
|
8
|
+
# recommends safe concurrency levels that work WITH Rails connection pool
|
9
|
+
# rather than around it.
|
10
|
+
#
|
11
|
+
# Key Design Principles:
|
12
|
+
# - CONSTANTS: Ruby/Rails optimization characteristics (safety thresholds, precision)
|
13
|
+
# - CONFIGURABLE: Environment-dependent pressure response factors
|
14
|
+
# - Conservative safety margins to prevent connection exhaustion
|
15
|
+
# - Comprehensive structured logging for observability
|
16
|
+
#
|
17
|
+
# @example Basic usage
|
18
|
+
# health = ConnectionPoolIntelligence.assess_connection_health
|
19
|
+
# concurrency = ConnectionPoolIntelligence.intelligent_concurrency_for_step_executor
|
20
|
+
#
|
21
|
+
# @example With custom configuration
|
22
|
+
# config = Tasker.configuration.execution
|
23
|
+
# config.connection_pressure_factors = { high: 0.3, critical: 0.1 }
|
24
|
+
# concurrency = ConnectionPoolIntelligence.intelligent_concurrency_for_step_executor
|
25
|
+
class ConnectionPoolIntelligence
|
26
|
+
# ✅ CONSTANTS: Ruby/Rails optimization characteristics
|
27
|
+
# These are based on Rails connection pool behavior and should NOT be configurable
|
28
|
+
|
29
|
+
# Decimal places for utilization calculation (based on Rails pool stat precision)
|
30
|
+
CONNECTION_UTILIZATION_PRECISION = 3
|
31
|
+
|
32
|
+
# Pressure assessment thresholds (based on Rails connection pool characteristics)
|
33
|
+
PRESSURE_ASSESSMENT_THRESHOLDS = {
|
34
|
+
low: 0.0..0.5,
|
35
|
+
moderate: 0.5..0.7,
|
36
|
+
high: 0.7..0.85,
|
37
|
+
critical: 0.85..Float::INFINITY
|
38
|
+
}.freeze
|
39
|
+
|
40
|
+
# Conservative safety patterns (based on Rails connection pool behavior)
|
41
|
+
# Never use more than 60% of pool to prevent connection exhaustion
|
42
|
+
MAX_SAFE_CONNECTION_PERCENTAGE = 0.6
|
43
|
+
|
44
|
+
# Absolute minimum for system stability (based on Tasker orchestration needs)
|
45
|
+
EMERGENCY_FALLBACK_CONCURRENCY = 3
|
46
|
+
|
47
|
+
# Assess current database connection pool health
|
48
|
+
#
|
49
|
+
# Provides comprehensive analysis of Rails connection pool state including
|
50
|
+
# utilization metrics, pressure assessment, and concurrency recommendations.
|
51
|
+
#
|
52
|
+
# @return [Hash] Connection health assessment with structured metrics
|
53
|
+
# @option return [Float] :pool_utilization Connection pool utilization ratio (0.0-1.0+)
|
54
|
+
# @option return [Symbol] :connection_pressure Pressure level (:low, :moderate, :high, :critical)
|
55
|
+
# @option return [Integer] :recommended_concurrency Safe concurrency level
|
56
|
+
# @option return [Hash] :rails_pool_stats Raw Rails pool statistics
|
57
|
+
# @option return [Symbol] :health_status Overall health status
|
58
|
+
# @option return [Time] :assessment_timestamp When assessment was performed
|
59
|
+
def self.assess_connection_health
|
60
|
+
pool = ActiveRecord::Base.connection_pool
|
61
|
+
pool_stat = pool.stat
|
62
|
+
|
63
|
+
{
|
64
|
+
pool_utilization: calculate_utilization(pool_stat),
|
65
|
+
connection_pressure: assess_pressure(pool_stat),
|
66
|
+
recommended_concurrency: recommend_concurrency(pool_stat),
|
67
|
+
rails_pool_stats: pool_stat,
|
68
|
+
health_status: determine_health_status(pool_stat),
|
69
|
+
assessment_timestamp: Time.current
|
70
|
+
}
|
71
|
+
rescue StandardError => e
|
72
|
+
Rails.logger.error("ConnectionPoolIntelligence: Health assessment failed - #{e.class.name}: #{e.message}")
|
73
|
+
|
74
|
+
# Return safe fallback assessment
|
75
|
+
{
|
76
|
+
pool_utilization: 0.0,
|
77
|
+
connection_pressure: :unknown,
|
78
|
+
recommended_concurrency: EMERGENCY_FALLBACK_CONCURRENCY,
|
79
|
+
rails_pool_stats: {},
|
80
|
+
health_status: :unknown,
|
81
|
+
assessment_timestamp: Time.current,
|
82
|
+
assessment_error: e.message
|
83
|
+
}
|
84
|
+
end
|
85
|
+
|
86
|
+
# Calculate intelligent concurrency for StepExecutor integration
|
87
|
+
#
|
88
|
+
# Provides Rails-aware concurrency calculation that respects connection pool
|
89
|
+
# limits while applying configurable safety margins and pressure factors.
|
90
|
+
#
|
91
|
+
# @return [Integer] Safe concurrency level for step execution
|
92
|
+
def self.intelligent_concurrency_for_step_executor
|
93
|
+
health_data = assess_connection_health
|
94
|
+
config = Tasker.configuration.execution
|
95
|
+
|
96
|
+
# Get base recommendation from Rails pool analysis
|
97
|
+
base_recommendation = health_data[:recommended_concurrency]
|
98
|
+
safe_concurrency = apply_tasker_safety_margins(base_recommendation, health_data, config)
|
99
|
+
|
100
|
+
Rails.logger.debug do
|
101
|
+
"ConnectionPoolIntelligence: Dynamic concurrency=#{safe_concurrency}, " \
|
102
|
+
"pressure=#{health_data[:connection_pressure]}, " \
|
103
|
+
"pool_size=#{ActiveRecord::Base.connection_pool.size}, " \
|
104
|
+
"available=#{health_data[:rails_pool_stats][:available]}"
|
105
|
+
end
|
106
|
+
|
107
|
+
safe_concurrency
|
108
|
+
rescue StandardError => e
|
109
|
+
Rails.logger.error(
|
110
|
+
"ConnectionPoolIntelligence: Concurrency calculation failed - #{e.class.name}: #{e.message}, " \
|
111
|
+
"using fallback=#{EMERGENCY_FALLBACK_CONCURRENCY}"
|
112
|
+
)
|
113
|
+
|
114
|
+
EMERGENCY_FALLBACK_CONCURRENCY
|
115
|
+
end
|
116
|
+
|
117
|
+
private_class_method def self.calculate_utilization(pool_stat)
|
118
|
+
return 0.0 if pool_stat[:size].zero?
|
119
|
+
|
120
|
+
(pool_stat[:busy].to_f / pool_stat[:size]).round(CONNECTION_UTILIZATION_PRECISION)
|
121
|
+
end
|
122
|
+
|
123
|
+
private_class_method def self.assess_pressure(pool_stat)
|
124
|
+
utilization = calculate_utilization(pool_stat)
|
125
|
+
|
126
|
+
# Use CONSTANT thresholds for consistent pressure assessment
|
127
|
+
PRESSURE_ASSESSMENT_THRESHOLDS.each do |level, range|
|
128
|
+
return level if range.cover?(utilization)
|
129
|
+
end
|
130
|
+
|
131
|
+
:unknown
|
132
|
+
end
|
133
|
+
|
134
|
+
private_class_method def self.recommend_concurrency(pool_stat)
|
135
|
+
pressure = assess_pressure(pool_stat)
|
136
|
+
|
137
|
+
# ✅ CONFIGURABLE: Pressure response factors (environment-dependent)
|
138
|
+
pressure_config = Tasker.configuration.execution.connection_pressure_factors
|
139
|
+
factor = pressure_config[pressure] || 0.5
|
140
|
+
|
141
|
+
base_recommendation = [pool_stat[:available] * factor, 12].min.floor
|
142
|
+
[base_recommendation, EMERGENCY_FALLBACK_CONCURRENCY].max
|
143
|
+
end
|
144
|
+
|
145
|
+
private_class_method def self.determine_health_status(pool_stat)
|
146
|
+
pressure = assess_pressure(pool_stat)
|
147
|
+
|
148
|
+
case pressure
|
149
|
+
when :low, :moderate then :healthy
|
150
|
+
when :high then :degraded
|
151
|
+
when :critical then :critical
|
152
|
+
else :unknown
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
private_class_method def self.apply_tasker_safety_margins(base_recommendation, health_data, config)
|
157
|
+
# Use CONSTANT safety percentage with CONFIGURABLE bounds
|
158
|
+
max_safe = (health_data[:rails_pool_stats][:available] * MAX_SAFE_CONNECTION_PERCENTAGE).floor
|
159
|
+
|
160
|
+
# Apply configurable pressure adjustments based on connection pool state
|
161
|
+
pressure_adjusted = case health_data[:connection_pressure]
|
162
|
+
when :moderate
|
163
|
+
[base_recommendation, max_safe].min
|
164
|
+
when :high
|
165
|
+
[base_recommendation * 0.7, max_safe].min.floor
|
166
|
+
when :critical, :unknown
|
167
|
+
[EMERGENCY_FALLBACK_CONCURRENCY, max_safe].min
|
168
|
+
else # :low pressure or any other state
|
169
|
+
base_recommendation
|
170
|
+
end
|
171
|
+
|
172
|
+
# Apply CONFIGURABLE absolute bounds from ExecutionConfig
|
173
|
+
pressure_adjusted.clamp(config.min_concurrent_steps, config.max_concurrent_steps_limit)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative '../concerns/idempotent_state_transitions'
|
4
|
+
require_relative 'viable_step_discovery'
|
5
|
+
require_relative 'step_executor'
|
6
|
+
require_relative 'task_finalizer'
|
7
|
+
require_relative 'task_initializer'
|
8
|
+
require_relative 'step_sequence_factory'
|
9
|
+
require_relative 'task_reenqueuer'
|
10
|
+
|
11
|
+
module Tasker
|
12
|
+
module Orchestration
|
13
|
+
# Coordinator handles orchestration system initialization and monitoring
|
14
|
+
#
|
15
|
+
# This class ensures the orchestration system is properly initialized and provides
|
16
|
+
# observability into the system state. It does NOT handle task processing -
|
17
|
+
# that responsibility belongs to TaskHandler using the proven delegation pattern.
|
18
|
+
class Coordinator
|
19
|
+
include Tasker::Concerns::IdempotentStateTransitions
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Check if the orchestration system has been initialized
|
23
|
+
#
|
24
|
+
# @return [Boolean] True if initialized
|
25
|
+
def initialized?
|
26
|
+
@initialized == true
|
27
|
+
end
|
28
|
+
|
29
|
+
# Initialize the orchestration system
|
30
|
+
#
|
31
|
+
# Sets up all orchestration components, registers events, and connects subscribers.
|
32
|
+
# This method is idempotent and can be called multiple times safely.
|
33
|
+
def initialize!
|
34
|
+
return if @initialized
|
35
|
+
|
36
|
+
Rails.logger.info('Tasker::Orchestration::Coordinator: Initializing orchestration system')
|
37
|
+
|
38
|
+
# Initialize core orchestration components
|
39
|
+
setup_publisher
|
40
|
+
setup_event_subscriptions
|
41
|
+
|
42
|
+
# Initialize telemetry and monitoring
|
43
|
+
setup_telemetry_subscriber
|
44
|
+
|
45
|
+
@initialized = true
|
46
|
+
Rails.logger.info('Tasker::Orchestration::Coordinator: Orchestration system initialized successfully')
|
47
|
+
rescue StandardError => e
|
48
|
+
Rails.logger.error("Tasker::Orchestration::Coordinator: Failed to initialize: #{e.message}")
|
49
|
+
@initialized = false
|
50
|
+
raise
|
51
|
+
end
|
52
|
+
|
53
|
+
# Reset initialization state (primarily for testing)
|
54
|
+
def reset!
|
55
|
+
@initialized = false
|
56
|
+
@publisher = nil
|
57
|
+
Rails.logger.debug('Tasker::Orchestration::Coordinator: Initialization state reset')
|
58
|
+
end
|
59
|
+
|
60
|
+
# Get statistics about the workflow orchestration system
|
61
|
+
#
|
62
|
+
# @return [Hash] Statistics about component initialization and event subscriptions
|
63
|
+
def statistics
|
64
|
+
{
|
65
|
+
initialized: @initialized || false,
|
66
|
+
components: {
|
67
|
+
publisher: defined?(Tasker::Events::Publisher),
|
68
|
+
viable_step_discovery: defined?(Tasker::Orchestration::ViableStepDiscovery),
|
69
|
+
step_executor: defined?(Tasker::Orchestration::StepExecutor),
|
70
|
+
task_finalizer: defined?(Tasker::Orchestration::TaskFinalizer),
|
71
|
+
task_reenqueuer: defined?(Tasker::Orchestration::TaskReenqueuer)
|
72
|
+
},
|
73
|
+
publisher_instance: @publisher&.class&.name
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
# Get sequence for a task (utility method for orchestration components)
|
78
|
+
#
|
79
|
+
# @param task [Tasker::Task] The task
|
80
|
+
# @param task_handler [Object] The task handler
|
81
|
+
# @return [Tasker::Types::StepSequence] The step sequence
|
82
|
+
def get_sequence_for_task(task, task_handler)
|
83
|
+
Tasker::Orchestration::StepSequenceFactory.get_sequence(task, task_handler)
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
# Set up the main publisher
|
89
|
+
def setup_publisher
|
90
|
+
@publisher = Tasker::Events::Publisher.instance
|
91
|
+
end
|
92
|
+
|
93
|
+
# Set up event subscriptions for orchestration components
|
94
|
+
def setup_event_subscriptions
|
95
|
+
# Currently using direct method delegation instead of event subscriptions
|
96
|
+
# for the core workflow loop. Events are used for observability.
|
97
|
+
# Future enhancement: Add event-driven workflow subscriptions here
|
98
|
+
end
|
99
|
+
|
100
|
+
# Set up the telemetry subscriber for comprehensive observability
|
101
|
+
def setup_telemetry_subscriber
|
102
|
+
# Ensure telemetry subscriber is connected to the lifecycle events system
|
103
|
+
Tasker::Events::Publisher.instance.tap do |publisher|
|
104
|
+
Tasker::Events::Subscribers::TelemetrySubscriber.subscribe(publisher)
|
105
|
+
end
|
106
|
+
Rails.logger.debug('Tasker::Orchestration::Coordinator: TelemetrySubscriber connected successfully')
|
107
|
+
|
108
|
+
# Set up the metrics subscriber for automatic metrics collection via EventRouter
|
109
|
+
Tasker::Events::Publisher.instance.tap do |publisher|
|
110
|
+
Tasker::Events::Subscribers::MetricsSubscriber.subscribe(publisher)
|
111
|
+
end
|
112
|
+
Rails.logger.debug('Tasker::Orchestration::Coordinator: MetricsSubscriber connected successfully')
|
113
|
+
rescue StandardError => e
|
114
|
+
Rails.logger.error("Tasker::Orchestration::Coordinator: Failed to setup telemetry subscriber: #{e.message}")
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tasker
|
4
|
+
module Orchestration
|
5
|
+
# Abstraction layer for analyzing Concurrent::Future states in our domain context
|
6
|
+
#
|
7
|
+
# This class encapsulates the complex state logic around Concurrent::Future objects,
|
8
|
+
# providing domain-specific methods that express our actual intentions rather than
|
9
|
+
# requiring callers to understand the intricacies of the Future state machine.
|
10
|
+
#
|
11
|
+
# The Concurrent::Future state machine has these states:
|
12
|
+
# - unscheduled: Created but not yet executed
|
13
|
+
# - pending: Scheduled but not yet started
|
14
|
+
# - executing: Currently running
|
15
|
+
# - fulfilled: Completed successfully
|
16
|
+
# - rejected: Completed with error
|
17
|
+
# - cancelled: Cancelled before completion
|
18
|
+
#
|
19
|
+
# Our domain needs are:
|
20
|
+
# - Should we cancel this future? (pending futures)
|
21
|
+
# - Should we wait for this future? (executing futures)
|
22
|
+
# - Can we ignore this future? (completed or unscheduled futures)
|
23
|
+
class FutureStateAnalyzer
|
24
|
+
# Initialize with a Concurrent::Future object
|
25
|
+
#
|
26
|
+
# @param future [Concurrent::Future] The future to analyze
|
27
|
+
def initialize(future)
|
28
|
+
@future = future
|
29
|
+
end
|
30
|
+
|
31
|
+
# Should this future be cancelled during cleanup?
|
32
|
+
#
|
33
|
+
# We cancel futures that are pending (scheduled but not started).
|
34
|
+
# This prevents them from starting when we're trying to clean up.
|
35
|
+
#
|
36
|
+
# @return [Boolean] true if the future should be cancelled
|
37
|
+
def should_cancel?
|
38
|
+
@future.pending?
|
39
|
+
end
|
40
|
+
|
41
|
+
# Should we wait for this future to complete during cleanup?
|
42
|
+
#
|
43
|
+
# We wait for futures that are actively executing to give them
|
44
|
+
# a chance to complete gracefully before forcing cleanup.
|
45
|
+
#
|
46
|
+
# A future is "executing" if:
|
47
|
+
# - It's incomplete (not finished)
|
48
|
+
# - It's scheduled (not unscheduled)
|
49
|
+
# - It's not pending (it has started)
|
50
|
+
#
|
51
|
+
# @return [Boolean] true if we should wait for this future
|
52
|
+
def should_wait_for_completion?
|
53
|
+
executing?
|
54
|
+
end
|
55
|
+
|
56
|
+
# Can we safely ignore this future during cleanup?
|
57
|
+
#
|
58
|
+
# We can ignore futures that are either:
|
59
|
+
# - Already completed (fulfilled, rejected, or cancelled)
|
60
|
+
# - Never scheduled (unscheduled)
|
61
|
+
#
|
62
|
+
# @return [Boolean] true if this future can be ignored
|
63
|
+
def can_ignore?
|
64
|
+
completed? || unscheduled?
|
65
|
+
end
|
66
|
+
|
67
|
+
# Is this future currently executing?
|
68
|
+
#
|
69
|
+
# A future is executing if it has been scheduled, started, but not completed.
|
70
|
+
#
|
71
|
+
# @return [Boolean] true if the future is actively executing
|
72
|
+
def executing?
|
73
|
+
@future.incomplete? && !@future.unscheduled? && !@future.pending?
|
74
|
+
end
|
75
|
+
|
76
|
+
# Is this future completed (in any completion state)?
|
77
|
+
#
|
78
|
+
# A future is completed if it's fulfilled, rejected, or cancelled.
|
79
|
+
#
|
80
|
+
# @return [Boolean] true if the future has completed
|
81
|
+
def completed?
|
82
|
+
@future.complete?
|
83
|
+
end
|
84
|
+
|
85
|
+
# Is this future unscheduled (never started)?
|
86
|
+
#
|
87
|
+
# An unscheduled future was created but never executed.
|
88
|
+
#
|
89
|
+
# @return [Boolean] true if the future is unscheduled
|
90
|
+
delegate :unscheduled?, to: :@future
|
91
|
+
|
92
|
+
# Is this future pending (scheduled but not started)?
|
93
|
+
#
|
94
|
+
# A pending future has been scheduled for execution but hasn't started yet.
|
95
|
+
#
|
96
|
+
# @return [Boolean] true if the future is pending
|
97
|
+
delegate :pending?, to: :@future
|
98
|
+
|
99
|
+
# Get a human-readable description of the future's state
|
100
|
+
#
|
101
|
+
# This is useful for logging and debugging.
|
102
|
+
#
|
103
|
+
# @return [String] A description of the current state
|
104
|
+
def state_description
|
105
|
+
return 'unscheduled' if unscheduled?
|
106
|
+
return 'pending' if pending?
|
107
|
+
return 'executing' if executing?
|
108
|
+
return 'fulfilled' if @future.fulfilled?
|
109
|
+
return 'rejected' if @future.rejected?
|
110
|
+
return 'cancelled' if @future.cancelled?
|
111
|
+
|
112
|
+
'unknown'
|
113
|
+
end
|
114
|
+
|
115
|
+
# Get detailed state information for debugging
|
116
|
+
#
|
117
|
+
# @return [Hash] Detailed state information
|
118
|
+
def debug_state
|
119
|
+
{
|
120
|
+
state_description: state_description,
|
121
|
+
should_cancel: should_cancel?,
|
122
|
+
should_wait: should_wait_for_completion?,
|
123
|
+
can_ignore: can_ignore?,
|
124
|
+
raw_states: {
|
125
|
+
pending: @future.pending?,
|
126
|
+
complete: @future.complete?,
|
127
|
+
incomplete: @future.incomplete?,
|
128
|
+
unscheduled: @future.unscheduled?,
|
129
|
+
fulfilled: @future.fulfilled?,
|
130
|
+
rejected: @future.rejected?,
|
131
|
+
cancelled: @future.cancelled?
|
132
|
+
}
|
133
|
+
}
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tasker
|
4
|
+
module Orchestration
|
5
|
+
# PluginIntegration provides shared access to TaskHandler plugin functionality
|
6
|
+
#
|
7
|
+
# This module extracts the plugin integration patterns from TaskHandler
|
8
|
+
# and makes them available to orchestration components while preserving
|
9
|
+
# the extensibility that makes Tasker valuable.
|
10
|
+
#
|
11
|
+
# Key methods preserved:
|
12
|
+
# - get_step_handler: Access to step handler plugins
|
13
|
+
# - establish_step_dependencies_and_defaults: Extensibility hook
|
14
|
+
# - update_annotations: Extensibility hook
|
15
|
+
# - schema validation: Context validation hook
|
16
|
+
module PluginIntegration
|
17
|
+
# Get a step handler for a specific step
|
18
|
+
#
|
19
|
+
# This method integrates with the TaskHandler plugin system to get
|
20
|
+
# the appropriate handler for a step.
|
21
|
+
#
|
22
|
+
# @param step [Tasker::WorkflowStep] The step to get a handler for
|
23
|
+
# @param task_handler [Object] The task handler instance
|
24
|
+
# @return [Object] The step handler
|
25
|
+
# @raise [Tasker::ProceduralError] If no handler is registered for the step
|
26
|
+
def get_step_handler_from_task_handler(step, task_handler)
|
27
|
+
unless task_handler.step_handler_class_map[step.name]
|
28
|
+
raise(Tasker::ProceduralError,
|
29
|
+
"No registered class for #{step.name}")
|
30
|
+
end
|
31
|
+
|
32
|
+
handler_config = task_handler.step_handler_config_map[step.name]
|
33
|
+
handler_class = task_handler.step_handler_class_map[step.name].to_s.camelize.constantize
|
34
|
+
|
35
|
+
return handler_class.new if handler_config.nil?
|
36
|
+
|
37
|
+
handler_class.new(config: handler_config)
|
38
|
+
end
|
39
|
+
|
40
|
+
# Get the step sequence for a task using task handler
|
41
|
+
#
|
42
|
+
# This delegates to the task handler's get_sequence method which handles
|
43
|
+
# step template creation and dependency establishment.
|
44
|
+
#
|
45
|
+
# @param task [Tasker::Task] The task
|
46
|
+
# @param task_handler [Object] The task handler instance
|
47
|
+
# @return [Tasker::Types::StepSequence] The step sequence
|
48
|
+
def get_sequence_for_task(task, task_handler)
|
49
|
+
task_handler.get_sequence(task)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Establish step dependencies and defaults using task handler hook
|
53
|
+
#
|
54
|
+
# @param task [Tasker::Task] The task being processed
|
55
|
+
# @param steps [Array<Tasker::WorkflowStep>] The steps to establish dependencies for
|
56
|
+
# @param task_handler [Object] The task handler instance
|
57
|
+
def establish_step_dependencies_and_defaults_via_handler(task, steps, task_handler)
|
58
|
+
# Call the task handler's hook method if it exists
|
59
|
+
return unless task_handler.respond_to?(:establish_step_dependencies_and_defaults)
|
60
|
+
|
61
|
+
task_handler.establish_step_dependencies_and_defaults(task, steps)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Update annotations using task handler hook
|
65
|
+
#
|
66
|
+
# @param task [Tasker::Task] The task being processed
|
67
|
+
# @param sequence [Tasker::Types::StepSequence] The sequence of steps
|
68
|
+
# @param steps [Array<Tasker::WorkflowStep>] The processed steps
|
69
|
+
# @param task_handler [Object] The task handler instance
|
70
|
+
def update_annotations_via_handler(task, sequence, steps, task_handler)
|
71
|
+
return unless task_handler.respond_to?(:update_annotations)
|
72
|
+
|
73
|
+
task_handler.update_annotations(task, sequence, steps)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Validate context using task handler schema
|
77
|
+
#
|
78
|
+
# @param context [Hash] The context to validate
|
79
|
+
# @param task_handler [Object] The task handler with schema
|
80
|
+
# @return [Array<String>] Validation errors, if any
|
81
|
+
def validate_context_via_handler(context, task_handler)
|
82
|
+
return [] unless task_handler.respond_to?(:schema) && task_handler.schema
|
83
|
+
|
84
|
+
data = context.to_hash.deep_symbolize_keys
|
85
|
+
JSON::Validator.fully_validate(task_handler.schema, data, strict: true, insert_defaults: true)
|
86
|
+
end
|
87
|
+
|
88
|
+
# Check if task handler supports concurrent processing
|
89
|
+
#
|
90
|
+
# This checks the task handler's concurrent processing configuration
|
91
|
+
# to determine the appropriate processing mode.
|
92
|
+
#
|
93
|
+
# @param task_handler [Object] The task handler instance
|
94
|
+
# @return [Boolean] True if concurrent processing is enabled
|
95
|
+
def supports_concurrent_processing?(_task_handler)
|
96
|
+
true
|
97
|
+
end
|
98
|
+
|
99
|
+
# Get task handler instance for a task
|
100
|
+
#
|
101
|
+
# @param task [Tasker::Task] The task
|
102
|
+
# @return [Object] The task handler instance
|
103
|
+
def get_task_handler_for_task(task)
|
104
|
+
handler_factory = Tasker::HandlerFactory.instance
|
105
|
+
handler_factory.get(
|
106
|
+
task.name,
|
107
|
+
namespace_name: task.named_task.task_namespace.name,
|
108
|
+
version: task.named_task.version
|
109
|
+
)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Get task handler class for a task name
|
113
|
+
#
|
114
|
+
# This provides access to the handler class without instantiation.
|
115
|
+
#
|
116
|
+
# @param task_name [String] The task name
|
117
|
+
# @return [Class] The task handler class
|
118
|
+
def get_task_handler_class(task_name)
|
119
|
+
handler_factory = Tasker::HandlerFactory.instance
|
120
|
+
handler_factory.handler_class_for(task_name)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|