tasker-engine 0.1.0 → 1.0.2
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.
Potentially problematic release.
This version of tasker-engine might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +8 -8
- data/app/controllers/tasker/analytics_controller.rb +2 -2
- data/app/controllers/tasker/graphql_controller.rb +3 -3
- data/app/controllers/tasker/health_controller.rb +1 -1
- data/app/controllers/tasker/metrics_controller.rb +3 -3
- data/app/jobs/tasker/metrics_export_job.rb +1 -1
- data/app/models/tasker/application_record.rb +5 -5
- data/app/models/tasker/task.rb +1 -1
- data/app/models/tasker/workflow_step_edge.rb +4 -5
- data/docs/AUTH.md +11 -11
- data/docs/DEVELOPER_GUIDE.md +6 -6
- data/docs/EXECUTION_CONFIGURATION.md +1 -1
- data/docs/HEALTH.md +3 -3
- data/docs/METRICS.md +4 -4
- data/docs/OPTIMIZATION_PLAN.md +3 -3
- data/docs/QUICK_START.md +1 -1
- data/docs/REST_API.md +1 -1
- data/docs/TELEMETRY.md +5 -5
- data/docs/TROUBLESHOOTING.md +2 -2
- data/docs/TaskHandlerGenerator.html +55 -55
- data/docs/Tasker/Analysis/RuntimeGraphAnalyzer.html +1 -1
- data/docs/Tasker/Analysis/TemplateGraphAnalyzer.html +1 -1
- data/docs/Tasker/Analysis.html +1 -1
- data/docs/Tasker/AnalyticsController.html +1 -1
- data/docs/Tasker/AnalyticsService/BottleneckAnalytics.html +1 -1
- data/docs/Tasker/AnalyticsService/PerformanceAnalytics.html +1 -1
- data/docs/Tasker/AnalyticsService.html +1 -1
- data/docs/Tasker/AnnotationType.html +1 -1
- data/docs/Tasker/AnnotationTypeSerializer.html +1 -1
- data/docs/Tasker/ApplicationController.html +1 -1
- data/docs/Tasker/ApplicationJob.html +1 -1
- data/docs/Tasker/ApplicationRecord.html +6 -6
- data/docs/Tasker/Authentication/AuthenticationError.html +1 -1
- data/docs/Tasker/Authentication/ConfigurationError.html +1 -1
- data/docs/Tasker/Authentication/Coordinator.html +1 -1
- data/docs/Tasker/Authentication/Interface.html +1 -1
- data/docs/Tasker/Authentication/InterfaceError.html +1 -1
- data/docs/Tasker/Authentication/NoneAuthenticator.html +1 -1
- data/docs/Tasker/Authentication.html +1 -1
- data/docs/Tasker/Authorization/AuthorizationError.html +1 -1
- data/docs/Tasker/Authorization/BaseCoordinator.html +2 -2
- data/docs/Tasker/Authorization/ConfigurationError.html +1 -1
- data/docs/Tasker/Authorization/ResourceConstants/ACTIONS.html +1 -1
- data/docs/Tasker/Authorization/ResourceConstants/RESOURCES.html +1 -1
- data/docs/Tasker/Authorization/ResourceConstants.html +1 -1
- data/docs/Tasker/Authorization/ResourceRegistry.html +1 -1
- data/docs/Tasker/Authorization/UnauthorizedError.html +1 -1
- data/docs/Tasker/Authorization.html +2 -2
- data/docs/Tasker/CacheCapabilities.html +1 -1
- data/docs/Tasker/CacheStrategy.html +1 -1
- data/docs/Tasker/Concerns/Authenticatable.html +1 -1
- data/docs/Tasker/Concerns/Authorizable/AdminStatusChecker.html +1 -1
- data/docs/Tasker/Concerns/Authorizable.html +1 -1
- data/docs/Tasker/Concerns/ControllerAuthorizable.html +1 -1
- data/docs/Tasker/Concerns/EventPublisher.html +1 -1
- data/docs/Tasker/Concerns/IdempotentStateTransitions.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase/ClassMethods.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase/ClassMethods.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase/StateMachineBase.html +1 -1
- data/docs/Tasker/Concerns/StateMachineBase.html +1 -1
- data/docs/Tasker/Concerns/StructuredLogging.html +1 -1
- data/docs/Tasker/Concerns.html +1 -1
- data/docs/Tasker/Configuration/ConfigurationProxy.html +1 -1
- data/docs/Tasker/Configuration/TelemetryConfigurationProxy.html +1 -1
- data/docs/Tasker/Configuration.html +1 -1
- data/docs/Tasker/ConfigurationError.html +1 -1
- data/docs/Tasker/ConfiguredTask.html +2 -2
- data/docs/Tasker/Constants/EventDefinitions.html +1 -1
- data/docs/Tasker/Constants/ObservabilityEvents/Step.html +1 -1
- data/docs/Tasker/Constants/ObservabilityEvents/Task.html +1 -1
- data/docs/Tasker/Constants/ObservabilityEvents.html +1 -1
- data/docs/Tasker/Constants/RegistryEvents.html +1 -1
- data/docs/Tasker/Constants/StepEvents.html +1 -1
- data/docs/Tasker/Constants/TaskEvents.html +1 -1
- data/docs/Tasker/Constants/TaskExecution/ExecutionStatus.html +1 -1
- data/docs/Tasker/Constants/TaskExecution/HealthStatus.html +1 -1
- data/docs/Tasker/Constants/TaskExecution/RecommendedAction.html +1 -1
- data/docs/Tasker/Constants/TaskExecution.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization/ErrorMessages.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization/PendingReasons.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization/ReenqueueReasons.html +1 -1
- data/docs/Tasker/Constants/TaskFinalization.html +1 -1
- data/docs/Tasker/Constants/TaskStatuses.html +1 -1
- data/docs/Tasker/Constants/TestEvents.html +1 -1
- data/docs/Tasker/Constants/WorkflowEvents.html +1 -1
- data/docs/Tasker/Constants/WorkflowStepStatuses.html +1 -1
- data/docs/Tasker/Constants.html +1 -1
- data/docs/Tasker/DependentSystem.html +1 -1
- data/docs/Tasker/DependentSystemObjectMap.html +1 -1
- data/docs/Tasker/DetectorRegistry.html +1 -1
- data/docs/Tasker/Engine.html +1 -1
- data/docs/Tasker/Error.html +1 -1
- data/docs/Tasker/Events/Catalog/CatalogPrinter.html +1 -1
- data/docs/Tasker/Events/Catalog/CustomEventRegistrar.html +1 -1
- data/docs/Tasker/Events/Catalog/ExamplePayloadGenerator.html +1 -1
- data/docs/Tasker/Events/Catalog.html +1 -1
- data/docs/Tasker/Events/CustomRegistry.html +1 -1
- data/docs/Tasker/Events/DefinitionLoader.html +1 -1
- data/docs/Tasker/Events/EventPayloadBuilder/ErrorInfoExtractor.html +1 -1
- data/docs/Tasker/Events/EventPayloadBuilder/StepPayloadBuilder.html +1 -1
- data/docs/Tasker/Events/EventPayloadBuilder.html +1 -1
- data/docs/Tasker/Events/Publisher.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer/ErrorTypeClassifier.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/ErrorCategorizer.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber/MetricTagsExtractor.html +1 -1
- data/docs/Tasker/Events/Subscribers/BaseSubscriber.html +1 -1
- data/docs/Tasker/Events/Subscribers/MetricsSubscriber.html +2 -2
- data/docs/Tasker/Events/Subscribers/TelemetrySubscriber.html +5 -5
- data/docs/Tasker/Events/Subscribers.html +1 -1
- data/docs/Tasker/Events/SubscriptionLoader.html +1 -1
- data/docs/Tasker/Events.html +1 -1
- data/docs/Tasker/EventsGenerator.html +2 -2
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics/AnalyticsMetrics.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedAnalyticsMetrics.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedDependencyLevels.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps/SlowestStep.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestSteps.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks/SlowestTask.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSlowestTasks.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedStepReadinessStatus.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts/HealthMetrics.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedSystemHealthCounts.html +1 -1
- data/docs/Tasker/Functions/FunctionBasedTaskExecutionContext.html +1 -1
- data/docs/Tasker/Functions/FunctionWrapper.html +1 -1
- data/docs/Tasker/Functions.html +1 -1
- data/docs/Tasker/Generators/AuthenticatorGenerator/UsageInstructionsFormatter.html +1 -1
- data/docs/Tasker/Generators/AuthenticatorGenerator.html +1 -1
- data/docs/Tasker/Generators/AuthorizationCoordinatorGenerator.html +1 -1
- data/docs/Tasker/Generators/SubscriberGenerator.html +1 -1
- data/docs/Tasker/Generators/TaskHandlerGenerator.html +4 -4
- data/docs/Tasker/Generators.html +1 -1
- data/docs/Tasker/GraphQLTypes/AnnotationType.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseArgument.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseConnection.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseEdge.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseEnum.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseField.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseInputObject.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseInterface.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseObject.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseScalar.html +1 -1
- data/docs/Tasker/GraphQLTypes/BaseUnion.html +1 -1
- data/docs/Tasker/GraphQLTypes/DependentSystemObjectMapType.html +1 -1
- data/docs/Tasker/GraphQLTypes/DependentSystemType.html +1 -1
- data/docs/Tasker/GraphQLTypes/MutationType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NamedStepType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NamedTaskType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NamedTasksNamedStepType.html +1 -1
- data/docs/Tasker/GraphQLTypes/NodeType.html +1 -1
- data/docs/Tasker/GraphQLTypes/QueryType.html +1 -1
- data/docs/Tasker/GraphQLTypes/TaskAnnotationType.html +1 -1
- data/docs/Tasker/GraphQLTypes/TaskInterface.html +1 -1
- data/docs/Tasker/GraphQLTypes/TaskType.html +1 -1
- data/docs/Tasker/GraphQLTypes/WorkflowStepType.html +1 -1
- data/docs/Tasker/GraphQLTypes.html +1 -1
- data/docs/Tasker/GraphqlController.html +1 -1
- data/docs/Tasker/HandlerFactory.html +1 -1
- data/docs/Tasker/HandlerSerializer.html +1 -1
- data/docs/Tasker/HandlersController.html +1 -1
- data/docs/Tasker/HashIdentityStrategy.html +1 -1
- data/docs/Tasker/Health/ReadinessChecker.html +2 -2
- data/docs/Tasker/Health/StatusChecker.html +2 -2
- data/docs/Tasker/Health.html +1 -1
- data/docs/Tasker/HealthController.html +1 -1
- data/docs/Tasker/IdentityStrategy.html +1 -1
- data/docs/Tasker/InvalidTaskHandlerConfig.html +1 -1
- data/docs/Tasker/Logging/CorrelationIdGenerator.html +2 -2
- data/docs/Tasker/Logging.html +1 -1
- data/docs/Tasker/MetricsController.html +1 -1
- data/docs/Tasker/MetricsExportJob.html +1 -1
- data/docs/Tasker/Mutations/BaseMutation.html +1 -1
- data/docs/Tasker/Mutations/CancelStep.html +1 -1
- data/docs/Tasker/Mutations/CancelTask.html +1 -1
- data/docs/Tasker/Mutations/CreateTask.html +1 -1
- data/docs/Tasker/Mutations/UpdateStep.html +1 -1
- data/docs/Tasker/Mutations/UpdateTask.html +1 -1
- data/docs/Tasker/Mutations.html +1 -1
- data/docs/Tasker/NamedStep.html +1 -1
- data/docs/Tasker/NamedTask.html +1 -1
- data/docs/Tasker/NamedTasksNamedStep.html +1 -1
- data/docs/Tasker/Orchestration/BackoffCalculator.html +1 -1
- data/docs/Tasker/Orchestration/ConnectionBuilder/ConfigValidator.html +1 -1
- data/docs/Tasker/Orchestration/ConnectionBuilder.html +2 -2
- data/docs/Tasker/Orchestration/ConnectionPoolIntelligence.html +3 -3
- data/docs/Tasker/Orchestration/Coordinator.html +1 -1
- data/docs/Tasker/Orchestration/FutureStateAnalyzer.html +1 -1
- data/docs/Tasker/Orchestration/PluginIntegration.html +1 -1
- data/docs/Tasker/Orchestration/ResponseProcessor.html +1 -1
- data/docs/Tasker/Orchestration/RetryHeaderParser.html +1 -1
- data/docs/Tasker/Orchestration/StepExecutor.html +4 -4
- data/docs/Tasker/Orchestration/StepSequenceFactory.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/BlockageChecker.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/ContextManager.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/DelayCalculator.html +2 -2
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationDecisionMaker.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/FinalizationProcessor.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/ReasonDeterminer.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/ReenqueueManager.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer/UnclearStateHandler.html +1 -1
- data/docs/Tasker/Orchestration/TaskFinalizer.html +1 -1
- data/docs/Tasker/Orchestration/TaskInitializer.html +1 -1
- data/docs/Tasker/Orchestration/TaskReenqueuer.html +1 -1
- data/docs/Tasker/Orchestration/ViableStepDiscovery.html +1 -1
- data/docs/Tasker/Orchestration/WorkflowCoordinator.html +1 -1
- data/docs/Tasker/Orchestration.html +1 -1
- data/docs/Tasker/PageSort/PageSortParamsBuilder.html +1 -1
- data/docs/Tasker/PageSort.html +1 -1
- data/docs/Tasker/PermanentError.html +1 -1
- data/docs/Tasker/ProceduralError.html +1 -1
- data/docs/Tasker/Queries/AllAnnotationTypes.html +1 -1
- data/docs/Tasker/Queries/AllTasks.html +1 -1
- data/docs/Tasker/Queries/BaseQuery.html +1 -1
- data/docs/Tasker/Queries/Helpers.html +1 -1
- data/docs/Tasker/Queries/OneStep.html +1 -1
- data/docs/Tasker/Queries/OneTask.html +1 -1
- data/docs/Tasker/Queries/TasksByAnnotation.html +1 -1
- data/docs/Tasker/Queries/TasksByStatus.html +1 -1
- data/docs/Tasker/Queries.html +1 -1
- data/docs/Tasker/Railtie.html +1 -1
- data/docs/Tasker/Registry/BaseRegistry.html +2 -2
- data/docs/Tasker/Registry/EventPublisher.html +1 -1
- data/docs/Tasker/Registry/InterfaceValidator.html +1 -1
- data/docs/Tasker/Registry/RegistrationError.html +1 -1
- data/docs/Tasker/Registry/RegistryError.html +1 -1
- data/docs/Tasker/Registry/StatisticsCollector.html +1 -1
- data/docs/Tasker/Registry/SubscriberRegistry.html +1 -1
- data/docs/Tasker/Registry/ValidationError.html +1 -1
- data/docs/Tasker/Registry.html +1 -1
- data/docs/Tasker/RetryableError.html +1 -1
- data/docs/Tasker/StateMachine/Compatibility.html +1 -1
- data/docs/Tasker/StateMachine/InvalidStateTransition.html +1 -1
- data/docs/Tasker/StateMachine/StepStateMachine.html +1 -1
- data/docs/Tasker/StateMachine/TaskStateMachine.html +1 -1
- data/docs/Tasker/StateMachine.html +1 -1
- data/docs/Tasker/StepDagRelationship.html +1 -1
- data/docs/Tasker/StepHandler/Api/Config.html +1 -1
- data/docs/Tasker/StepHandler/Api.html +1 -1
- data/docs/Tasker/StepHandler/AutomaticEventPublishing.html +1 -1
- data/docs/Tasker/StepHandler/Base.html +1 -1
- data/docs/Tasker/StepHandler.html +1 -1
- data/docs/Tasker/StepReadinessStatus.html +1 -1
- data/docs/Tasker/Task.html +1 -1
- data/docs/Tasker/TaskAnnotation.html +1 -1
- data/docs/Tasker/TaskAnnotationSerializer.html +1 -1
- data/docs/Tasker/TaskBuilder/StepNameValidator.html +1 -1
- data/docs/Tasker/TaskBuilder/StepTemplateDefiner.html +1 -1
- data/docs/Tasker/TaskBuilder.html +1 -1
- data/docs/Tasker/TaskExecutionContext.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/ClassBasedEventRegistrar.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner/YamlEventRegistrar.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods/StepTemplateDefiner.html +1 -1
- data/docs/Tasker/TaskHandler/ClassMethods.html +1 -1
- data/docs/Tasker/TaskHandler/InstanceMethods.html +1 -1
- data/docs/Tasker/TaskHandler/StepGroup.html +1 -1
- data/docs/Tasker/TaskHandler.html +1 -1
- data/docs/Tasker/TaskNamespace.html +1 -1
- data/docs/Tasker/TaskRunnerJob.html +1 -1
- data/docs/Tasker/TaskSerializer.html +1 -1
- data/docs/Tasker/TaskTransition.html +1 -1
- data/docs/Tasker/TaskerRailsSchema/InvalidObjectTypeError.html +1 -1
- data/docs/Tasker/TaskerRailsSchema/TypeResolutionError.html +1 -1
- data/docs/Tasker/TaskerRailsSchema/UnknownInterfaceError.html +1 -1
- data/docs/Tasker/TaskerRailsSchema.html +1 -1
- data/docs/Tasker/TasksController.html +1 -1
- data/docs/Tasker/Telemetry/EventMapping.html +1 -1
- data/docs/Tasker/Telemetry/EventRouter.html +1 -1
- data/docs/Tasker/Telemetry/Events/ExportEvents.html +1 -1
- data/docs/Tasker/Telemetry/Events.html +1 -1
- data/docs/Tasker/Telemetry/ExportCoordinator.html +1 -1
- data/docs/Tasker/Telemetry/IntelligentCacheManager.html +2 -2
- data/docs/Tasker/Telemetry/LogBackend.html +1 -1
- data/docs/Tasker/Telemetry/MetricTypes/Counter.html +2 -2
- data/docs/Tasker/Telemetry/MetricTypes/Gauge.html +73 -73
- data/docs/Tasker/Telemetry/MetricTypes/Histogram.html +103 -103
- data/docs/Tasker/Telemetry/MetricTypes.html +1 -1
- data/docs/Tasker/Telemetry/MetricsBackend.html +1 -1
- data/docs/Tasker/Telemetry/MetricsExportService.html +1 -1
- data/docs/Tasker/Telemetry/PluginRegistry.html +1 -1
- data/docs/Tasker/Telemetry/Plugins/BaseExporter.html +1 -1
- data/docs/Tasker/Telemetry/Plugins/CsvExporter.html +1 -1
- data/docs/Tasker/Telemetry/Plugins/JsonExporter.html +1 -1
- data/docs/Tasker/Telemetry/Plugins.html +1 -1
- data/docs/Tasker/Telemetry/PrometheusExporter.html +1 -1
- data/docs/Tasker/Telemetry/TraceBackend.html +1 -1
- data/docs/Tasker/Telemetry.html +1 -1
- data/docs/Tasker/Types/AuthConfig.html +1 -1
- data/docs/Tasker/Types/BackoffConfig.html +1 -1
- data/docs/Tasker/Types/BaseConfig.html +1 -1
- data/docs/Tasker/Types/CacheConfig.html +1 -1
- data/docs/Tasker/Types/DatabaseConfig.html +1 -1
- data/docs/Tasker/Types/DependencyGraph.html +1 -1
- data/docs/Tasker/Types/DependencyGraphConfig.html +1 -1
- data/docs/Tasker/Types/EngineConfig.html +1 -1
- data/docs/Tasker/Types/ExecutionConfig.html +1 -1
- data/docs/Tasker/Types/GraphEdge.html +1 -1
- data/docs/Tasker/Types/GraphMetadata.html +1 -1
- data/docs/Tasker/Types/GraphNode.html +1 -1
- data/docs/Tasker/Types/HealthConfig.html +1 -1
- data/docs/Tasker/Types/StepSequence.html +1 -1
- data/docs/Tasker/Types/StepTemplate.html +1 -1
- data/docs/Tasker/Types/TaskRequest.html +1 -1
- data/docs/Tasker/Types/TelemetryConfig.html +2 -2
- data/docs/Tasker/Types.html +1 -1
- data/docs/Tasker/WorkflowStep/StepFinder.html +1 -1
- data/docs/Tasker/WorkflowStep.html +1 -1
- data/docs/Tasker/WorkflowStepEdge.html +4 -6
- data/docs/Tasker/WorkflowStepSerializer.html +1 -1
- data/docs/Tasker/WorkflowStepTransition/TransitionDescriptionFormatter.html +1 -1
- data/docs/Tasker/WorkflowStepTransition.html +1 -1
- data/docs/Tasker/WorkflowStepsController.html +1 -1
- data/docs/Tasker.html +2 -18
- data/docs/VISION.md +1 -1
- data/docs/_index.html +1 -1
- data/docs/file.README.html +9 -9
- data/docs/index.html +9 -9
- data/docs/method_list.html +74 -74
- data/docs/top-level-namespace.html +1 -1
- data/lib/generators/tasker/authenticator_generator.rb +5 -5
- data/lib/generators/tasker/authorization_coordinator_generator.rb +1 -1
- data/lib/generators/tasker/events_generator.rb +1 -1
- data/lib/generators/tasker/task_handler_generator.rb +4 -4
- data/lib/generators/tasker/templates/api_token_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/custom_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/devise_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/initialize.rb.erb +1 -1
- data/lib/generators/tasker/templates/jwt_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/omniauth_authenticator.rb.erb +1 -1
- data/lib/generators/tasker/templates/opentelemetry_initializer.rb +4 -4
- data/lib/generators/tasker/templates/task_config.yaml.erb +25 -25
- data/lib/generators/tasker/templates/task_handler.rb.erb +2 -3
- data/lib/generators/tasker/templates/task_handler_spec.rb.erb +43 -49
- data/lib/tasker/analysis/runtime_graph_analyzer.rb +1 -1
- data/lib/tasker/authentication/coordinator.rb +2 -2
- data/lib/tasker/authorization/base_coordinator.rb +1 -1
- data/lib/tasker/authorization.rb +1 -1
- data/lib/tasker/concerns/authenticatable.rb +1 -1
- data/lib/tasker/concerns/controller_authorizable.rb +3 -3
- data/lib/tasker/concerns/structured_logging.rb +2 -2
- data/lib/tasker/events/definition_loader.rb +1 -1
- data/lib/tasker/events/subscribers/metrics_subscriber.rb +1 -1
- data/lib/tasker/events/subscribers/telemetry_subscriber.rb +5 -5
- data/lib/tasker/health/readiness_checker.rb +1 -1
- data/lib/tasker/health/status_checker.rb +1 -1
- data/lib/tasker/logging/correlation_id_generator.rb +1 -1
- data/lib/tasker/orchestration/backoff_calculator.rb +1 -1
- data/lib/tasker/orchestration/connection_builder.rb +1 -1
- data/lib/tasker/orchestration/connection_pool_intelligence.rb +3 -3
- data/lib/tasker/orchestration/step_executor.rb +2 -2
- data/lib/tasker/orchestration/task_finalizer.rb +1 -1
- data/lib/tasker/registry/base_registry.rb +1 -1
- data/lib/tasker/task_builder.rb +1 -1
- data/lib/tasker/telemetry/intelligent_cache_manager.rb +1 -1
- data/lib/tasker/telemetry/metric_types.rb +9 -57
- data/lib/tasker/telemetry/metrics_backend.rb +3 -3
- data/lib/tasker/telemetry/metrics_export_service.rb +1 -1
- data/lib/tasker/telemetry/prometheus_exporter.rb +2 -2
- data/lib/tasker/types/telemetry_config.rb +1 -1
- data/lib/tasker/version.rb +1 -2
- data/lib/tasks/tasker_tasks.rake +4 -85
- metadata +4 -7
- data/db/functions/get_step_readiness_status_single_and_batch_v02.sql +0 -223
- data/db/migrate/20250710110830_step_readiness_sql_functions_v02.rb +0 -39
- data/docs/REVERSIONING.md +0 -404
|
@@ -476,8 +476,8 @@ module Tasker
|
|
|
476
476
|
}
|
|
477
477
|
|
|
478
478
|
# Override with telemetry configuration if available
|
|
479
|
-
if defined?(Tasker
|
|
480
|
-
telemetry_config = Tasker
|
|
479
|
+
if defined?(Tasker.configuration) && Tasker.configuration.telemetry
|
|
480
|
+
telemetry_config = Tasker.configuration.telemetry
|
|
481
481
|
base_config[:retention_window] = (telemetry_config.metrics_retention_hours || 1).hours
|
|
482
482
|
end
|
|
483
483
|
|
|
@@ -1074,7 +1074,7 @@ module Tasker
|
|
|
1074
1074
|
# @return [Hash] Versioned snapshot data
|
|
1075
1075
|
def create_versioned_snapshot
|
|
1076
1076
|
{
|
|
1077
|
-
version: Tasker::
|
|
1077
|
+
version: Tasker::VERSION,
|
|
1078
1078
|
timestamp: Time.current.iso8601,
|
|
1079
1079
|
instance_id: @instance_id,
|
|
1080
1080
|
cache_strategy: @sync_strategy,
|
|
@@ -325,7 +325,7 @@ module Tasker
|
|
|
325
325
|
#
|
|
326
326
|
# @return [Hash] Default Prometheus configuration
|
|
327
327
|
def default_prometheus_config
|
|
328
|
-
Tasker
|
|
328
|
+
Tasker.configuration.telemetry.prometheus
|
|
329
329
|
rescue StandardError
|
|
330
330
|
{}
|
|
331
331
|
end
|
|
@@ -212,9 +212,9 @@ module Tasker
|
|
|
212
212
|
#
|
|
213
213
|
# @return [Boolean] True if telemetry is enabled
|
|
214
214
|
def telemetry_enabled?
|
|
215
|
-
return false unless defined?(Tasker
|
|
215
|
+
return false unless defined?(Tasker.configuration)
|
|
216
216
|
|
|
217
|
-
Tasker
|
|
217
|
+
Tasker.configuration.telemetry.metrics_enabled
|
|
218
218
|
end
|
|
219
219
|
|
|
220
220
|
# Log export error with structured logging
|
|
@@ -41,7 +41,7 @@ module Tasker
|
|
|
41
41
|
#
|
|
42
42
|
# @!attribute [r] service_version
|
|
43
43
|
# @return [String] Service version for telemetry
|
|
44
|
-
attribute :service_version, Types::String.default(
|
|
44
|
+
attribute :service_version, Types::String.default(proc { Tasker::VERSION }.freeze, shared: true)
|
|
45
45
|
|
|
46
46
|
# Parameters to filter from logs and telemetry
|
|
47
47
|
# Can contain symbols, strings, or regex patterns as supported by Rails
|
data/lib/tasker/version.rb
CHANGED
data/lib/tasks/tasker_tasks.rake
CHANGED
|
@@ -12,9 +12,6 @@ namespace :tasker do
|
|
|
12
12
|
|
|
13
13
|
puts 'Installing Tasker database objects...'
|
|
14
14
|
|
|
15
|
-
# Check and configure SQL schema format
|
|
16
|
-
check_and_configure_sql_schema_format
|
|
17
|
-
|
|
18
15
|
# Find the Tasker gem path using multiple methods for reliability
|
|
19
16
|
tasker_gem_path = find_tasker_gem_path
|
|
20
17
|
|
|
@@ -115,84 +112,6 @@ namespace :tasker do
|
|
|
115
112
|
puts ' This may indicate an incomplete Tasker installation'
|
|
116
113
|
end
|
|
117
114
|
end
|
|
118
|
-
|
|
119
|
-
# Check if SQL schema format is configured and offer to fix it if needed
|
|
120
|
-
def check_and_configure_sql_schema_format
|
|
121
|
-
application_rb_path = Rails.root.join('config/application.rb')
|
|
122
|
-
|
|
123
|
-
unless File.exist?(application_rb_path)
|
|
124
|
-
puts "⚠️ Application file not found: #{application_rb_path}"
|
|
125
|
-
puts ' This is unexpected for a Rails application.'
|
|
126
|
-
return
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
application_content = File.read(application_rb_path)
|
|
130
|
-
|
|
131
|
-
if application_content.include?('config.active_record.schema_format = :sql')
|
|
132
|
-
puts '✅ SQL schema format already configured'
|
|
133
|
-
return
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
puts ''
|
|
137
|
-
puts '⚠️ IMPORTANT: SQL Schema Format Configuration Required'
|
|
138
|
-
puts ''
|
|
139
|
-
puts ' Tasker uses database functions and views that are not preserved'
|
|
140
|
-
puts " in Rails' default schema.rb file. To ensure these database objects"
|
|
141
|
-
puts ' are properly recreated during test database drops/recreates, you'
|
|
142
|
-
puts ' need to configure Rails to use structure.sql instead.'
|
|
143
|
-
puts ''
|
|
144
|
-
puts ' This requires adding the following line to config/application.rb:'
|
|
145
|
-
puts ' config.active_record.schema_format = :sql'
|
|
146
|
-
puts ''
|
|
147
|
-
print ' Would you like me to add this configuration automatically? (y/n): '
|
|
148
|
-
|
|
149
|
-
response = $stdin.gets.chomp.downcase
|
|
150
|
-
|
|
151
|
-
if %w[y yes].include?(response)
|
|
152
|
-
if update_application_rb_schema_format(application_rb_path, application_content)
|
|
153
|
-
puts '✅ SQL schema format configured successfully!'
|
|
154
|
-
puts ' Your application will now use db/structure.sql instead of db/schema.rb'
|
|
155
|
-
else
|
|
156
|
-
puts '❌ Failed to update application.rb automatically'
|
|
157
|
-
puts ' Please manually add: config.active_record.schema_format = :sql'
|
|
158
|
-
puts ' to your config/application.rb file inside the Application class'
|
|
159
|
-
end
|
|
160
|
-
else
|
|
161
|
-
puts '⚠️ Skipping automatic configuration.'
|
|
162
|
-
puts ' WARNING: Database functions and views may not work correctly'
|
|
163
|
-
puts ' in test environments without this configuration.'
|
|
164
|
-
puts ''
|
|
165
|
-
puts ' To configure manually, add this line to config/application.rb:'
|
|
166
|
-
puts ' config.active_record.schema_format = :sql'
|
|
167
|
-
end
|
|
168
|
-
puts ''
|
|
169
|
-
end
|
|
170
|
-
|
|
171
|
-
# Update application.rb to include SQL schema format configuration
|
|
172
|
-
#
|
|
173
|
-
# @param application_rb_path [String] Path to application.rb file
|
|
174
|
-
# @param application_content [String] Current content of application.rb
|
|
175
|
-
# @return [Boolean] Success status
|
|
176
|
-
def update_application_rb_schema_format(application_rb_path, application_content)
|
|
177
|
-
if application_content.include?('class Application < Rails::Application')
|
|
178
|
-
# Add SQL schema format configuration
|
|
179
|
-
new_application_content = application_content.gsub(
|
|
180
|
-
/(class Application < Rails::Application\s*\n)/,
|
|
181
|
-
"\\1 # Configure SQL schema format to preserve database functions and views\n config.active_record.schema_format = :sql\n\n"
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
begin
|
|
185
|
-
File.write(application_rb_path, new_application_content)
|
|
186
|
-
true
|
|
187
|
-
rescue StandardError => e
|
|
188
|
-
puts " Error writing to application.rb: #{e.message}"
|
|
189
|
-
false
|
|
190
|
-
end
|
|
191
|
-
else
|
|
192
|
-
puts ' Could not find Application class in application.rb'
|
|
193
|
-
false
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
115
|
end
|
|
197
116
|
|
|
198
117
|
# @!method setup
|
|
@@ -221,9 +140,9 @@ namespace :tasker do
|
|
|
221
140
|
end
|
|
222
141
|
|
|
223
142
|
# Create necessary directories based on configuration
|
|
224
|
-
task_handler_dir = Rails.root.join('app', Tasker
|
|
225
|
-
task_config_dir = Rails.root.join('config', Tasker
|
|
226
|
-
task_spec_dir = Rails.root.join('spec', Tasker
|
|
143
|
+
task_handler_dir = Rails.root.join('app', Tasker.configuration.engine.task_handler_directory)
|
|
144
|
+
task_config_dir = Rails.root.join('config', Tasker.configuration.engine.task_config_directory)
|
|
145
|
+
task_spec_dir = Rails.root.join('spec', Tasker.configuration.engine.task_handler_directory)
|
|
227
146
|
|
|
228
147
|
[task_handler_dir, task_config_dir, task_spec_dir].each do |dir|
|
|
229
148
|
unless File.directory?(dir)
|
|
@@ -359,7 +278,7 @@ namespace :tasker do
|
|
|
359
278
|
end
|
|
360
279
|
|
|
361
280
|
# Configuration
|
|
362
|
-
config = Tasker
|
|
281
|
+
config = Tasker.configuration.telemetry
|
|
363
282
|
puts "\nTelemetry Configuration:"
|
|
364
283
|
puts " Enabled: #{config.enabled}"
|
|
365
284
|
puts " Metrics Enabled: #{config.metrics_enabled}"
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: tasker-engine
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 1.0.2
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Pete Taylor
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2025-07-
|
|
11
|
+
date: 2025-07-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: logger
|
|
@@ -30,14 +30,14 @@ dependencies:
|
|
|
30
30
|
requirements:
|
|
31
31
|
- - "~>"
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
33
|
+
version: 7.2.2
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
38
|
- - "~>"
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
40
|
+
version: 7.2.2
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
42
42
|
name: pg
|
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -417,14 +417,12 @@ files:
|
|
|
417
417
|
- db/functions/get_slowest_steps_v01.sql
|
|
418
418
|
- db/functions/get_slowest_tasks_v01.sql
|
|
419
419
|
- db/functions/get_step_readiness_status_batch_v01.sql
|
|
420
|
-
- db/functions/get_step_readiness_status_single_and_batch_v02.sql
|
|
421
420
|
- db/functions/get_step_readiness_status_v01.sql
|
|
422
421
|
- db/functions/get_system_health_counts_v01.sql
|
|
423
422
|
- db/functions/get_task_execution_context_v01.sql
|
|
424
423
|
- db/functions/get_task_execution_contexts_batch_v01.sql
|
|
425
424
|
- db/init/schema.sql
|
|
426
425
|
- db/migrate/20250701165431_initial_tasker_schema.rb
|
|
427
|
-
- db/migrate/20250710110830_step_readiness_sql_functions_v02.rb
|
|
428
426
|
- db/views/tasker_step_dag_relationships_v01.sql
|
|
429
427
|
- docs/APPLICATION_GENERATOR.md
|
|
430
428
|
- docs/AUTH.md
|
|
@@ -440,7 +438,6 @@ files:
|
|
|
440
438
|
- docs/QUICK_START.md
|
|
441
439
|
- docs/REGISTRY_SYSTEMS.md
|
|
442
440
|
- docs/REST_API.md
|
|
443
|
-
- docs/REVERSIONING.md
|
|
444
441
|
- docs/ROADMAP.md
|
|
445
442
|
- docs/SQL_FUNCTIONS.md
|
|
446
443
|
- docs/TASK_EXECUTION_CONTROL_FLOW.md
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
-- Fix step readiness logic for NULL attempts
|
|
2
|
-
-- When attempts is NULL, it should be treated as 0 for comparison purposes
|
|
3
|
-
|
|
4
|
-
-- Update get_step_readiness_status function
|
|
5
|
-
CREATE OR REPLACE FUNCTION get_step_readiness_status(input_task_id bigint, step_ids bigint[] DEFAULT NULL::bigint[]) RETURNS TABLE(workflow_step_id bigint, task_id bigint, named_step_id integer, name text, current_state text, dependencies_satisfied boolean, retry_eligible boolean, ready_for_execution boolean, last_failure_at timestamp without time zone, next_retry_at timestamp without time zone, total_parents integer, completed_parents integer, attempts integer, retry_limit integer, backoff_request_seconds integer, last_attempted_at timestamp without time zone)
|
|
6
|
-
LANGUAGE plpgsql STABLE
|
|
7
|
-
AS $$
|
|
8
|
-
BEGIN
|
|
9
|
-
RETURN QUERY
|
|
10
|
-
SELECT
|
|
11
|
-
ws.workflow_step_id,
|
|
12
|
-
ws.task_id,
|
|
13
|
-
ws.named_step_id,
|
|
14
|
-
ns.name::TEXT,
|
|
15
|
-
|
|
16
|
-
-- Current State Information (optimized using most_recent flag)
|
|
17
|
-
COALESCE(current_state.to_state, 'pending')::TEXT as current_state,
|
|
18
|
-
|
|
19
|
-
-- Dependency Satisfaction Analysis
|
|
20
|
-
CASE
|
|
21
|
-
WHEN dep_edges.to_step_id IS NULL OR
|
|
22
|
-
COUNT(dep_edges.from_step_id) = 0 THEN true
|
|
23
|
-
ELSE
|
|
24
|
-
COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id)
|
|
25
|
-
END as dependencies_satisfied,
|
|
26
|
-
|
|
27
|
-
-- Retry Eligibility
|
|
28
|
-
CASE
|
|
29
|
-
WHEN COALESCE(ws.attempts, 0) < COALESCE(ws.retry_limit, 3) THEN true
|
|
30
|
-
ELSE false
|
|
31
|
-
END as retry_eligible,
|
|
32
|
-
|
|
33
|
-
-- Overall Ready for Execution (complex business logic)
|
|
34
|
-
CASE
|
|
35
|
-
WHEN COALESCE(current_state.to_state, 'pending') IN ('pending', 'error')
|
|
36
|
-
AND (ws.processed = false OR ws.processed IS NULL) -- CRITICAL: Only unprocessed steps can be ready
|
|
37
|
-
AND (dep_edges.to_step_id IS NULL OR
|
|
38
|
-
COUNT(dep_edges.from_step_id) = 0 OR
|
|
39
|
-
COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id))
|
|
40
|
-
AND (COALESCE(ws.attempts, 0) < COALESCE(ws.retry_limit, 3)) -- FIXED: Handle NULL attempts
|
|
41
|
-
AND (COALESCE(ws.retryable, true) = true)
|
|
42
|
-
AND (ws.in_process = false OR ws.in_process IS NULL)
|
|
43
|
-
AND (
|
|
44
|
-
-- Check explicit backoff timing (most restrictive)
|
|
45
|
-
-- If backoff is set, the backoff period must have expired
|
|
46
|
-
CASE
|
|
47
|
-
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
|
48
|
-
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second') <= NOW()
|
|
49
|
-
ELSE true -- No explicit backoff set
|
|
50
|
-
END
|
|
51
|
-
AND
|
|
52
|
-
-- Then check failure-based backoff
|
|
53
|
-
(last_failure.created_at IS NULL OR
|
|
54
|
-
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds')) <= NOW())
|
|
55
|
-
)
|
|
56
|
-
THEN true
|
|
57
|
-
ELSE false
|
|
58
|
-
END as ready_for_execution,
|
|
59
|
-
|
|
60
|
-
-- Timing Information
|
|
61
|
-
last_failure.created_at as last_failure_at,
|
|
62
|
-
CASE
|
|
63
|
-
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
|
64
|
-
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second')
|
|
65
|
-
WHEN last_failure.created_at IS NOT NULL THEN
|
|
66
|
-
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds'))
|
|
67
|
-
ELSE NULL
|
|
68
|
-
END as next_retry_at,
|
|
69
|
-
|
|
70
|
-
-- Dependency Context (calculated from joins)
|
|
71
|
-
COALESCE(COUNT(dep_edges.from_step_id), 0)::INTEGER as total_parents,
|
|
72
|
-
COALESCE(COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END), 0)::INTEGER as completed_parents,
|
|
73
|
-
|
|
74
|
-
-- Retry Context
|
|
75
|
-
COALESCE(ws.attempts, 0)::INTEGER as attempts, -- FIXED: Return 0 instead of NULL
|
|
76
|
-
COALESCE(ws.retry_limit, 3) as retry_limit,
|
|
77
|
-
ws.backoff_request_seconds,
|
|
78
|
-
ws.last_attempted_at
|
|
79
|
-
|
|
80
|
-
FROM tasker_workflow_steps ws
|
|
81
|
-
JOIN tasker_named_steps ns ON ns.named_step_id = ws.named_step_id
|
|
82
|
-
|
|
83
|
-
-- OPTIMIZED: Current State using most_recent flag instead of DISTINCT ON
|
|
84
|
-
LEFT JOIN tasker_workflow_step_transitions current_state
|
|
85
|
-
ON current_state.workflow_step_id = ws.workflow_step_id
|
|
86
|
-
AND current_state.most_recent = true
|
|
87
|
-
|
|
88
|
-
-- OPTIMIZED: Dependency check using direct joins (no subquery)
|
|
89
|
-
LEFT JOIN tasker_workflow_step_edges dep_edges
|
|
90
|
-
ON dep_edges.to_step_id = ws.workflow_step_id
|
|
91
|
-
LEFT JOIN tasker_workflow_step_transitions parent_states
|
|
92
|
-
ON parent_states.workflow_step_id = dep_edges.from_step_id
|
|
93
|
-
AND parent_states.most_recent = true
|
|
94
|
-
|
|
95
|
-
-- OPTIMIZED: Last failure using index-optimized approach
|
|
96
|
-
LEFT JOIN tasker_workflow_step_transitions last_failure
|
|
97
|
-
ON last_failure.workflow_step_id = ws.workflow_step_id
|
|
98
|
-
AND last_failure.to_state = 'error'
|
|
99
|
-
AND last_failure.most_recent = true
|
|
100
|
-
|
|
101
|
-
-- KEY PERFORMANCE IMPROVEMENT: Filter by task first, then optionally by step IDs
|
|
102
|
-
-- CRITICAL FIX: Include ALL steps for task execution context calculation
|
|
103
|
-
-- Only filter by processed status when specifically querying for ready steps
|
|
104
|
-
WHERE ws.task_id = input_task_id
|
|
105
|
-
AND (step_ids IS NULL OR ws.workflow_step_id = ANY(step_ids))
|
|
106
|
-
|
|
107
|
-
GROUP BY
|
|
108
|
-
ws.workflow_step_id, ws.task_id, ws.named_step_id, ns.name,
|
|
109
|
-
current_state.to_state, last_failure.created_at,
|
|
110
|
-
ws.attempts, ws.retry_limit, ws.backoff_request_seconds, ws.last_attempted_at,
|
|
111
|
-
ws.in_process, ws.processed, ws.retryable, dep_edges.to_step_id,
|
|
112
|
-
current_state.workflow_step_id, last_failure.workflow_step_id;
|
|
113
|
-
END;
|
|
114
|
-
$$;
|
|
115
|
-
|
|
116
|
-
-- Also update the batch version
|
|
117
|
-
CREATE OR REPLACE FUNCTION get_step_readiness_status_batch(input_task_ids bigint[]) RETURNS TABLE(workflow_step_id bigint, task_id bigint, named_step_id integer, name text, current_state text, dependencies_satisfied boolean, retry_eligible boolean, ready_for_execution boolean, last_failure_at timestamp without time zone, next_retry_at timestamp without time zone, total_parents integer, completed_parents integer, attempts integer, retry_limit integer, backoff_request_seconds integer, last_attempted_at timestamp without time zone)
|
|
118
|
-
LANGUAGE plpgsql STABLE
|
|
119
|
-
AS $$
|
|
120
|
-
BEGIN
|
|
121
|
-
RETURN QUERY
|
|
122
|
-
SELECT
|
|
123
|
-
ws.workflow_step_id,
|
|
124
|
-
ws.task_id,
|
|
125
|
-
ws.named_step_id,
|
|
126
|
-
ns.name::TEXT,
|
|
127
|
-
|
|
128
|
-
-- Current State Information (optimized using most_recent flag)
|
|
129
|
-
COALESCE(current_state.to_state, 'pending')::TEXT as current_state,
|
|
130
|
-
|
|
131
|
-
-- Dependency Satisfaction Analysis
|
|
132
|
-
CASE
|
|
133
|
-
WHEN dep_edges.to_step_id IS NULL OR
|
|
134
|
-
COUNT(dep_edges.from_step_id) = 0 THEN true
|
|
135
|
-
ELSE
|
|
136
|
-
COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id)
|
|
137
|
-
END as dependencies_satisfied,
|
|
138
|
-
|
|
139
|
-
-- Retry Eligibility
|
|
140
|
-
CASE
|
|
141
|
-
WHEN COALESCE(ws.attempts, 0) < COALESCE(ws.retry_limit, 3) THEN true
|
|
142
|
-
ELSE false
|
|
143
|
-
END as retry_eligible,
|
|
144
|
-
|
|
145
|
-
-- Overall Ready for Execution (complex business logic)
|
|
146
|
-
CASE
|
|
147
|
-
WHEN COALESCE(current_state.to_state, 'pending') IN ('pending', 'error')
|
|
148
|
-
AND (ws.processed = false OR ws.processed IS NULL)
|
|
149
|
-
AND (dep_edges.to_step_id IS NULL OR
|
|
150
|
-
COUNT(dep_edges.from_step_id) = 0 OR
|
|
151
|
-
COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END) = COUNT(dep_edges.from_step_id))
|
|
152
|
-
AND (COALESCE(ws.attempts, 0) < COALESCE(ws.retry_limit, 3)) -- FIXED: Handle NULL attempts
|
|
153
|
-
AND (COALESCE(ws.retryable, true) = true)
|
|
154
|
-
AND (ws.in_process = false OR ws.in_process IS NULL)
|
|
155
|
-
AND (
|
|
156
|
-
-- Check explicit backoff timing (most restrictive)
|
|
157
|
-
-- If backoff is set, the backoff period must have expired
|
|
158
|
-
CASE
|
|
159
|
-
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
|
160
|
-
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second') <= NOW()
|
|
161
|
-
ELSE true -- No explicit backoff set
|
|
162
|
-
END
|
|
163
|
-
AND
|
|
164
|
-
-- Then check failure-based backoff
|
|
165
|
-
(last_failure.created_at IS NULL OR
|
|
166
|
-
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds')) <= NOW())
|
|
167
|
-
)
|
|
168
|
-
THEN true
|
|
169
|
-
ELSE false
|
|
170
|
-
END as ready_for_execution,
|
|
171
|
-
|
|
172
|
-
-- Timing Information
|
|
173
|
-
last_failure.created_at as last_failure_at,
|
|
174
|
-
CASE
|
|
175
|
-
WHEN ws.backoff_request_seconds IS NOT NULL AND ws.last_attempted_at IS NOT NULL THEN
|
|
176
|
-
ws.last_attempted_at + (ws.backoff_request_seconds * interval '1 second')
|
|
177
|
-
WHEN last_failure.created_at IS NOT NULL THEN
|
|
178
|
-
last_failure.created_at + (LEAST(power(2, COALESCE(ws.attempts, 1)) * interval '1 second', interval '30 seconds'))
|
|
179
|
-
ELSE NULL
|
|
180
|
-
END as next_retry_at,
|
|
181
|
-
|
|
182
|
-
-- Dependency Context (calculated from joins)
|
|
183
|
-
COALESCE(COUNT(dep_edges.from_step_id), 0)::INTEGER as total_parents,
|
|
184
|
-
COALESCE(COUNT(CASE WHEN parent_states.to_state IN ('complete', 'resolved_manually') THEN 1 END), 0)::INTEGER as completed_parents,
|
|
185
|
-
|
|
186
|
-
-- Retry Context
|
|
187
|
-
COALESCE(ws.attempts, 0)::INTEGER as attempts, -- FIXED: Return 0 instead of NULL
|
|
188
|
-
COALESCE(ws.retry_limit, 3) as retry_limit,
|
|
189
|
-
ws.backoff_request_seconds,
|
|
190
|
-
ws.last_attempted_at
|
|
191
|
-
|
|
192
|
-
FROM tasker_workflow_steps ws
|
|
193
|
-
JOIN tasker_named_steps ns ON ns.named_step_id = ws.named_step_id
|
|
194
|
-
|
|
195
|
-
-- OPTIMIZED: Current State using most_recent flag instead of DISTINCT ON
|
|
196
|
-
LEFT JOIN tasker_workflow_step_transitions current_state
|
|
197
|
-
ON current_state.workflow_step_id = ws.workflow_step_id
|
|
198
|
-
AND current_state.most_recent = true
|
|
199
|
-
|
|
200
|
-
-- OPTIMIZED: Dependency check using direct joins (no subquery)
|
|
201
|
-
LEFT JOIN tasker_workflow_step_edges dep_edges
|
|
202
|
-
ON dep_edges.to_step_id = ws.workflow_step_id
|
|
203
|
-
LEFT JOIN tasker_workflow_step_transitions parent_states
|
|
204
|
-
ON parent_states.workflow_step_id = dep_edges.from_step_id
|
|
205
|
-
AND parent_states.most_recent = true
|
|
206
|
-
|
|
207
|
-
-- OPTIMIZED: Last failure using index-optimized approach
|
|
208
|
-
LEFT JOIN tasker_workflow_step_transitions last_failure
|
|
209
|
-
ON last_failure.workflow_step_id = ws.workflow_step_id
|
|
210
|
-
AND last_failure.to_state = 'error'
|
|
211
|
-
AND last_failure.most_recent = true
|
|
212
|
-
|
|
213
|
-
-- KEY PERFORMANCE IMPROVEMENT: Filter by task first, then optionally by step IDs
|
|
214
|
-
WHERE ws.task_id = ANY(input_task_ids)
|
|
215
|
-
|
|
216
|
-
GROUP BY
|
|
217
|
-
ws.workflow_step_id, ws.task_id, ws.named_step_id, ns.name,
|
|
218
|
-
current_state.to_state, last_failure.created_at,
|
|
219
|
-
ws.attempts, ws.retry_limit, ws.backoff_request_seconds, ws.last_attempted_at,
|
|
220
|
-
ws.in_process, ws.processed, ws.retryable, dep_edges.to_step_id,
|
|
221
|
-
current_state.workflow_step_id, last_failure.workflow_step_id;
|
|
222
|
-
END;
|
|
223
|
-
$$;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
class StepReadinessSqlFunctionsV02 < ActiveRecord::Migration[7.2]
|
|
4
|
-
def up
|
|
5
|
-
if defined?(Tasker::Engine)
|
|
6
|
-
# When running in engine context, look in the engine root
|
|
7
|
-
engine_root = Tasker::Engine.root
|
|
8
|
-
sql_file = engine_root.join('db', 'functions', 'get_step_readiness_status_single_and_batch_v02.sql')
|
|
9
|
-
else
|
|
10
|
-
# When running standalone, use Rails.root
|
|
11
|
-
sql_file = Rails.root.join('db/functions/get_step_readiness_status_single_and_batch_v02.sql')
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
unless File.exist?(sql_file)
|
|
15
|
-
raise "SQL file not found at #{sql_file}. Please ensure db/functions/get_step_readiness_status_single_and_batch_v02.sql exists."
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
execute(File.read(sql_file))
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
def down
|
|
22
|
-
path_root = if defined?(Tasker::Engine)
|
|
23
|
-
# When running in engine context, look in the engine root
|
|
24
|
-
Tasker::Engine.root
|
|
25
|
-
else
|
|
26
|
-
# When running standalone, use Rails.root
|
|
27
|
-
Rails.root
|
|
28
|
-
end
|
|
29
|
-
original_sql_files = [
|
|
30
|
-
'get_step_readiness_status_v01.sql',
|
|
31
|
-
'get_step_readiness_status_batch_v01.sql'
|
|
32
|
-
]
|
|
33
|
-
|
|
34
|
-
original_sql_files.each do |file|
|
|
35
|
-
sql_file = File.read(path_root.join('db', 'functions', file))
|
|
36
|
-
execute(sql_file)
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|