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,31 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Tasker
|
5
|
+
module Queries
|
6
|
+
class TasksByAnnotation < BaseQuery
|
7
|
+
include Helpers
|
8
|
+
type [Tasker::GraphQLTypes::TaskType], null: true
|
9
|
+
|
10
|
+
description 'Find and sort tasks by status'
|
11
|
+
argument :annotation_type, String, required: true
|
12
|
+
argument :annotation_key, String, required: true
|
13
|
+
argument :annotation_value, String, required: true
|
14
|
+
argument :limit, Integer, default_value: 20, prepare: ->(limit, _ctx) { [limit, 100].min }, required: false
|
15
|
+
argument :offset, Integer, default_value: 0, required: false
|
16
|
+
argument :sort_by, String, default_value: :requested_at, required: false
|
17
|
+
argument :sort_order, String, default_value: :desc, required: false
|
18
|
+
|
19
|
+
def resolve(limit:, offset:, sort_by:, sort_order:, annotation_type:, annotation_key:, annotation_value:)
|
20
|
+
sorts = page_sort_params(model: Tasker::Task, limit: limit, offset: offset, sort_by: sort_by,
|
21
|
+
sort_order: sort_order)
|
22
|
+
Tasker::Task
|
23
|
+
.with_all_associated
|
24
|
+
.by_annotation(annotation_type, annotation_key, annotation_value)
|
25
|
+
.limit(sorts[:limit])
|
26
|
+
.offset(sorts[:offset])
|
27
|
+
.order(sorts[:order])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Tasker
|
5
|
+
module Queries
|
6
|
+
class TasksByStatus < BaseQuery
|
7
|
+
include Helpers
|
8
|
+
type [Tasker::GraphQLTypes::TaskType], null: true
|
9
|
+
|
10
|
+
description 'Find and sort tasks by status'
|
11
|
+
argument :status, String, required: true
|
12
|
+
argument :limit, Integer, default_value: 20, prepare: ->(limit, _ctx) { [limit, 100].min }, required: false
|
13
|
+
argument :offset, Integer, default_value: 0, required: false
|
14
|
+
argument :sort_by, String, default_value: :requested_at, required: false
|
15
|
+
argument :sort_order, String, default_value: :desc, required: false
|
16
|
+
|
17
|
+
def resolve(limit:, offset:, sort_by:, sort_order:, status:)
|
18
|
+
sorts = page_sort_params(model: Tasker::Task, limit: limit, offset: offset, sort_by: sort_by,
|
19
|
+
sort_order: sort_order)
|
20
|
+
|
21
|
+
# Use the ActiveRecord scope to query tasks by current state
|
22
|
+
Tasker::Task.with_all_associated
|
23
|
+
.by_current_state(status)
|
24
|
+
.limit(sorts[:limit])
|
25
|
+
.offset(sorts[:offset])
|
26
|
+
.order(sorts[:order])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require_relative 'graph_ql_types'
|
5
|
+
|
6
|
+
module Tasker
|
7
|
+
class TaskerRailsSchema < GraphQL::Schema
|
8
|
+
mutation(Tasker::GraphQLTypes::MutationType)
|
9
|
+
query(Tasker::GraphQLTypes::QueryType)
|
10
|
+
|
11
|
+
# Custom exception for GraphQL type resolution errors
|
12
|
+
class TypeResolutionError < GraphQL::ExecutionError; end
|
13
|
+
class UnknownInterfaceError < TypeResolutionError; end
|
14
|
+
class InvalidObjectTypeError < TypeResolutionError; end
|
15
|
+
|
16
|
+
# Union and Interface Resolution
|
17
|
+
def self.resolve_type(abstract_type, obj, _ctx)
|
18
|
+
case abstract_type.graphql_name
|
19
|
+
when 'TaskInterface'
|
20
|
+
# TaskInterface is only implemented by TaskType
|
21
|
+
unless obj.is_a?(Tasker::Task) || (obj.is_a?(Hash) && obj.key?(:named_task_id))
|
22
|
+
raise InvalidObjectTypeError, "Unable to resolve TaskInterface for object: #{obj.class}"
|
23
|
+
end
|
24
|
+
|
25
|
+
GraphQLTypes::TaskType
|
26
|
+
|
27
|
+
else
|
28
|
+
raise UnknownInterfaceError, "Unknown abstract type: #{abstract_type.graphql_name}"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Relay-style Object Identification:
|
33
|
+
|
34
|
+
# Return a string UUID for `object`
|
35
|
+
def self.id_from_object(object, type_definition, query_ctx)
|
36
|
+
# Here's a simple implementation which:
|
37
|
+
# - joins the type name & object.id
|
38
|
+
# - encodes it with base64:
|
39
|
+
# GraphQL::Schema::UniqueWithinType.encode(type_definition.name, object.id)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Given a string UUID, find the object
|
43
|
+
def self.object_from_id(id, query_ctx)
|
44
|
+
# For example, to decode the UUIDs generated above:
|
45
|
+
# type_name, item_id = GraphQL::Schema::UniqueWithinType.decode(id)
|
46
|
+
#
|
47
|
+
# Then, based on `type_name` and `id`
|
48
|
+
# find an object in your application
|
49
|
+
# ...
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Tasker
|
4
|
+
# ActiveJob for exporting metrics with distributed coordination
|
5
|
+
#
|
6
|
+
# **Phase 4.2.2.3.3**: Thin wrapper around MetricsExportService that handles
|
7
|
+
# ActiveJob concerns (queueing, retries, timeouts) while delegating the actual
|
8
|
+
# export business logic to the service.
|
9
|
+
#
|
10
|
+
# Key Features:
|
11
|
+
# - Rails ActiveJob integration for any backend (Sidekiq, SQS, etc.)
|
12
|
+
# - Distributed coordination through ExportCoordinator
|
13
|
+
# - Retry handling with exponential backoff
|
14
|
+
# - Timeout protection
|
15
|
+
# - Comprehensive logging
|
16
|
+
#
|
17
|
+
# @example Scheduled by ExportCoordinator
|
18
|
+
# MetricsExportJob.set(wait_until: 5.minutes.from_now).perform_later(
|
19
|
+
# format: :prometheus,
|
20
|
+
# coordinator_instance: "web-1-12345",
|
21
|
+
# timing: { export_time: Time.current + 5.minutes }
|
22
|
+
# )
|
23
|
+
#
|
24
|
+
class MetricsExportJob < ApplicationJob
|
25
|
+
include Tasker::Concerns::StructuredLogging
|
26
|
+
|
27
|
+
# Configure job retry behavior with exponential backoff
|
28
|
+
# This replaces the sleep-based retry in ExportCoordinator
|
29
|
+
retry_on StandardError,
|
30
|
+
wait: :exponentially_longer,
|
31
|
+
attempts: 3,
|
32
|
+
queue: :metrics_export_retry
|
33
|
+
|
34
|
+
# Use separate queue for metrics export to avoid blocking other jobs
|
35
|
+
queue_as :metrics_export
|
36
|
+
|
37
|
+
# Job timeout to prevent hanging exports
|
38
|
+
around_perform :with_timeout
|
39
|
+
|
40
|
+
# @param format [Symbol] Export format (:prometheus, :json, :csv)
|
41
|
+
# @param coordinator_instance [String] ExportCoordinator instance identifier
|
42
|
+
# @param scheduled_by [String] Who scheduled this job
|
43
|
+
# @param timing [Hash] Export timing information
|
44
|
+
# @param include_instances [Boolean] Include per-instance metrics breakdown
|
45
|
+
def perform(format:, coordinator_instance:, scheduled_by: nil, timing: nil, include_instances: false)
|
46
|
+
@format = format.to_sym
|
47
|
+
@coordinator_instance = coordinator_instance
|
48
|
+
@scheduled_by = scheduled_by
|
49
|
+
@timing = timing
|
50
|
+
@include_instances = include_instances
|
51
|
+
@job_start_time = Time.current
|
52
|
+
|
53
|
+
log_job_started
|
54
|
+
|
55
|
+
# Get metrics data from coordinator
|
56
|
+
coordinator = Tasker::Telemetry::ExportCoordinator.instance
|
57
|
+
export_result = coordinator.execute_coordinated_export(
|
58
|
+
format: @format,
|
59
|
+
include_instances: @include_instances
|
60
|
+
)
|
61
|
+
|
62
|
+
if export_result[:success]
|
63
|
+
# Delegate actual export to service
|
64
|
+
service_result = export_with_service(export_result[:result])
|
65
|
+
log_job_completed(service_result)
|
66
|
+
else
|
67
|
+
# Export coordination failed
|
68
|
+
handle_failed_coordination(export_result)
|
69
|
+
end
|
70
|
+
rescue StandardError => e
|
71
|
+
log_job_error(e)
|
72
|
+
|
73
|
+
# Extend cache TTL before retry to prevent data loss
|
74
|
+
extend_cache_ttl_for_retry
|
75
|
+
|
76
|
+
raise # Re-raise to trigger ActiveJob retry logic
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
# Export metrics using the MetricsExportService
|
82
|
+
#
|
83
|
+
# @param metrics_data [Hash] Metrics data from coordinator
|
84
|
+
# @return [Hash] Export service result
|
85
|
+
def export_with_service(metrics_data)
|
86
|
+
service = Tasker::Telemetry::MetricsExportService.new
|
87
|
+
|
88
|
+
export_context = {
|
89
|
+
job_id: job_id,
|
90
|
+
coordinator_instance: @coordinator_instance,
|
91
|
+
scheduled_by: @scheduled_by,
|
92
|
+
timing: @timing
|
93
|
+
}
|
94
|
+
|
95
|
+
service.export_metrics(
|
96
|
+
format: @format,
|
97
|
+
metrics_data: metrics_data,
|
98
|
+
context: export_context
|
99
|
+
)
|
100
|
+
end
|
101
|
+
|
102
|
+
# Handle failed export coordination
|
103
|
+
#
|
104
|
+
# @param export_result [Hash] Export result with error information
|
105
|
+
def handle_failed_coordination(export_result)
|
106
|
+
log_coordination_failure(export_result)
|
107
|
+
|
108
|
+
# If this is a lock timeout, it's not necessarily an error
|
109
|
+
# Another container is handling the export
|
110
|
+
unless export_result[:error]&.include?('lock timeout')
|
111
|
+
raise StandardError, "Export coordination failed: #{export_result[:error]}"
|
112
|
+
end
|
113
|
+
|
114
|
+
log_concurrent_export_detected
|
115
|
+
|
116
|
+
# Actual coordination failure - raise error to trigger retry
|
117
|
+
end
|
118
|
+
|
119
|
+
# Timeout wrapper for job execution
|
120
|
+
#
|
121
|
+
# @param job [ActiveJob] The job being executed
|
122
|
+
# @yield Block to execute with timeout
|
123
|
+
def with_timeout(_job, &)
|
124
|
+
timeout_duration = job_timeout_duration
|
125
|
+
|
126
|
+
Timeout.timeout(timeout_duration, &)
|
127
|
+
rescue Timeout::Error
|
128
|
+
log_job_timeout(timeout_duration)
|
129
|
+
raise StandardError, "Export job timed out after #{timeout_duration} seconds"
|
130
|
+
end
|
131
|
+
|
132
|
+
# Get job timeout duration from configuration
|
133
|
+
#
|
134
|
+
# @return [Integer] Timeout duration in seconds
|
135
|
+
def job_timeout_duration
|
136
|
+
prometheus_config = begin
|
137
|
+
Tasker.configuration.telemetry.prometheus
|
138
|
+
rescue StandardError
|
139
|
+
{}
|
140
|
+
end
|
141
|
+
prometheus_config[:job_timeout] || 5.minutes
|
142
|
+
end
|
143
|
+
|
144
|
+
# Extend cache TTL to prevent data loss during job retry
|
145
|
+
#
|
146
|
+
# Uses the job's executions count to calculate appropriate extension
|
147
|
+
def extend_cache_ttl_for_retry
|
148
|
+
return unless defined?(executions) && executions > 1
|
149
|
+
|
150
|
+
# Calculate extension based on retry attempt and expected delay
|
151
|
+
retry_delay = calculate_job_retry_delay(executions)
|
152
|
+
safety_margin = 1.minute
|
153
|
+
extension_duration = retry_delay + safety_margin
|
154
|
+
|
155
|
+
coordinator = Tasker::Telemetry::ExportCoordinator.instance
|
156
|
+
result = coordinator.extend_cache_ttl(extension_duration)
|
157
|
+
|
158
|
+
log_ttl_extension_for_retry(extension_duration, result)
|
159
|
+
rescue StandardError => e
|
160
|
+
log_ttl_extension_error(e)
|
161
|
+
# Don't fail the job if TTL extension fails
|
162
|
+
end
|
163
|
+
|
164
|
+
# Calculate expected retry delay for current execution attempt
|
165
|
+
#
|
166
|
+
# @param execution_count [Integer] Current execution attempt (1-based)
|
167
|
+
# @return [Duration] Expected delay until next retry
|
168
|
+
def calculate_job_retry_delay(execution_count)
|
169
|
+
# ActiveJob exponentially_longer uses: attempt ** 4 + 2 seconds
|
170
|
+
# But we use a more conservative estimate based on our config
|
171
|
+
base_delay = 30.seconds
|
172
|
+
(base_delay * (2**(execution_count - 2))).clamp(30.seconds, 10.minutes)
|
173
|
+
end
|
174
|
+
|
175
|
+
# Logging methods for job execution events
|
176
|
+
|
177
|
+
def log_job_started
|
178
|
+
log_structured(:info, 'Metrics export job started',
|
179
|
+
job_id: job_id,
|
180
|
+
format: @format,
|
181
|
+
coordinator_instance: @coordinator_instance,
|
182
|
+
scheduled_by: @scheduled_by,
|
183
|
+
timing: @timing,
|
184
|
+
include_instances: @include_instances)
|
185
|
+
end
|
186
|
+
|
187
|
+
def log_job_completed(service_result)
|
188
|
+
duration = Time.current - @job_start_time
|
189
|
+
|
190
|
+
log_structured(:info, 'Metrics export job completed',
|
191
|
+
job_id: job_id,
|
192
|
+
format: @format,
|
193
|
+
success: service_result[:success],
|
194
|
+
duration: duration,
|
195
|
+
service_duration: service_result[:duration],
|
196
|
+
exported_at: service_result[:exported_at])
|
197
|
+
end
|
198
|
+
|
199
|
+
def log_job_error(error)
|
200
|
+
# Get first 5 backtrace lines and pad to exactly 5 elements with nil
|
201
|
+
backtrace_lines = error.backtrace&.first(5) || []
|
202
|
+
backtrace = backtrace_lines + Array.new(5 - backtrace_lines.size, nil)
|
203
|
+
|
204
|
+
log_structured(:error, 'Metrics export job error',
|
205
|
+
job_id: job_id,
|
206
|
+
format: @format,
|
207
|
+
error: error.message,
|
208
|
+
error_class: error.class.name,
|
209
|
+
backtrace: backtrace)
|
210
|
+
end
|
211
|
+
|
212
|
+
def log_job_timeout(timeout_duration)
|
213
|
+
log_structured(:error, 'Metrics export job timeout',
|
214
|
+
job_id: job_id,
|
215
|
+
format: @format,
|
216
|
+
timeout_duration: timeout_duration)
|
217
|
+
end
|
218
|
+
|
219
|
+
def log_coordination_failure(export_result)
|
220
|
+
log_structured(:warn, 'Export coordination failed',
|
221
|
+
job_id: job_id,
|
222
|
+
format: @format,
|
223
|
+
error: export_result[:error],
|
224
|
+
attempts: export_result[:attempts])
|
225
|
+
end
|
226
|
+
|
227
|
+
def log_concurrent_export_detected
|
228
|
+
log_structured(:info, 'Concurrent export detected - skipping',
|
229
|
+
job_id: job_id,
|
230
|
+
format: @format,
|
231
|
+
reason: 'another_container_exporting')
|
232
|
+
end
|
233
|
+
|
234
|
+
def log_ttl_extension_for_retry(extension_duration, result)
|
235
|
+
log_structured(:info, 'Cache TTL extended for job retry',
|
236
|
+
job_id: job_id,
|
237
|
+
format: @format,
|
238
|
+
execution_attempt: defined?(executions) ? executions : 1,
|
239
|
+
extension_duration: extension_duration,
|
240
|
+
ttl_extension_success: result[:success],
|
241
|
+
metrics_extended: result[:metrics_extended])
|
242
|
+
end
|
243
|
+
|
244
|
+
def log_ttl_extension_error(error)
|
245
|
+
log_structured(:warn, 'Failed to extend cache TTL for retry',
|
246
|
+
job_id: job_id,
|
247
|
+
format: @format,
|
248
|
+
error: error.message,
|
249
|
+
note: 'Job will continue but metrics may expire during retry delay')
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
@@ -0,0 +1,224 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'tasker/logging/correlation_id_generator'
|
5
|
+
require_relative '../../../lib/tasker/errors'
|
6
|
+
|
7
|
+
module Tasker
|
8
|
+
class TaskRunnerJob < Tasker::ApplicationJob
|
9
|
+
include Tasker::Concerns::StructuredLogging
|
10
|
+
include Tasker::Concerns::EventPublisher
|
11
|
+
|
12
|
+
queue_as :default
|
13
|
+
|
14
|
+
# Retry retryable errors with exponential backoff
|
15
|
+
retry_on Tasker::RetryableError, wait: :exponentially_longer, attempts: 5
|
16
|
+
|
17
|
+
# Don't retry permanent errors
|
18
|
+
discard_on Tasker::PermanentError
|
19
|
+
|
20
|
+
# Retry other errors with shorter attempts
|
21
|
+
retry_on StandardError, wait: 3.seconds, attempts: 3
|
22
|
+
|
23
|
+
def handler_factory
|
24
|
+
@handler_factory ||= Tasker::HandlerFactory.instance
|
25
|
+
end
|
26
|
+
|
27
|
+
def perform(task_id, correlation_id: nil)
|
28
|
+
job_start_time = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
29
|
+
task = nil
|
30
|
+
|
31
|
+
# Establish correlation ID for the entire job execution
|
32
|
+
job_correlation_id = correlation_id || generate_correlation_id
|
33
|
+
|
34
|
+
with_correlation_id(job_correlation_id) do
|
35
|
+
log_structured(:info, 'TaskRunnerJob execution started',
|
36
|
+
task_id: task_id,
|
37
|
+
job_id: job_id,
|
38
|
+
correlation_id: job_correlation_id,
|
39
|
+
queue_name: queue_name,
|
40
|
+
attempt: executions + 1)
|
41
|
+
|
42
|
+
# Find and validate task
|
43
|
+
task = find_and_validate_task(task_id)
|
44
|
+
return unless task
|
45
|
+
|
46
|
+
# Publish task enqueue event for observability
|
47
|
+
publish_task_enqueue(task,
|
48
|
+
job_id: job_id,
|
49
|
+
correlation_id: job_correlation_id,
|
50
|
+
queue_name: queue_name,
|
51
|
+
attempt: executions + 1)
|
52
|
+
|
53
|
+
# Execute task with monitoring
|
54
|
+
execute_task_with_monitoring(task, job_correlation_id, job_start_time)
|
55
|
+
|
56
|
+
job_duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - job_start_time
|
57
|
+
|
58
|
+
# Safely get final status
|
59
|
+
final_status = task&.reload&.status || 'unknown'
|
60
|
+
|
61
|
+
log_performance_event('task_runner_job_execution', job_duration,
|
62
|
+
task_id: task_id,
|
63
|
+
job_id: job_id,
|
64
|
+
final_status: final_status,
|
65
|
+
correlation_id: job_correlation_id)
|
66
|
+
|
67
|
+
log_structured(:info, 'TaskRunnerJob execution completed',
|
68
|
+
task_id: task_id,
|
69
|
+
job_id: job_id,
|
70
|
+
final_task_status: task&.status,
|
71
|
+
duration_ms: (job_duration * 1000).round(2),
|
72
|
+
correlation_id: job_correlation_id)
|
73
|
+
end
|
74
|
+
rescue StandardError => e
|
75
|
+
job_duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - job_start_time
|
76
|
+
|
77
|
+
log_exception(e, context: {
|
78
|
+
task_id: task_id,
|
79
|
+
job_id: job_id,
|
80
|
+
correlation_id: job_correlation_id,
|
81
|
+
operation: 'task_runner_job_execution',
|
82
|
+
duration: job_duration,
|
83
|
+
attempt: executions + 1
|
84
|
+
})
|
85
|
+
|
86
|
+
Rails.logger.error("TaskRunnerJob: Error processing task #{task_id}: #{e.message}")
|
87
|
+
raise
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
# Find and validate the task for execution
|
93
|
+
#
|
94
|
+
# @param task_id [String] The task ID to find
|
95
|
+
# @return [Tasker::Task, nil] The task if found and valid, nil otherwise
|
96
|
+
def find_and_validate_task(task_id)
|
97
|
+
task = Tasker::Task.where(task_id: task_id).first
|
98
|
+
|
99
|
+
unless task
|
100
|
+
log_structured(:error, 'TaskRunnerJob: Task not found',
|
101
|
+
task_id: task_id,
|
102
|
+
job_id: job_id,
|
103
|
+
error: 'Task not found in database')
|
104
|
+
return nil
|
105
|
+
end
|
106
|
+
|
107
|
+
log_structured(:debug, 'TaskRunnerJob: Task found and validated',
|
108
|
+
task_id: task_id,
|
109
|
+
task_name: task.name,
|
110
|
+
task_status: task.status,
|
111
|
+
job_id: job_id)
|
112
|
+
|
113
|
+
task
|
114
|
+
end
|
115
|
+
|
116
|
+
# Execute the task with comprehensive monitoring
|
117
|
+
#
|
118
|
+
# @param task [Tasker::Task] The task to execute
|
119
|
+
# @param job_correlation_id [String] The correlation ID for this job
|
120
|
+
# @param job_start_time [Float] The job start time for duration calculation
|
121
|
+
# @return [void]
|
122
|
+
def execute_task_with_monitoring(task, job_correlation_id, _job_start_time)
|
123
|
+
Rails.logger.info "TaskRunnerJob: Starting execution for task #{task.task_id}"
|
124
|
+
|
125
|
+
log_task_event(task, :job_execution_started,
|
126
|
+
job_id: job_id,
|
127
|
+
correlation_id: job_correlation_id,
|
128
|
+
queue_name: queue_name,
|
129
|
+
attempt: executions + 1)
|
130
|
+
|
131
|
+
# Get the appropriate task handler with timing
|
132
|
+
handler_lookup_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
133
|
+
handler = handler_factory.get(task.name, namespace_name: task.namespace_name, version: task.version)
|
134
|
+
handler_lookup_duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - handler_lookup_start
|
135
|
+
|
136
|
+
log_performance_event('handler_factory_lookup', handler_lookup_duration,
|
137
|
+
task_id: task.task_id,
|
138
|
+
task_name: task.name,
|
139
|
+
namespace_name: task.namespace_name,
|
140
|
+
version: task.version,
|
141
|
+
handler_class: handler.class.name)
|
142
|
+
|
143
|
+
log_structured(:debug, 'TaskRunnerJob: Handler retrieved',
|
144
|
+
task_id: task.task_id,
|
145
|
+
handler_class: handler.class.name,
|
146
|
+
lookup_duration_ms: (handler_lookup_duration * 1000).round(2))
|
147
|
+
|
148
|
+
# Execute the task handler with timing
|
149
|
+
task_execution_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
150
|
+
handler.handle(task)
|
151
|
+
task_execution_duration = Process.clock_gettime(Process::CLOCK_MONOTONIC) - task_execution_start
|
152
|
+
|
153
|
+
log_performance_event('task_handler_execution', task_execution_duration,
|
154
|
+
task_id: task.task_id,
|
155
|
+
task_name: task.name,
|
156
|
+
handler_class: handler.class.name)
|
157
|
+
|
158
|
+
# Validate task completion
|
159
|
+
validate_task_completion(task, job_correlation_id, task_execution_duration)
|
160
|
+
|
161
|
+
Rails.logger.info "TaskRunnerJob: Completed execution for task #{task.task_id}"
|
162
|
+
end
|
163
|
+
|
164
|
+
# Validate that the task completed successfully
|
165
|
+
#
|
166
|
+
# @param task [Tasker::Task] The task to validate
|
167
|
+
# @param job_correlation_id [String] The correlation ID for this job
|
168
|
+
# @param task_execution_duration [Float] How long the task execution took
|
169
|
+
# @return [void]
|
170
|
+
# @raise [RuntimeError] If task did not complete successfully
|
171
|
+
def validate_task_completion(task, job_correlation_id, task_execution_duration)
|
172
|
+
task.reload
|
173
|
+
|
174
|
+
log_task_event(task, :job_execution_completed,
|
175
|
+
job_id: job_id,
|
176
|
+
final_status: task.status,
|
177
|
+
correlation_id: job_correlation_id,
|
178
|
+
execution_duration_ms: (task_execution_duration * 1000).round(2))
|
179
|
+
|
180
|
+
if task.status == Tasker::Constants::TaskStatuses::COMPLETE
|
181
|
+
log_structured(:info, 'TaskRunnerJob: Task completed successfully',
|
182
|
+
task_id: task.task_id,
|
183
|
+
final_status: task.status,
|
184
|
+
execution_duration_ms: (task_execution_duration * 1000).round(2))
|
185
|
+
else
|
186
|
+
error_message = "Task processing failed for task #{task.task_id} - final status: #{task.status}"
|
187
|
+
|
188
|
+
log_task_event(task, :job_execution_failed,
|
189
|
+
job_id: job_id,
|
190
|
+
final_status: task.status,
|
191
|
+
error: error_message,
|
192
|
+
correlation_id: job_correlation_id)
|
193
|
+
|
194
|
+
Rails.logger.error("TaskRunnerJob: #{error_message}")
|
195
|
+
|
196
|
+
# Raise appropriate error type based on task status
|
197
|
+
case task.status
|
198
|
+
when Tasker::Constants::TaskStatuses::FAILED
|
199
|
+
raise Tasker::PermanentError.new(
|
200
|
+
error_message,
|
201
|
+
error_code: 'TASK_EXECUTION_FAILED',
|
202
|
+
context: { task_id: task.task_id, final_status: task.status }
|
203
|
+
)
|
204
|
+
else
|
205
|
+
raise Tasker::RetryableError.new(
|
206
|
+
error_message,
|
207
|
+
context: { task_id: task.task_id, final_status: task.status }
|
208
|
+
)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
# Generate a correlation ID for job execution
|
214
|
+
#
|
215
|
+
# @return [String] A unique correlation ID
|
216
|
+
def generate_correlation_id
|
217
|
+
if defined?(Tasker::Logging::CorrelationIdGenerator)
|
218
|
+
Tasker::Logging::CorrelationIdGenerator.generate
|
219
|
+
else
|
220
|
+
"job_#{SecureRandom.hex(8)}"
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# typed: false
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# == Schema Information
|
5
|
+
#
|
6
|
+
# Table name: annotation_types
|
7
|
+
#
|
8
|
+
# description :string(255)
|
9
|
+
# name :string(64) not null
|
10
|
+
# created_at :datetime not null
|
11
|
+
# updated_at :datetime not null
|
12
|
+
# annotation_type_id :integer not null, primary key
|
13
|
+
#
|
14
|
+
# Indexes
|
15
|
+
#
|
16
|
+
# annotation_types_name_index (name)
|
17
|
+
# annotation_types_name_unique (name) UNIQUE
|
18
|
+
#
|
19
|
+
|
20
|
+
module Tasker
|
21
|
+
class AnnotationType < ApplicationRecord
|
22
|
+
self.primary_key = :annotation_type_id
|
23
|
+
has_many :task_annotations, dependent: :destroy
|
24
|
+
validates :name, presence: true, uniqueness: true
|
25
|
+
end
|
26
|
+
end
|