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