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
data/docs/METRICS.md
ADDED
@@ -0,0 +1,731 @@
|
|
1
|
+
# Tasker Metrics System
|
2
|
+
|
3
|
+
## Overview
|
4
|
+
|
5
|
+
Tasker's metrics system provides production-ready observability for workflow orchestration through a hybrid architecture that combines high-performance in-memory collection with persistent, distributed storage. This system is designed to be cache-store agnostic, infrastructure-independent, and production-scalable.
|
6
|
+
|
7
|
+
## Architecture Philosophy
|
8
|
+
|
9
|
+
### Distinct Systems: Event Subscribers vs Metrics Collector
|
10
|
+
|
11
|
+
Tasker employs **two complementary but distinct observability systems** with clear separation of concerns:
|
12
|
+
|
13
|
+
#### **🔍 TelemetrySubscriber (Event-Driven Spans)**
|
14
|
+
- **Purpose**: Detailed tracing and debugging with OpenTelemetry spans
|
15
|
+
- **Use Cases**:
|
16
|
+
- "Why did task #12345 fail?"
|
17
|
+
- "What's the execution path through this workflow?"
|
18
|
+
- "Which step is causing the bottleneck?"
|
19
|
+
- **Data**: Rich contextual information, hierarchical relationships, error details
|
20
|
+
- **Storage**: OpenTelemetry backends (Jaeger, Zipkin, Honeycomb)
|
21
|
+
- **Performance**: Optimized for detailed context, not high-volume aggregation
|
22
|
+
|
23
|
+
#### **📊 MetricsBackend (Native Metrics Collection)**
|
24
|
+
- **Purpose**: High-performance aggregated metrics for dashboards and alerting
|
25
|
+
- **Use Cases**:
|
26
|
+
- "How many tasks completed in the last hour?"
|
27
|
+
- "What's the 95th percentile execution time?"
|
28
|
+
- "Alert if error rate exceeds 5%"
|
29
|
+
- **Data**: Numerical counters, gauges, histograms with labels
|
30
|
+
- **Storage**: Prometheus, JSON, CSV exports
|
31
|
+
- **Performance**: Optimized for high-volume, low-latency operations
|
32
|
+
|
33
|
+
### Why Two Systems?
|
34
|
+
|
35
|
+
```mermaid
|
36
|
+
flowchart TD
|
37
|
+
subgraph Events[Event-Driven Observability]
|
38
|
+
TelemetrySubscriber[TelemetrySubscriber]
|
39
|
+
OpenTelemetry[OpenTelemetry Spans]
|
40
|
+
Jaeger[Jaeger/Zipkin]
|
41
|
+
end
|
42
|
+
|
43
|
+
subgraph Metrics[Native Metrics Collection]
|
44
|
+
MetricsBackend[MetricsBackend]
|
45
|
+
Prometheus[Prometheus Export]
|
46
|
+
Dashboards[Grafana Dashboards]
|
47
|
+
end
|
48
|
+
|
49
|
+
subgraph Business[Business Logic]
|
50
|
+
TaskExecution[Task Execution]
|
51
|
+
StepProcessing[Step Processing]
|
52
|
+
WorkflowOrchestration[Workflow Orchestration]
|
53
|
+
end
|
54
|
+
|
55
|
+
Business -->|Events| Events
|
56
|
+
Business -->|Direct Collection| Metrics
|
57
|
+
|
58
|
+
Events -->|Detailed Traces| Jaeger
|
59
|
+
Metrics -->|Aggregated Data| Dashboards
|
60
|
+
|
61
|
+
style Events fill:#e1f5fe,stroke:#01579b
|
62
|
+
style Metrics fill:#fff3e0,stroke:#ef6c00
|
63
|
+
style Business fill:#e8f5e8,stroke:#2e7d32
|
64
|
+
```
|
65
|
+
|
66
|
+
**Benefits of Separation**:
|
67
|
+
- **Performance**: Native metrics avoid event publishing overhead for high-frequency operations
|
68
|
+
- **Reliability**: Metrics collection continues even if event system has issues
|
69
|
+
- **Flexibility**: Choose appropriate storage backend for each use case
|
70
|
+
- **Scalability**: Each system optimized for its specific workload
|
71
|
+
|
72
|
+
## Core Components
|
73
|
+
|
74
|
+
### 1. MetricsBackend (Thread-Safe Collection)
|
75
|
+
|
76
|
+
The core metrics collection engine using `Concurrent::Hash` for thread-safe operations:
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
class MetricsBackend
|
80
|
+
include Singleton
|
81
|
+
|
82
|
+
def initialize
|
83
|
+
@metrics = Concurrent::Hash.new
|
84
|
+
@cache_capabilities = detect_cache_capabilities
|
85
|
+
@sync_strategy = select_sync_strategy
|
86
|
+
end
|
87
|
+
|
88
|
+
# High-performance metric operations
|
89
|
+
def counter(name, value: 1, **labels)
|
90
|
+
# Thread-safe increment operations
|
91
|
+
end
|
92
|
+
|
93
|
+
def gauge(name, value:, **labels)
|
94
|
+
# Atomic value updates
|
95
|
+
end
|
96
|
+
|
97
|
+
def histogram(name, value:, **labels)
|
98
|
+
# Concurrent histogram updates
|
99
|
+
end
|
100
|
+
end
|
101
|
+
```
|
102
|
+
|
103
|
+
### 2. Cache-Agnostic Sync Strategies
|
104
|
+
|
105
|
+
Adaptive synchronization based on Rails.cache capabilities:
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
# Automatic strategy selection based on cache store
|
109
|
+
@sync_strategy = case @cache_capabilities[:store_class]
|
110
|
+
when 'Redis::Store', 'RedisCacheStore'
|
111
|
+
:distributed_atomic # Full coordination with atomic operations
|
112
|
+
when 'MemCacheStore'
|
113
|
+
:distributed_basic # Basic coordination with read-modify-write
|
114
|
+
when 'FileStore', 'MemoryStore', 'NullStore'
|
115
|
+
:local_only # Local snapshots only
|
116
|
+
end
|
117
|
+
```
|
118
|
+
|
119
|
+
### 3. Export Coordination System
|
120
|
+
|
121
|
+
TTL-aware export scheduling with distributed coordination:
|
122
|
+
|
123
|
+
```ruby
|
124
|
+
class ExportCoordinator
|
125
|
+
def schedule_export(format: :prometheus)
|
126
|
+
# Calculate optimal export timing
|
127
|
+
timing = calculate_export_timing(safety_margin)
|
128
|
+
|
129
|
+
# Schedule with TTL safety
|
130
|
+
MetricsExportJob.set(wait_until: timing[:export_time])
|
131
|
+
.perform_later(format: format)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
```
|
135
|
+
|
136
|
+
## Cache Strategy Benefits and Drawbacks
|
137
|
+
|
138
|
+
### Redis Cache Store (`:redis_cache_store`)
|
139
|
+
|
140
|
+
#### ✅ Benefits
|
141
|
+
- **Full Coordination**: Atomic operations enable perfect cross-container synchronization
|
142
|
+
- **Distributed Locking**: Prevents concurrent export conflicts
|
143
|
+
- **TTL Inspection**: Can detect and extend cache expiration times
|
144
|
+
- **High Performance**: Optimized for concurrent access patterns
|
145
|
+
- **Persistence**: Survives container restarts and deployments
|
146
|
+
|
147
|
+
#### ⚠️ Considerations
|
148
|
+
- **Infrastructure Dependency**: Requires Redis cluster for production
|
149
|
+
- **Network Latency**: Sync operations involve network calls
|
150
|
+
- **Redis Memory**: Additional memory usage for metrics storage
|
151
|
+
- **Complexity**: More moving parts in infrastructure stack
|
152
|
+
|
153
|
+
**Best For**: Production environments with existing Redis infrastructure, multi-container deployments requiring coordination.
|
154
|
+
|
155
|
+
### Memcached (`:mem_cache_store`)
|
156
|
+
|
157
|
+
#### ✅ Benefits
|
158
|
+
- **Distributed Storage**: Shared cache across multiple containers
|
159
|
+
- **Atomic Operations**: Basic increment/decrement support
|
160
|
+
- **Mature Technology**: Well-understood operational characteristics
|
161
|
+
- **Memory Efficiency**: Optimized for memory usage patterns
|
162
|
+
|
163
|
+
#### ⚠️ Considerations
|
164
|
+
- **Limited Locking**: No distributed locking support
|
165
|
+
- **No TTL Inspection**: Cannot detect or extend expiration times
|
166
|
+
- **Basic Coordination**: Read-modify-write patterns only
|
167
|
+
- **Data Loss Risk**: No persistence across restarts
|
168
|
+
|
169
|
+
**Best For**: Environments with existing Memcached infrastructure, scenarios where basic distributed storage is sufficient.
|
170
|
+
|
171
|
+
### File Store (`:file_store`)
|
172
|
+
|
173
|
+
#### ✅ Benefits
|
174
|
+
- **No Infrastructure**: Works without external dependencies
|
175
|
+
- **Persistence**: Survives container restarts
|
176
|
+
- **Simple Deployment**: Easy to set up and maintain
|
177
|
+
- **Local Performance**: No network latency for operations
|
178
|
+
|
179
|
+
#### ⚠️ Considerations
|
180
|
+
- **No Distribution**: Cannot coordinate across containers
|
181
|
+
- **File I/O Overhead**: Disk operations slower than memory
|
182
|
+
- **Concurrency Limits**: File locking limitations
|
183
|
+
- **Storage Management**: Requires disk space management
|
184
|
+
|
185
|
+
**Best For**: Single-container deployments, development environments, scenarios where external dependencies are not allowed.
|
186
|
+
|
187
|
+
### Memory Store (`:memory_store`)
|
188
|
+
|
189
|
+
#### ✅ Benefits
|
190
|
+
- **Highest Performance**: Pure in-memory operations
|
191
|
+
- **No Dependencies**: No external infrastructure required
|
192
|
+
- **Simple Configuration**: Works out of the box
|
193
|
+
- **Low Latency**: Fastest possible cache operations
|
194
|
+
|
195
|
+
#### ⚠️ Considerations
|
196
|
+
- **Single Process Only**: No cross-container coordination
|
197
|
+
- **Data Loss**: Lost on container restart
|
198
|
+
- **Memory Limits**: Bounded by container memory
|
199
|
+
- **No Persistence**: Cannot survive deployments
|
200
|
+
|
201
|
+
**Best For**: Development environments, single-container applications, testing scenarios.
|
202
|
+
|
203
|
+
## Kubernetes Integration
|
204
|
+
|
205
|
+
### CronJob-Based Export Architecture
|
206
|
+
|
207
|
+
Tasker follows cloud-native patterns by providing export capabilities while delegating scheduling to Kubernetes:
|
208
|
+
|
209
|
+
```yaml
|
210
|
+
# Prometheus Export Every 5 Minutes
|
211
|
+
apiVersion: batch/v1
|
212
|
+
kind: CronJob
|
213
|
+
metadata:
|
214
|
+
name: tasker-metrics-export
|
215
|
+
namespace: production
|
216
|
+
spec:
|
217
|
+
schedule: "*/5 * * * *"
|
218
|
+
jobTemplate:
|
219
|
+
spec:
|
220
|
+
template:
|
221
|
+
spec:
|
222
|
+
containers:
|
223
|
+
- name: metrics-exporter
|
224
|
+
image: your-app:latest
|
225
|
+
command:
|
226
|
+
- /bin/bash
|
227
|
+
- -c
|
228
|
+
- |
|
229
|
+
cd /app && \
|
230
|
+
bundle exec rake tasker:export_metrics[prometheus]
|
231
|
+
env:
|
232
|
+
- name: RAILS_ENV
|
233
|
+
value: "production"
|
234
|
+
- name: METRICS_FORMAT
|
235
|
+
value: "prometheus"
|
236
|
+
resources:
|
237
|
+
requests:
|
238
|
+
memory: "128Mi"
|
239
|
+
cpu: "100m"
|
240
|
+
limits:
|
241
|
+
memory: "256Mi"
|
242
|
+
cpu: "200m"
|
243
|
+
restartPolicy: OnFailure
|
244
|
+
successfulJobsHistoryLimit: 3
|
245
|
+
failedJobsHistoryLimit: 3
|
246
|
+
```
|
247
|
+
|
248
|
+
### Cache Synchronization
|
249
|
+
|
250
|
+
```yaml
|
251
|
+
# Cache Sync Every 30 Seconds
|
252
|
+
apiVersion: batch/v1
|
253
|
+
kind: CronJob
|
254
|
+
metadata:
|
255
|
+
name: tasker-cache-sync
|
256
|
+
spec:
|
257
|
+
schedule: "*/1 * * * *" # Every minute
|
258
|
+
jobTemplate:
|
259
|
+
spec:
|
260
|
+
template:
|
261
|
+
spec:
|
262
|
+
containers:
|
263
|
+
- name: cache-sync
|
264
|
+
image: your-app:latest
|
265
|
+
command:
|
266
|
+
- /bin/bash
|
267
|
+
- -c
|
268
|
+
- |
|
269
|
+
cd /app && \
|
270
|
+
bundle exec rake tasker:sync_metrics && \
|
271
|
+
sleep 30 && \
|
272
|
+
bundle exec rake tasker:sync_metrics
|
273
|
+
resources:
|
274
|
+
requests:
|
275
|
+
memory: "64Mi"
|
276
|
+
cpu: "50m"
|
277
|
+
limits:
|
278
|
+
memory: "128Mi"
|
279
|
+
cpu: "100m"
|
280
|
+
```
|
281
|
+
|
282
|
+
### Monitoring and Alerting
|
283
|
+
|
284
|
+
```yaml
|
285
|
+
# Prometheus ServiceMonitor
|
286
|
+
apiVersion: monitoring.coreos.com/v1
|
287
|
+
kind: ServiceMonitor
|
288
|
+
metadata:
|
289
|
+
name: tasker-metrics
|
290
|
+
spec:
|
291
|
+
selector:
|
292
|
+
matchLabels:
|
293
|
+
app: tasker-metrics-exporter
|
294
|
+
endpoints:
|
295
|
+
- port: metrics
|
296
|
+
interval: 30s
|
297
|
+
path: /metrics
|
298
|
+
```
|
299
|
+
|
300
|
+
```yaml
|
301
|
+
# Prometheus Alerts
|
302
|
+
groups:
|
303
|
+
- name: tasker-metrics
|
304
|
+
rules:
|
305
|
+
- alert: TaskerMetricsExportFailed
|
306
|
+
expr: increase(kube_job_status_failed{job_name=~"tasker-metrics-export.*"}[1h]) > 0
|
307
|
+
for: 5m
|
308
|
+
labels:
|
309
|
+
severity: warning
|
310
|
+
annotations:
|
311
|
+
summary: "Tasker metrics export job failed"
|
312
|
+
description: "Metrics export job has failed {{ $value }} times in the last hour"
|
313
|
+
|
314
|
+
- alert: TaskerMetricsStale
|
315
|
+
expr: time() - kube_job_status_completion_time{job_name=~"tasker-metrics-export.*"} > 900
|
316
|
+
for: 10m
|
317
|
+
labels:
|
318
|
+
severity: critical
|
319
|
+
annotations:
|
320
|
+
summary: "Tasker metrics export stale"
|
321
|
+
description: "No successful metrics export in the last 15 minutes"
|
322
|
+
```
|
323
|
+
|
324
|
+
## Configuration
|
325
|
+
|
326
|
+
### Basic Configuration
|
327
|
+
|
328
|
+
```ruby
|
329
|
+
# config/initializers/tasker.rb
|
330
|
+
Tasker.configuration do |config|
|
331
|
+
config.telemetry do |tel|
|
332
|
+
# Enable native metrics collection
|
333
|
+
tel.metrics_enabled = true
|
334
|
+
tel.metrics_format = 'prometheus' # String, not symbol
|
335
|
+
|
336
|
+
# Prometheus export configuration
|
337
|
+
tel.prometheus = {
|
338
|
+
endpoint: ENV['PROMETHEUS_ENDPOINT'],
|
339
|
+
retention_window: 5.minutes,
|
340
|
+
safety_margin: 1.minute,
|
341
|
+
export_timeout: 2.minutes,
|
342
|
+
username: ENV['PROMETHEUS_USERNAME'], # Optional
|
343
|
+
password: ENV['PROMETHEUS_PASSWORD'] # Optional
|
344
|
+
}
|
345
|
+
end
|
346
|
+
end
|
347
|
+
```
|
348
|
+
|
349
|
+
### Advanced Configuration
|
350
|
+
|
351
|
+
```ruby
|
352
|
+
Tasker.configuration do |config|
|
353
|
+
config.telemetry do |tel|
|
354
|
+
tel.metrics_enabled = true
|
355
|
+
tel.metrics_format = 'prometheus'
|
356
|
+
|
357
|
+
# Prometheus export configuration (matches TelemetryConfig.default_prometheus_config)
|
358
|
+
tel.prometheus = {
|
359
|
+
# Prometheus remote write endpoint (nil disables export)
|
360
|
+
endpoint: 'http://prometheus:9090/api/v1/write',
|
361
|
+
|
362
|
+
# Basic authentication for Prometheus endpoint
|
363
|
+
username: ENV['PROMETHEUS_USERNAME'],
|
364
|
+
password: ENV['PROMETHEUS_PASSWORD'],
|
365
|
+
|
366
|
+
# Job configuration
|
367
|
+
job_timeout: 5.minutes,
|
368
|
+
export_timeout: 2.minutes,
|
369
|
+
retry_attempts: 3,
|
370
|
+
|
371
|
+
# Export scheduling
|
372
|
+
retention_window: 5.minutes,
|
373
|
+
safety_margin: 1.minute,
|
374
|
+
|
375
|
+
# Metric naming
|
376
|
+
metric_prefix: 'tasker',
|
377
|
+
include_instance_labels: true,
|
378
|
+
|
379
|
+
# Performance tuning
|
380
|
+
compression: 'snappy', # 'snappy', 'gzip', or nil
|
381
|
+
batch_size: 1000,
|
382
|
+
|
383
|
+
# Test/development mode
|
384
|
+
skip_if_unavailable: true # Don't fail if Prometheus is unreachable
|
385
|
+
}
|
386
|
+
end
|
387
|
+
end
|
388
|
+
```
|
389
|
+
|
390
|
+
### Environment-Specific Configuration
|
391
|
+
|
392
|
+
```ruby
|
393
|
+
# config/environments/production.rb
|
394
|
+
config.after_initialize do
|
395
|
+
Tasker.configuration do |config|
|
396
|
+
config.telemetry do |tel|
|
397
|
+
tel.metrics_enabled = true
|
398
|
+
tel.prometheus = {
|
399
|
+
endpoint: ENV.fetch('PROMETHEUS_ENDPOINT'),
|
400
|
+
retention_window: 10.minutes,
|
401
|
+
safety_margin: 2.minutes,
|
402
|
+
username: ENV['PROMETHEUS_USERNAME'],
|
403
|
+
password: ENV['PROMETHEUS_PASSWORD']
|
404
|
+
}
|
405
|
+
end
|
406
|
+
end
|
407
|
+
end
|
408
|
+
|
409
|
+
# config/environments/development.rb
|
410
|
+
config.after_initialize do
|
411
|
+
Tasker.configuration do |config|
|
412
|
+
config.telemetry do |tel|
|
413
|
+
tel.metrics_enabled = true
|
414
|
+
tel.prometheus = {
|
415
|
+
endpoint: 'http://localhost:9090/api/v1/write',
|
416
|
+
retention_window: 2.minutes,
|
417
|
+
safety_margin: 30.seconds,
|
418
|
+
skip_if_unavailable: true # Don't fail if Prometheus is unreachable in dev
|
419
|
+
}
|
420
|
+
end
|
421
|
+
end
|
422
|
+
end
|
423
|
+
```
|
424
|
+
|
425
|
+
## Dependencies and Assumptions
|
426
|
+
|
427
|
+
### Required Dependencies
|
428
|
+
|
429
|
+
```ruby
|
430
|
+
# Gemfile
|
431
|
+
gem 'concurrent-ruby', '~> 1.0' # Thread-safe data structures
|
432
|
+
gem 'activejob', '>= 6.0' # Background job processing
|
433
|
+
gem 'rails', '>= 6.0' # Rails.cache integration
|
434
|
+
```
|
435
|
+
|
436
|
+
### Optional Dependencies
|
437
|
+
|
438
|
+
```ruby
|
439
|
+
# For Redis cache store
|
440
|
+
gem 'redis', '~> 4.0'
|
441
|
+
gem 'redis-rails', '~> 5.0'
|
442
|
+
|
443
|
+
# For Memcached
|
444
|
+
gem 'dalli', '~> 3.0'
|
445
|
+
|
446
|
+
# For background job processing
|
447
|
+
gem 'sidekiq', '~> 6.0' # or
|
448
|
+
gem 'resque', '~> 2.0' # or
|
449
|
+
gem 'delayed_job_active_record', '~> 4.0'
|
450
|
+
```
|
451
|
+
|
452
|
+
### Infrastructure Assumptions
|
453
|
+
|
454
|
+
#### **Cache Store**
|
455
|
+
- Rails.cache properly configured
|
456
|
+
- Cache store supports basic read/write operations
|
457
|
+
- TTL (time-to-live) support for automatic cleanup
|
458
|
+
|
459
|
+
#### **Background Jobs**
|
460
|
+
- ActiveJob backend configured (Sidekiq, Resque, DelayedJob, etc.)
|
461
|
+
- Job queues operational and monitored
|
462
|
+
- Retry mechanisms available for failed jobs
|
463
|
+
|
464
|
+
#### **Container Environment**
|
465
|
+
- Container orchestration platform (Kubernetes, Docker Swarm, etc.)
|
466
|
+
- CronJob scheduling capabilities
|
467
|
+
- Resource limits and monitoring
|
468
|
+
|
469
|
+
#### **Monitoring Infrastructure**
|
470
|
+
- Prometheus server (for Prometheus export)
|
471
|
+
- Grafana or similar for visualization
|
472
|
+
- Alerting system for operational issues
|
473
|
+
|
474
|
+
### Performance Expectations
|
475
|
+
|
476
|
+
#### **In-Memory Operations**
|
477
|
+
- **Latency**: < 1ms for counter/gauge operations
|
478
|
+
- **Throughput**: > 10,000 operations/second per container
|
479
|
+
- **Memory**: ~1MB per 10,000 unique metric combinations
|
480
|
+
- **Concurrency**: Scales linearly with CPU cores
|
481
|
+
|
482
|
+
#### **Cache Synchronization**
|
483
|
+
- **Frequency**: Every 30 seconds (configurable)
|
484
|
+
- **Latency**: < 100ms for Redis, < 500ms for Memcached
|
485
|
+
- **Batch Size**: 1,000 metrics per sync operation
|
486
|
+
- **Network**: Minimal bandwidth usage with compression
|
487
|
+
|
488
|
+
#### **Export Operations**
|
489
|
+
- **Frequency**: Every 5 minutes (configurable via CronJob)
|
490
|
+
- **Duration**: < 30 seconds for 10,000 metrics
|
491
|
+
- **Resource Usage**: < 256MB memory, < 200m CPU
|
492
|
+
- **Network**: Compressed payload reduces bandwidth by 70%
|
493
|
+
|
494
|
+
## Interoperability
|
495
|
+
|
496
|
+
### Prometheus Integration
|
497
|
+
|
498
|
+
#### **Native Prometheus Format**
|
499
|
+
```ruby
|
500
|
+
# Exported metrics follow Prometheus naming conventions
|
501
|
+
tasker_task_duration_seconds_bucket{le="0.1",task_name="payment_processing"} 45
|
502
|
+
tasker_task_duration_seconds_bucket{le="0.5",task_name="payment_processing"} 123
|
503
|
+
tasker_task_duration_seconds_bucket{le="1.0",task_name="payment_processing"} 145
|
504
|
+
tasker_task_duration_seconds_count{task_name="payment_processing"} 150
|
505
|
+
tasker_task_duration_seconds_sum{task_name="payment_processing"} 87.5
|
506
|
+
|
507
|
+
tasker_step_executions_total{step_name="validate_payment",status="success"} 1247
|
508
|
+
tasker_step_executions_total{step_name="validate_payment",status="failure"} 23
|
509
|
+
```
|
510
|
+
|
511
|
+
#### **Grafana Dashboards**
|
512
|
+
```yaml
|
513
|
+
# Example Grafana dashboard queries
|
514
|
+
- name: "Task Completion Rate"
|
515
|
+
query: 'rate(tasker_task_executions_total{status="success"}[5m])'
|
516
|
+
|
517
|
+
- name: "95th Percentile Task Duration"
|
518
|
+
query: 'histogram_quantile(0.95, rate(tasker_task_duration_seconds_bucket[5m]))'
|
519
|
+
|
520
|
+
- name: "Error Rate by Task Type"
|
521
|
+
query: 'rate(tasker_task_executions_total{status="failure"}[5m]) / rate(tasker_task_executions_total[5m])'
|
522
|
+
```
|
523
|
+
|
524
|
+
### OpenTelemetry Compatibility
|
525
|
+
|
526
|
+
The native metrics system is designed to be complementary to OpenTelemetry spans from TelemetrySubscriber. For OpenTelemetry metrics integration, use the existing TelemetrySubscriber which automatically publishes to OpenTelemetry backends.
|
527
|
+
|
528
|
+
```ruby
|
529
|
+
# OpenTelemetry spans (via TelemetrySubscriber) + Native metrics (via MetricsBackend)
|
530
|
+
config.telemetry do |tel|
|
531
|
+
tel.enabled = true # Enable OpenTelemetry spans
|
532
|
+
tel.metrics_enabled = true # Enable native metrics
|
533
|
+
tel.metrics_format = 'prometheus' # Export native metrics to Prometheus
|
534
|
+
end
|
535
|
+
```
|
536
|
+
|
537
|
+
### Custom Export Formats
|
538
|
+
|
539
|
+
```ruby
|
540
|
+
# JSON export for custom integrations
|
541
|
+
{
|
542
|
+
"timestamp": "2024-01-01T12:00:00Z",
|
543
|
+
"metrics": {
|
544
|
+
"counters": {
|
545
|
+
"tasker.task.executions": {
|
546
|
+
"value": 1247,
|
547
|
+
"labels": {"status": "success", "task_name": "payment_processing"}
|
548
|
+
}
|
549
|
+
},
|
550
|
+
"gauges": {
|
551
|
+
"tasker.queue.depth": {
|
552
|
+
"value": 42,
|
553
|
+
"labels": {"queue": "default"}
|
554
|
+
}
|
555
|
+
},
|
556
|
+
"histograms": {
|
557
|
+
"tasker.task.duration": {
|
558
|
+
"count": 150,
|
559
|
+
"sum": 87.5,
|
560
|
+
"buckets": [
|
561
|
+
{"le": "0.1", "count": 45},
|
562
|
+
{"le": "0.5", "count": 123},
|
563
|
+
{"le": "1.0", "count": 145}
|
564
|
+
],
|
565
|
+
"labels": {"task_name": "payment_processing"}
|
566
|
+
}
|
567
|
+
}
|
568
|
+
}
|
569
|
+
}
|
570
|
+
```
|
571
|
+
|
572
|
+
### DataDog Integration
|
573
|
+
|
574
|
+
```ruby
|
575
|
+
# Custom subscriber for DataDog StatsD
|
576
|
+
class DataDogMetricsSubscriber < Tasker::Events::BaseSubscriber
|
577
|
+
# Subscribe to task completion events
|
578
|
+
subscribe_to Tasker::Constants::TaskEvents::COMPLETED
|
579
|
+
|
580
|
+
def handle_task_completed(event)
|
581
|
+
duration = event[:execution_duration]
|
582
|
+
task_name = event[:task_name]
|
583
|
+
|
584
|
+
StatsD.histogram('tasker.task.duration', duration,
|
585
|
+
tags: ["task:#{task_name}"])
|
586
|
+
StatsD.increment('tasker.task.completed',
|
587
|
+
tags: ["task:#{task_name}"])
|
588
|
+
end
|
589
|
+
end
|
590
|
+
```
|
591
|
+
|
592
|
+
## Production Deployment Patterns
|
593
|
+
|
594
|
+
### High-Availability Setup
|
595
|
+
|
596
|
+
```yaml
|
597
|
+
# Multiple export jobs for redundancy
|
598
|
+
apiVersion: batch/v1
|
599
|
+
kind: CronJob
|
600
|
+
metadata:
|
601
|
+
name: tasker-metrics-export-primary
|
602
|
+
spec:
|
603
|
+
schedule: "*/5 * * * *"
|
604
|
+
# ... primary export configuration
|
605
|
+
|
606
|
+
---
|
607
|
+
apiVersion: batch/v1
|
608
|
+
kind: CronJob
|
609
|
+
metadata:
|
610
|
+
name: tasker-metrics-export-backup
|
611
|
+
spec:
|
612
|
+
schedule: "2-57/5 * * * *" # Offset by 2 minutes
|
613
|
+
# ... backup export configuration with different endpoint
|
614
|
+
```
|
615
|
+
|
616
|
+
### Resource Management
|
617
|
+
|
618
|
+
```yaml
|
619
|
+
# Resource quotas for metrics jobs
|
620
|
+
apiVersion: v1
|
621
|
+
kind: ResourceQuota
|
622
|
+
metadata:
|
623
|
+
name: tasker-metrics-quota
|
624
|
+
spec:
|
625
|
+
hard:
|
626
|
+
requests.cpu: "500m"
|
627
|
+
requests.memory: "1Gi"
|
628
|
+
limits.cpu: "1000m"
|
629
|
+
limits.memory: "2Gi"
|
630
|
+
count/jobs.batch: "10"
|
631
|
+
```
|
632
|
+
|
633
|
+
### Security Considerations
|
634
|
+
|
635
|
+
```yaml
|
636
|
+
# ServiceAccount with minimal permissions
|
637
|
+
apiVersion: v1
|
638
|
+
kind: ServiceAccount
|
639
|
+
metadata:
|
640
|
+
name: tasker-metrics-exporter
|
641
|
+
|
642
|
+
---
|
643
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
644
|
+
kind: Role
|
645
|
+
metadata:
|
646
|
+
name: tasker-metrics-role
|
647
|
+
rules:
|
648
|
+
- apiGroups: [""]
|
649
|
+
resources: ["configmaps", "secrets"]
|
650
|
+
verbs: ["get", "list"]
|
651
|
+
|
652
|
+
---
|
653
|
+
apiVersion: rbac.authorization.k8s.io/v1
|
654
|
+
kind: RoleBinding
|
655
|
+
metadata:
|
656
|
+
name: tasker-metrics-binding
|
657
|
+
subjects:
|
658
|
+
- kind: ServiceAccount
|
659
|
+
name: tasker-metrics-exporter
|
660
|
+
roleRef:
|
661
|
+
kind: Role
|
662
|
+
name: tasker-metrics-role
|
663
|
+
apiGroup: rbac.authorization.k8s.io
|
664
|
+
```
|
665
|
+
|
666
|
+
## Troubleshooting
|
667
|
+
|
668
|
+
### Common Issues
|
669
|
+
|
670
|
+
#### **Cache Sync Failures**
|
671
|
+
```bash
|
672
|
+
# Check cache store connectivity
|
673
|
+
bundle exec rails runner "puts Rails.cache.read('test') || 'Cache not accessible'"
|
674
|
+
|
675
|
+
# Verify cache capabilities
|
676
|
+
bundle exec rake tasker:metrics_status
|
677
|
+
```
|
678
|
+
|
679
|
+
#### **Export Job Failures**
|
680
|
+
```bash
|
681
|
+
# Check job queue status
|
682
|
+
bundle exec rails runner "puts ActiveJob::Base.queue_adapter"
|
683
|
+
|
684
|
+
# View failed jobs
|
685
|
+
bundle exec sidekiq-cli stats # for Sidekiq
|
686
|
+
```
|
687
|
+
|
688
|
+
#### **Missing Metrics**
|
689
|
+
```bash
|
690
|
+
# Verify metrics collection
|
691
|
+
bundle exec rails runner "
|
692
|
+
backend = Tasker::Telemetry::MetricsBackend.instance
|
693
|
+
puts backend.all_metrics.size
|
694
|
+
"
|
695
|
+
|
696
|
+
# Check sync strategy
|
697
|
+
bundle exec rake tasker:metrics_status | grep 'Sync Strategy'
|
698
|
+
```
|
699
|
+
|
700
|
+
### Debugging Commands
|
701
|
+
|
702
|
+
```bash
|
703
|
+
# Export metrics immediately for testing
|
704
|
+
bundle exec rake tasker:export_metrics_now[prometheus]
|
705
|
+
|
706
|
+
# Sync metrics to cache manually
|
707
|
+
bundle exec rake tasker:sync_metrics
|
708
|
+
|
709
|
+
# Show detailed configuration
|
710
|
+
VERBOSE=true bundle exec rake tasker:metrics_status
|
711
|
+
```
|
712
|
+
|
713
|
+
### Performance Monitoring
|
714
|
+
|
715
|
+
```ruby
|
716
|
+
# Add custom monitoring to your application
|
717
|
+
class MetricsHealthCheck
|
718
|
+
def self.check
|
719
|
+
backend = Tasker::Telemetry::MetricsBackend.instance
|
720
|
+
|
721
|
+
{
|
722
|
+
metrics_count: backend.all_metrics.size,
|
723
|
+
sync_strategy: backend.sync_strategy,
|
724
|
+
last_sync: backend.last_sync_time,
|
725
|
+
cache_healthy: Rails.cache.write('health_check', Time.current)
|
726
|
+
}
|
727
|
+
end
|
728
|
+
end
|
729
|
+
```
|
730
|
+
|
731
|
+
This comprehensive metrics system provides production-ready observability while maintaining the flexibility to adapt to different infrastructure environments and scaling requirements.
|