orchestrator-core 4.2.0rc3__tar.gz → 4.3.0__tar.gz
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.
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/PKG-INFO +1 -1
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/__init__.py +1 -1
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/processes.py +1 -10
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/loaders/subscriptions.py +12 -1
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/subscription.py +4 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/types.py +10 -1
- orchestrator_core-4.3.0/orchestrator/migrations/versions/schema/2025-07-28_850dccac3b02_update_description_of_resume_workflows_.py +35 -0
- orchestrator_core-4.3.0/orchestrator/py.typed +0 -0
- {orchestrator_core-4.2.0rc3/orchestrator/services → orchestrator_core-4.3.0/orchestrator/services/executors}/celery.py +39 -51
- orchestrator_core-4.3.0/orchestrator/services/executors/threadpool.py +128 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/input_state.py +6 -3
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/processes.py +45 -53
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/subscription_relations.py +21 -1
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/tasks.py +17 -46
- orchestrator_core-4.3.0/orchestrator/workflows/tasks/__init__.py +12 -0
- orchestrator_core-4.3.0/orchestrator/workflows/tasks/resume_workflows.py +115 -0
- orchestrator_core-4.2.0rc3/orchestrator/workflows/tasks/resume_workflows.py +0 -59
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/LICENSE +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/README.md +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/api.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/health.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/product_blocks.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/products.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/resource_types.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/subscription_customer_descriptions.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/subscriptions.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/translations.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/user.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/workflows.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/api_v1/endpoints/ws.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/error_handling.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/api/models.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/app.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/database.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/domain_gen_helpers/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/domain_gen_helpers/fixed_input_helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/domain_gen_helpers/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/domain_gen_helpers/product_block_helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/domain_gen_helpers/product_helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/domain_gen_helpers/resource_type_helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/domain_gen_helpers/types.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generate.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/README +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_create_imports.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_create_input_fields.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_create_steps.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_modify_imports.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_modify_input_fields.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_modify_steps.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_terminate_imports.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_terminate_input_fields.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/custom_templates/additional_terminate_steps.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/enums.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/migration.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/product.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/product_block.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/translations.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/unittest.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/validations.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/generator/workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/products/workshop/circuit.yaml +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/products/workshop/node.yaml +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/products/workshop/user.yaml +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/products/workshop/user_group.yaml +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/additional_create_imports.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/additional_create_steps.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/additional_modify_imports.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/additional_modify_steps.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/additional_terminate_steps.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/constrained_int_definitions.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/create_data_head.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/create_product.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/enums.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/lazy_workflow_instance.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/list_definitions.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/macros.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/modify_product.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/new_product_migration.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/product.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/product_block.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/shared_forms.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/shared_workflows.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/subscription_model_registry.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/terminate_product.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/test_create_workflow.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/test_modify_workflow.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/test_product_type.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/test_terminate_workflow.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/test_validate_workflow.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/generator/templates/validate_product.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/helpers/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/helpers/input_helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/helpers/print_helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/main.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/migrate_domain_models.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/migrate_tasks.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/migrate_workflows.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/migration_helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/cli/scheduler.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/config/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/config/assignee.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/database.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/filters.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/process.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/product.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/product_block.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/resource_type.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/search_filters/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/search_filters/inferred_filter.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/subscription.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/filters/workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/listeners.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/loaders.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/models.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/queries/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/queries/subscription.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/queries/subscription_instance.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/range/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/range/range.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/process.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/product.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/product_block.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/resource_type.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/sorting.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/subscription.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/db/sorting/workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/devtools/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/devtools/populator.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/devtools/scripts/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/devtools/scripts/migrate_20.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/devtools/scripts/migrate_30.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/devtools/scripts/shared.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/distlock/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/distlock/distlock_manager.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/distlock/managers/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/distlock/managers/memory_distlock_manager.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/distlock/managers/redis_distlock_manager.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/domain/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/domain/base.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/domain/context_cache.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/domain/customer_description.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/domain/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/domain/lifecycle.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/domain/subscription_instance_transform.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/exception_handlers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/forms/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/forms/validators/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/forms/validators/customer_contact_list.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/forms/validators/customer_id.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/forms/validators/display_subscription.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/forms/validators/network_type_validators.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/forms/validators/product_id.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/autoregistration.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/extensions/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/extensions/model_cache.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/extensions/stats.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/loaders/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/mutations/customer_description.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/mutations/start_process.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/pagination.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/customer.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/process.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/product.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/product_block.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/resource_type.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/subscription.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/version.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/resolvers/workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schema.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/customer.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/customer_description.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/errors.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/fixed_input.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/process.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/product.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/product_block.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/resource_type.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/strawberry_pydantic_patch.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/version.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/create_resolver_error_handler.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/get_query_loaders.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/get_selected_fields.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/get_selected_paths.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/get_subscription_product_blocks.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/is_query_detailed.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/override_class.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/utils/to_graphql_result_page.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/log_config.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/metrics/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/metrics/engine.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/metrics/init.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/metrics/processes.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/metrics/subscriptions.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/README +0 -0
- /orchestrator_core-4.2.0rc3/orchestrator/py.typed → /orchestrator_core-4.3.0/orchestrator/migrations/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/alembic.ini +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/env.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/script.py.mako +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/templates/alembic.ini.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/templates/env.py.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/templates/helpers.py.j2 +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2020-10-19_3323bcb934e7_fix_tsv_triggers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2020-10-19_a76b9185b334_add_generic_workflows_to_core.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2020-10-19_c112305b07d3_initial_schema_migration.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2021-04-06_3c8b9185c221_add_validate_products_task.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2021-07-01_6896a54e9483_add_product_block_relations.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2021-11-17_19cdd3ab86f6_fix_parse_websearch.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2022-02-16_bed6bc0b197a_rename_parent_and_child_block_relations.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-03-06_e05bb1967eff_add_subscriptions_search_view.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-05-25_b1970225392d_add_subscription_metadata_workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-06-28_a09ac125ea73_add_throttling_to_refresh_subscriptions.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-06-28_a09ac125ea73_add_throttling_to_refresh_subscriptions.sql +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-07-17_165303a20fb1_customer_id_to_varchar.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-07-17_165303a20fb1_customer_id_to_varchar.sql +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-09-25_da5c9f4cce1c_add_subscription_metadata_to_fulltext_.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-09-25_da5c9f4cce1c_add_subscription_metadata_to_fulltext_.sql +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2023-12-06_048219045729_add_workflow_id_to_processes_table.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2024-09-27_460ec6748e37_add_uuid_search_workaround.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2024-09-27_460ec6748e37_add_uuid_search_workaround.sql +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-01-08_4c5859620539_add_version_column_to_subscription.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-01-19_4fjdn13f83ga_add_validate_product_type_task.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-02-12_bac6be6f2b4f_added_input_state_table.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-02-20_68d14db1b8da_make_workflow_description_mandatory.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-03-06_42b3d076a85b_subscription_instance_as_json_function.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-03-06_42b3d076a85b_subscription_instance_as_json_function.sql +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-04-09_fc5c993a4b4a_add_cascade_constraint_on_processes_.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-05-08_161918133bec_add_is_task_to_workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-07-01_93fc5834c7e5_changed_timestamping_fields_in_process_steps.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/migrations/versions/schema/2025-07-04_4b58e336d1bf_deprecating_workflow_target_in_.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schedules/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schedules/resume_workflows.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schedules/scheduling.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schedules/task_vacuum.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schedules/validate_products.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schedules/validate_subscriptions.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/base.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/engine_settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/fixed_input.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/problem_detail.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/process.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/product.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/product_block.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/resource_type.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/subscription.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/subscription_descriptions.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/schemas/workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/security.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3/orchestrator/utils → orchestrator_core-4.3.0/orchestrator/services/executors}/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/fixed_inputs.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/process_broadcast_thread.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/products.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/resource_types.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/settings_env_variables.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/subscriptions.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/translations.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/services/workflows.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/targets.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/types.py +0 -0
- {orchestrator_core-4.2.0rc3/orchestrator/workflows/tasks → orchestrator_core-4.3.0/orchestrator/utils}/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/auth.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/crypt.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/datetime.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/deprecation_logger.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/docs.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/enrich_process.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/errors.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/expose_settings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/fixed_inputs.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/functional.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/get_subscription_dict.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/get_updated_properties.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/helpers.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/json.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/redis.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/redis_client.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/search_query.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/state.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/strings.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/utils/validate_data_version.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/version.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/websocket/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/websocket/managers/broadcast_websocket_manager.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/websocket/managers/memory_websocket_manager.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/websocket/websocket_manager.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/__init__.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/modify_note.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/removed_workflow.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/steps.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/tasks/cleanup_tasks_log.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/tasks/validate_product_type.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/tasks/validate_products.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/translations/en-GB.json +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/workflows/utils.py +0 -0
- {orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/pyproject.toml +0 -0
|
@@ -48,6 +48,7 @@ from orchestrator.services.processes import (
|
|
|
48
48
|
_async_resume_processes,
|
|
49
49
|
_get_process,
|
|
50
50
|
abort_process,
|
|
51
|
+
can_be_resumed,
|
|
51
52
|
continue_awaiting_process,
|
|
52
53
|
load_process,
|
|
53
54
|
resume_process,
|
|
@@ -120,16 +121,6 @@ def get_auth_callbacks(steps: StepList, workflow: Workflow) -> tuple[Authorizer
|
|
|
120
121
|
return auth_resume, auth_retry
|
|
121
122
|
|
|
122
123
|
|
|
123
|
-
def can_be_resumed(status: ProcessStatus) -> bool:
|
|
124
|
-
return status in (
|
|
125
|
-
ProcessStatus.SUSPENDED, # Can be resumed
|
|
126
|
-
ProcessStatus.WAITING, # Can be retried
|
|
127
|
-
ProcessStatus.FAILED, # Can be retried
|
|
128
|
-
ProcessStatus.API_UNAVAILABLE, # subtype of FAILED
|
|
129
|
-
ProcessStatus.INCONSISTENT_DATA, # subtype of FAILED
|
|
130
|
-
)
|
|
131
|
-
|
|
132
|
-
|
|
133
124
|
def resolve_user_name(
|
|
134
125
|
*,
|
|
135
126
|
reporter: Reporter | None,
|
{orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/loaders/subscriptions.py
RENAMED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
from datetime import datetime
|
|
1
2
|
from typing import Literal
|
|
2
3
|
from uuid import UUID
|
|
3
4
|
|
|
@@ -8,7 +9,11 @@ from strawberry.dataloader import DataLoader
|
|
|
8
9
|
from orchestrator.db import (
|
|
9
10
|
SubscriptionTable,
|
|
10
11
|
)
|
|
11
|
-
from orchestrator.services.subscription_relations import
|
|
12
|
+
from orchestrator.services.subscription_relations import (
|
|
13
|
+
get_depends_on_subscriptions,
|
|
14
|
+
get_in_use_by_subscriptions,
|
|
15
|
+
get_last_validation_datetimes,
|
|
16
|
+
)
|
|
12
17
|
from orchestrator.types import SubscriptionLifecycle
|
|
13
18
|
|
|
14
19
|
logger = structlog.get_logger(__name__)
|
|
@@ -38,4 +43,10 @@ async def depends_on_subs_loader(keys: list[tuple[UUID, tuple[str, ...]]]) -> li
|
|
|
38
43
|
return await get_depends_on_subscriptions(subscription_ids, filter_statuses)
|
|
39
44
|
|
|
40
45
|
|
|
46
|
+
async def last_validation_datetime_loader(keys: list[UUID]) -> list[datetime | None]:
|
|
47
|
+
"""GraphQL dataloader to efficiently get the last validation datetime for multiple subscription_ids."""
|
|
48
|
+
return await get_last_validation_datetimes(keys)
|
|
49
|
+
|
|
50
|
+
|
|
41
51
|
SubsLoaderType = DataLoader[tuple[UUID, tuple[str, ...]], list[SubscriptionTable]]
|
|
52
|
+
LastValidationLoaderType = DataLoader[UUID, datetime | None]
|
{orchestrator_core-4.2.0rc3 → orchestrator_core-4.3.0}/orchestrator/graphql/schemas/subscription.py
RENAMED
|
@@ -175,6 +175,10 @@ class SubscriptionInterface:
|
|
|
175
175
|
]
|
|
176
176
|
return await resolve_subscriptions(info, filter_by_with_related_subscriptions, sort_by, first, after)
|
|
177
177
|
|
|
178
|
+
@strawberry.field(description="Returns the date and time of the last validation workflow run for a subscription") # type: ignore
|
|
179
|
+
async def last_validated_at(self, info: OrchestratorInfo) -> datetime | None:
|
|
180
|
+
return await info.context.core_last_validation_datetime_loader.load(self.subscription_id)
|
|
181
|
+
|
|
178
182
|
@strawberry.field(description="Returns customer of a subscription") # type: ignore
|
|
179
183
|
def customer(self) -> CustomerType:
|
|
180
184
|
return CustomerType(
|
|
@@ -30,7 +30,13 @@ from oauth2_lib.fastapi import AuthManager
|
|
|
30
30
|
from oauth2_lib.strawberry import OauthContext
|
|
31
31
|
from orchestrator.db.filters import Filter
|
|
32
32
|
from orchestrator.db.sorting import Sort, SortOrder
|
|
33
|
-
from orchestrator.graphql.loaders.subscriptions import
|
|
33
|
+
from orchestrator.graphql.loaders.subscriptions import (
|
|
34
|
+
LastValidationLoaderType,
|
|
35
|
+
SubsLoaderType,
|
|
36
|
+
depends_on_subs_loader,
|
|
37
|
+
in_use_by_subs_loader,
|
|
38
|
+
last_validation_datetime_loader,
|
|
39
|
+
)
|
|
34
40
|
from orchestrator.services.process_broadcast_thread import ProcessDataBroadcastThread
|
|
35
41
|
|
|
36
42
|
StrawberryPydanticModel = TypeVar("StrawberryPydanticModel", bound=StrawberryTypeFromPydantic)
|
|
@@ -60,6 +66,9 @@ class OrchestratorContext(OauthContext):
|
|
|
60
66
|
self.graphql_models = graphql_models or {}
|
|
61
67
|
self.core_in_use_by_subs_loader: SubsLoaderType = DataLoader(load_fn=in_use_by_subs_loader)
|
|
62
68
|
self.core_depends_on_subs_loader: SubsLoaderType = DataLoader(load_fn=depends_on_subs_loader)
|
|
69
|
+
self.core_last_validation_datetime_loader: LastValidationLoaderType = DataLoader(
|
|
70
|
+
load_fn=last_validation_datetime_loader
|
|
71
|
+
)
|
|
63
72
|
super().__init__(auth_manager)
|
|
64
73
|
|
|
65
74
|
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"""Update description of resume workflows task.
|
|
2
|
+
|
|
3
|
+
Revision ID: 850dccac3b02
|
|
4
|
+
Revises: 93fc5834c7e5
|
|
5
|
+
Create Date: 2025-07-28 15:38:57.211087
|
|
6
|
+
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
from alembic import op
|
|
10
|
+
|
|
11
|
+
# revision identifiers, used by Alembic.
|
|
12
|
+
revision = "850dccac3b02"
|
|
13
|
+
down_revision = "93fc5834c7e5"
|
|
14
|
+
branch_labels = None
|
|
15
|
+
depends_on = None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def upgrade() -> None:
|
|
19
|
+
op.execute(
|
|
20
|
+
"""
|
|
21
|
+
UPDATE workflows
|
|
22
|
+
SET description = 'Resume all workflows that are stuck on tasks with the status ''waiting'', ''created'' or ''resumed'''
|
|
23
|
+
WHERE name = 'task_resume_workflows';
|
|
24
|
+
"""
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def downgrade() -> None:
|
|
29
|
+
op.execute(
|
|
30
|
+
"""
|
|
31
|
+
UPDATE workflows
|
|
32
|
+
SET description = 'Resume all workflows that are stuck on tasks with the status ''waiting'''
|
|
33
|
+
WHERE name = 'task_resume_workflows';
|
|
34
|
+
"""
|
|
35
|
+
)
|
|
File without changes
|
|
@@ -18,19 +18,22 @@ from uuid import UUID
|
|
|
18
18
|
import structlog
|
|
19
19
|
from celery.result import AsyncResult
|
|
20
20
|
from kombu.exceptions import ConnectionError, OperationalError
|
|
21
|
+
from sqlalchemy import select
|
|
21
22
|
|
|
22
|
-
from oauth2_lib.fastapi import OIDCUserModel
|
|
23
23
|
from orchestrator import app_settings
|
|
24
24
|
from orchestrator.api.error_handling import raise_status
|
|
25
25
|
from orchestrator.db import ProcessTable, db
|
|
26
|
-
from orchestrator.services.
|
|
27
|
-
|
|
26
|
+
from orchestrator.services.processes import (
|
|
27
|
+
SYSTEM_USER,
|
|
28
|
+
can_be_resumed,
|
|
29
|
+
create_process,
|
|
30
|
+
delete_process,
|
|
31
|
+
set_process_status,
|
|
32
|
+
)
|
|
28
33
|
from orchestrator.services.workflows import get_workflow_by_name
|
|
29
|
-
from orchestrator.
|
|
34
|
+
from orchestrator.workflow import ProcessStat, ProcessStatus
|
|
30
35
|
from pydantic_forms.types import State
|
|
31
36
|
|
|
32
|
-
SYSTEM_USER = "SYSTEM"
|
|
33
|
-
|
|
34
37
|
logger = structlog.get_logger(__name__)
|
|
35
38
|
|
|
36
39
|
|
|
@@ -42,29 +45,17 @@ def _block_when_testing(task_result: AsyncResult) -> None:
|
|
|
42
45
|
raise RuntimeError("Celery worker has failed to resume process")
|
|
43
46
|
|
|
44
47
|
|
|
45
|
-
def _celery_start_process(
|
|
46
|
-
workflow_key: str,
|
|
47
|
-
user_inputs: list[State] | None,
|
|
48
|
-
user: str = SYSTEM_USER,
|
|
49
|
-
user_model: OIDCUserModel | None = None,
|
|
50
|
-
**kwargs: Any,
|
|
51
|
-
) -> UUID:
|
|
48
|
+
def _celery_start_process(pstat: ProcessStat, user: str = SYSTEM_USER, **kwargs: Any) -> UUID:
|
|
52
49
|
"""Client side call of Celery."""
|
|
53
50
|
from orchestrator.services.tasks import NEW_TASK, NEW_WORKFLOW, get_celery_task
|
|
54
51
|
|
|
55
|
-
|
|
56
|
-
if not workflow:
|
|
57
|
-
raise_status(HTTPStatus.NOT_FOUND, "Workflow does not exist")
|
|
58
|
-
|
|
59
|
-
wf_table = get_workflow_by_name(workflow.name)
|
|
60
|
-
if not wf_table:
|
|
52
|
+
if not (wf_table := get_workflow_by_name(pstat.workflow.name)):
|
|
61
53
|
raise_status(HTTPStatus.NOT_FOUND, "Workflow in Database does not exist")
|
|
62
54
|
|
|
63
55
|
task_name = NEW_TASK if wf_table.is_task else NEW_WORKFLOW
|
|
64
56
|
trigger_task = get_celery_task(task_name)
|
|
65
|
-
pstat = create_process(workflow_key, user_inputs=user_inputs, user=user, user_model=user_model)
|
|
66
57
|
try:
|
|
67
|
-
result = trigger_task.delay(pstat.process_id,
|
|
58
|
+
result = trigger_task.delay(pstat.process_id, user)
|
|
68
59
|
_block_when_testing(result)
|
|
69
60
|
return pstat.process_id
|
|
70
61
|
except (ConnectionError, OperationalError) as e:
|
|
@@ -77,65 +68,62 @@ def _celery_start_process(
|
|
|
77
68
|
def _celery_resume_process(
|
|
78
69
|
process: ProcessTable,
|
|
79
70
|
*,
|
|
80
|
-
user_inputs: list[State] | None = None,
|
|
81
71
|
user: str | None = None,
|
|
82
72
|
**kwargs: Any,
|
|
83
|
-
) ->
|
|
73
|
+
) -> bool:
|
|
84
74
|
"""Client side call of Celery."""
|
|
85
|
-
from orchestrator.services.processes import load_process
|
|
86
75
|
from orchestrator.services.tasks import RESUME_TASK, RESUME_WORKFLOW, get_celery_task
|
|
87
76
|
|
|
88
|
-
pstat = load_process(process)
|
|
89
77
|
last_process_status = process.last_status
|
|
90
|
-
workflow = pstat.workflow
|
|
91
|
-
|
|
92
|
-
wf_table = get_workflow_by_name(workflow.name)
|
|
93
|
-
if not workflow or not wf_table:
|
|
94
|
-
raise_status(HTTPStatus.NOT_FOUND, "Workflow does not exist")
|
|
95
78
|
|
|
96
|
-
task_name = RESUME_TASK if
|
|
79
|
+
task_name = RESUME_TASK if process.workflow.is_task else RESUME_WORKFLOW
|
|
97
80
|
trigger_task = get_celery_task(task_name)
|
|
98
81
|
|
|
99
|
-
|
|
100
|
-
|
|
82
|
+
_celery_set_process_status_resumed(process.process_id)
|
|
83
|
+
|
|
101
84
|
try:
|
|
102
|
-
|
|
103
|
-
result = trigger_task.delay(pstat.process_id, user)
|
|
85
|
+
result = trigger_task.delay(process.process_id, user)
|
|
104
86
|
_block_when_testing(result)
|
|
105
87
|
|
|
106
|
-
return
|
|
88
|
+
return process.process_id
|
|
107
89
|
except (ConnectionError, OperationalError) as e:
|
|
108
90
|
logger.warning(
|
|
109
91
|
"Connection error when submitting task to celery. Resetting process status back",
|
|
110
92
|
current_status=process.last_status,
|
|
111
93
|
last_status=last_process_status,
|
|
112
94
|
)
|
|
113
|
-
|
|
95
|
+
set_process_status(process.process_id, last_process_status)
|
|
114
96
|
raise e
|
|
115
97
|
|
|
116
98
|
|
|
117
|
-
def
|
|
118
|
-
process
|
|
119
|
-
db.session.add(process)
|
|
120
|
-
db.session.commit()
|
|
121
|
-
|
|
99
|
+
def _celery_set_process_status_resumed(process_id: UUID) -> None:
|
|
100
|
+
"""Set the process status to RESUMED to show its waiting to be picked up by a worker.
|
|
122
101
|
|
|
123
|
-
|
|
124
|
-
|
|
102
|
+
uses with_for_update to lock the subscription in a transaction, preventing other changes.
|
|
103
|
+
rolls back transation and raises an exception when it can't change to RESUMED to prevent it from being added to the queue.
|
|
125
104
|
|
|
126
105
|
Args:
|
|
127
|
-
|
|
106
|
+
process_id: Process ID to fetch process from DB
|
|
128
107
|
"""
|
|
129
|
-
|
|
130
|
-
|
|
108
|
+
stmt = select(ProcessTable).where(ProcessTable.process_id == process_id).with_for_update()
|
|
109
|
+
|
|
110
|
+
result = db.session.execute(stmt)
|
|
111
|
+
locked_process = result.scalar_one_or_none()
|
|
112
|
+
|
|
113
|
+
if not locked_process:
|
|
114
|
+
raise ValueError(f"Process not found: {process_id}")
|
|
131
115
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
116
|
+
if can_be_resumed(locked_process.last_status):
|
|
117
|
+
locked_process.last_status = ProcessStatus.RESUMED
|
|
118
|
+
db.session.commit()
|
|
119
|
+
else:
|
|
120
|
+
db.session.rollback()
|
|
121
|
+
raise ValueError(f"Process has incorrect status to resume: {locked_process.last_status}")
|
|
135
122
|
|
|
136
123
|
|
|
137
124
|
def _celery_validate(validation_workflow: str, json: list[State] | None) -> None:
|
|
138
|
-
|
|
125
|
+
pstat = create_process(validation_workflow, user_inputs=json)
|
|
126
|
+
_celery_start_process(pstat)
|
|
139
127
|
|
|
140
128
|
|
|
141
129
|
CELERY_EXECUTION_CONTEXT: dict[str, Callable] = {
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
# Copyright 2019-2025 SURF, GÉANT, ESnet.
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
from collections.abc import Callable
|
|
14
|
+
from functools import partial
|
|
15
|
+
from uuid import UUID
|
|
16
|
+
|
|
17
|
+
import structlog
|
|
18
|
+
from sqlalchemy import select
|
|
19
|
+
|
|
20
|
+
from oauth2_lib.fastapi import OIDCUserModel
|
|
21
|
+
from orchestrator.db import ProcessTable, db
|
|
22
|
+
from orchestrator.services.input_state import InputType, retrieve_input_state
|
|
23
|
+
from orchestrator.services.processes import (
|
|
24
|
+
RESUME_WORKFLOW_REMOVED_ERROR_MSG,
|
|
25
|
+
START_WORKFLOW_REMOVED_ERROR_MSG,
|
|
26
|
+
SYSTEM_USER,
|
|
27
|
+
StateMerger,
|
|
28
|
+
_run_process_async,
|
|
29
|
+
create_process,
|
|
30
|
+
load_process,
|
|
31
|
+
safe_logstep,
|
|
32
|
+
)
|
|
33
|
+
from orchestrator.types import BroadcastFunc
|
|
34
|
+
from orchestrator.workflow import (
|
|
35
|
+
ProcessStat,
|
|
36
|
+
ProcessStatus,
|
|
37
|
+
runwf,
|
|
38
|
+
)
|
|
39
|
+
from orchestrator.workflows.removed_workflow import removed_workflow
|
|
40
|
+
from pydantic_forms.types import State
|
|
41
|
+
|
|
42
|
+
logger = structlog.get_logger(__name__)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _set_process_status_running(process_id: UUID) -> None:
|
|
46
|
+
"""Set the process status to RUNNING to prevent it from being picked up by mutliple workers.
|
|
47
|
+
|
|
48
|
+
uses with_for_update to lock the subscription in a transaction, preventing other changes.
|
|
49
|
+
rolls back transation and raises an exception when its already on status RUNNING to prevent worker from running an already running process
|
|
50
|
+
|
|
51
|
+
Args:
|
|
52
|
+
process_id: Process ID to fetch process from DB
|
|
53
|
+
"""
|
|
54
|
+
stmt = select(ProcessTable).where(ProcessTable.process_id == process_id).with_for_update()
|
|
55
|
+
|
|
56
|
+
result = db.session.execute(stmt)
|
|
57
|
+
locked_process = result.scalar_one_or_none()
|
|
58
|
+
|
|
59
|
+
if not locked_process:
|
|
60
|
+
db.session.rollback()
|
|
61
|
+
raise ValueError(f"Process not found: {process_id}")
|
|
62
|
+
|
|
63
|
+
if locked_process.last_status is not ProcessStatus.RUNNING:
|
|
64
|
+
locked_process.last_status = ProcessStatus.RUNNING
|
|
65
|
+
db.session.commit()
|
|
66
|
+
else:
|
|
67
|
+
db.session.rollback()
|
|
68
|
+
raise Exception("Process is already running")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def thread_start_process(
|
|
72
|
+
pstat: ProcessStat,
|
|
73
|
+
user: str = SYSTEM_USER,
|
|
74
|
+
user_model: OIDCUserModel | None = None,
|
|
75
|
+
broadcast_func: BroadcastFunc | None = None,
|
|
76
|
+
) -> UUID:
|
|
77
|
+
if pstat.workflow == removed_workflow:
|
|
78
|
+
raise ValueError(START_WORKFLOW_REMOVED_ERROR_MSG)
|
|
79
|
+
|
|
80
|
+
# enforce an update to the process status to properly show the process
|
|
81
|
+
_set_process_status_running(pstat.process_id)
|
|
82
|
+
|
|
83
|
+
input_data = retrieve_input_state(pstat.process_id, "initial_state", False)
|
|
84
|
+
pstat.update(state=pstat.state.map(lambda state: StateMerger.merge(state, input_data.input_state)))
|
|
85
|
+
|
|
86
|
+
_safe_logstep_with_func = partial(safe_logstep, broadcast_func=broadcast_func)
|
|
87
|
+
return _run_process_async(pstat.process_id, lambda: runwf(pstat, _safe_logstep_with_func))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def thread_resume_process(
|
|
91
|
+
process: ProcessTable,
|
|
92
|
+
*,
|
|
93
|
+
user: str | None = None,
|
|
94
|
+
user_model: OIDCUserModel | None = None,
|
|
95
|
+
broadcast_func: BroadcastFunc | None = None,
|
|
96
|
+
) -> UUID:
|
|
97
|
+
# ATTENTION!! When modifying this function make sure you make similar changes to `resume_workflow` in the test code
|
|
98
|
+
pstat = load_process(process)
|
|
99
|
+
if pstat.workflow == removed_workflow:
|
|
100
|
+
raise ValueError(RESUME_WORKFLOW_REMOVED_ERROR_MSG)
|
|
101
|
+
|
|
102
|
+
if user:
|
|
103
|
+
pstat.update(current_user=user)
|
|
104
|
+
|
|
105
|
+
# retrieve_input_str is for the edge case when workflow engine stops whilst there is an existing 'CREATED' process queue'ed.
|
|
106
|
+
# It will have become a `RUNNING` process that gets resumed and this should fetch initial_state instead of user_input.
|
|
107
|
+
retrieve_input_str: InputType = "user_input" if process.steps else "initial_state"
|
|
108
|
+
input_data = retrieve_input_state(process.process_id, retrieve_input_str, False)
|
|
109
|
+
pstat.update(state=pstat.state.map(lambda state: StateMerger.merge(state, input_data.input_state)))
|
|
110
|
+
|
|
111
|
+
# enforce an update to the process status to properly show the process
|
|
112
|
+
_set_process_status_running(process.process_id)
|
|
113
|
+
|
|
114
|
+
_safe_logstep_prep = partial(safe_logstep, broadcast_func=broadcast_func)
|
|
115
|
+
_run_process_async(pstat.process_id, lambda: runwf(pstat, _safe_logstep_prep))
|
|
116
|
+
return pstat.process_id
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def thread_validate_workflow(validation_workflow: str, json: list[State] | None) -> UUID:
|
|
120
|
+
pstat = create_process(validation_workflow, user_inputs=json)
|
|
121
|
+
return thread_start_process(pstat)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
THREADPOOL_EXECUTION_CONTEXT: dict[str, Callable] = {
|
|
125
|
+
"start": thread_start_process,
|
|
126
|
+
"resume": thread_resume_process,
|
|
127
|
+
"validate": thread_validate_workflow,
|
|
128
|
+
}
|
|
@@ -24,12 +24,13 @@ logger = structlog.get_logger(__name__)
|
|
|
24
24
|
InputType = Literal["initial_state", "user_input"]
|
|
25
25
|
|
|
26
26
|
|
|
27
|
-
def retrieve_input_state(process_id: UUID, input_type: InputType) -> InputStateTable:
|
|
27
|
+
def retrieve_input_state(process_id: UUID, input_type: InputType, raise_exception: bool = True) -> InputStateTable:
|
|
28
28
|
"""Get user input.
|
|
29
29
|
|
|
30
30
|
Args:
|
|
31
31
|
process_id: Process ID
|
|
32
32
|
input_type: The type of the input.
|
|
33
|
+
raise_exception: boolean to throw error when not finding data or not
|
|
33
34
|
|
|
34
35
|
Returns:
|
|
35
36
|
User input table
|
|
@@ -40,13 +41,15 @@ def retrieve_input_state(process_id: UUID, input_type: InputType) -> InputStateT
|
|
|
40
41
|
select(InputStateTable)
|
|
41
42
|
.filter(InputStateTable.process_id == process_id)
|
|
42
43
|
.filter(InputStateTable.input_type == input_type)
|
|
43
|
-
.order_by(InputStateTable.input_time.
|
|
44
|
+
.order_by(InputStateTable.input_time.desc())
|
|
44
45
|
).first()
|
|
45
46
|
|
|
46
47
|
if res:
|
|
47
48
|
logger.debug("Retrieved input state", process_id=process_id, input_state=res, input_type=input_type)
|
|
48
49
|
return res
|
|
49
|
-
|
|
50
|
+
if raise_exception:
|
|
51
|
+
raise ValueError(f"No input state for pid: {process_id}")
|
|
52
|
+
return InputStateTable(input_state={})
|
|
50
53
|
|
|
51
54
|
|
|
52
55
|
def store_input_state(
|
|
@@ -51,7 +51,6 @@ from orchestrator.workflow import (
|
|
|
51
51
|
Success,
|
|
52
52
|
Workflow,
|
|
53
53
|
abort_wf,
|
|
54
|
-
runwf,
|
|
55
54
|
)
|
|
56
55
|
from orchestrator.workflow import Process as WFProcess
|
|
57
56
|
from orchestrator.workflows import get_workflow
|
|
@@ -68,13 +67,18 @@ SYSTEM_USER = "SYSTEM"
|
|
|
68
67
|
|
|
69
68
|
_workflow_executor = None
|
|
70
69
|
|
|
70
|
+
START_WORKFLOW_REMOVED_ERROR_MSG = "This workflow cannot be started because it has been removed"
|
|
71
|
+
RESUME_WORKFLOW_REMOVED_ERROR_MSG = "This workflow cannot be resumed because it has been removed"
|
|
72
|
+
|
|
71
73
|
|
|
72
74
|
def get_execution_context() -> dict[str, Callable]:
|
|
73
75
|
if app_settings.EXECUTOR == ExecutorType.WORKER:
|
|
74
|
-
from orchestrator.services.celery import CELERY_EXECUTION_CONTEXT
|
|
76
|
+
from orchestrator.services.executors.celery import CELERY_EXECUTION_CONTEXT
|
|
75
77
|
|
|
76
78
|
return CELERY_EXECUTION_CONTEXT
|
|
77
79
|
|
|
80
|
+
from orchestrator.services.executors.threadpool import THREADPOOL_EXECUTION_CONTEXT
|
|
81
|
+
|
|
78
82
|
return THREADPOOL_EXECUTION_CONTEXT
|
|
79
83
|
|
|
80
84
|
|
|
@@ -449,7 +453,6 @@ def create_process(
|
|
|
449
453
|
}
|
|
450
454
|
|
|
451
455
|
try:
|
|
452
|
-
|
|
453
456
|
state = post_form(workflow.initial_input_form, initial_state, user_inputs)
|
|
454
457
|
except FormValidationError:
|
|
455
458
|
logger.exception("Validation errors", user_inputs=user_inputs)
|
|
@@ -469,19 +472,6 @@ def create_process(
|
|
|
469
472
|
return pstat
|
|
470
473
|
|
|
471
474
|
|
|
472
|
-
def thread_start_process(
|
|
473
|
-
workflow_key: str,
|
|
474
|
-
user_inputs: list[State] | None = None,
|
|
475
|
-
user: str = SYSTEM_USER,
|
|
476
|
-
user_model: OIDCUserModel | None = None,
|
|
477
|
-
broadcast_func: BroadcastFunc | None = None,
|
|
478
|
-
) -> UUID:
|
|
479
|
-
pstat = create_process(workflow_key, user_inputs=user_inputs, user=user, user_model=user_model)
|
|
480
|
-
|
|
481
|
-
_safe_logstep_with_func = partial(safe_logstep, broadcast_func=broadcast_func)
|
|
482
|
-
return _run_process_async(pstat.process_id, lambda: runwf(pstat, _safe_logstep_with_func))
|
|
483
|
-
|
|
484
|
-
|
|
485
475
|
def start_process(
|
|
486
476
|
workflow_key: str,
|
|
487
477
|
user_inputs: list[State] | None = None,
|
|
@@ -502,57 +492,47 @@ def start_process(
|
|
|
502
492
|
process id
|
|
503
493
|
|
|
504
494
|
"""
|
|
495
|
+
pstat = create_process(workflow_key, user_inputs=user_inputs, user=user)
|
|
496
|
+
|
|
505
497
|
start_func = get_execution_context()["start"]
|
|
506
|
-
return start_func(
|
|
507
|
-
workflow_key, user_inputs=user_inputs, user=user, user_model=user_model, broadcast_func=broadcast_func
|
|
508
|
-
)
|
|
498
|
+
return start_func(pstat, user=user, user_model=user_model, broadcast_func=broadcast_func)
|
|
509
499
|
|
|
510
500
|
|
|
511
|
-
def
|
|
501
|
+
def restart_process(
|
|
512
502
|
process: ProcessTable,
|
|
513
503
|
*,
|
|
514
|
-
user_inputs: list[State] | None = None,
|
|
515
504
|
user: str | None = None,
|
|
516
505
|
broadcast_func: BroadcastFunc | None = None,
|
|
517
506
|
) -> UUID:
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
if user_inputs is None:
|
|
521
|
-
user_inputs = [{}]
|
|
522
|
-
|
|
523
|
-
pstat = load_process(process)
|
|
524
|
-
|
|
525
|
-
if pstat.workflow == removed_workflow:
|
|
526
|
-
raise ValueError("This workflow cannot be resumed")
|
|
507
|
+
"""Restart a process that is stuck on status CREATED.
|
|
527
508
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
509
|
+
Args:
|
|
510
|
+
process: Process from database
|
|
511
|
+
user: user who resumed this process
|
|
512
|
+
broadcast_func: Optional function to broadcast process data
|
|
531
513
|
|
|
532
|
-
|
|
533
|
-
|
|
514
|
+
Returns:
|
|
515
|
+
process id
|
|
534
516
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
store_input_state(pstat.process_id, user_input, "user_input")
|
|
538
|
-
# enforce an update to the process status to properly show the process
|
|
539
|
-
process.last_status = ProcessStatus.RUNNING
|
|
540
|
-
db.session.add(process)
|
|
541
|
-
db.session.commit()
|
|
517
|
+
"""
|
|
518
|
+
pstat = load_process(process)
|
|
542
519
|
|
|
543
|
-
|
|
544
|
-
return
|
|
520
|
+
start_func = get_execution_context()["start"]
|
|
521
|
+
return start_func(pstat, user=user, broadcast_func=broadcast_func)
|
|
545
522
|
|
|
546
523
|
|
|
547
|
-
|
|
548
|
-
|
|
524
|
+
RESUMABLE_STATUSES = (
|
|
525
|
+
ProcessStatus.SUSPENDED, # Can be resumed
|
|
526
|
+
ProcessStatus.WAITING, # Can be retried
|
|
527
|
+
ProcessStatus.FAILED, # Can be retried
|
|
528
|
+
ProcessStatus.API_UNAVAILABLE, # subtype of FAILED
|
|
529
|
+
ProcessStatus.INCONSISTENT_DATA, # subtype of FAILED
|
|
530
|
+
ProcessStatus.RESUMED, # re-resume stuck process
|
|
531
|
+
)
|
|
549
532
|
|
|
550
533
|
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
"resume": thread_resume_process,
|
|
554
|
-
"validate": thread_validate_workflow,
|
|
555
|
-
}
|
|
534
|
+
def can_be_resumed(status: ProcessStatus) -> bool:
|
|
535
|
+
return status in RESUMABLE_STATUSES
|
|
556
536
|
|
|
557
537
|
|
|
558
538
|
def resume_process(
|
|
@@ -576,14 +556,19 @@ def resume_process(
|
|
|
576
556
|
"""
|
|
577
557
|
pstat = load_process(process)
|
|
578
558
|
|
|
559
|
+
if pstat.workflow == removed_workflow:
|
|
560
|
+
raise ValueError(RESUME_WORKFLOW_REMOVED_ERROR_MSG)
|
|
561
|
+
|
|
579
562
|
try:
|
|
580
|
-
post_form(pstat.log[0].form, pstat.state.unwrap(), user_inputs=user_inputs or [])
|
|
563
|
+
user_input = post_form(pstat.log[0].form, pstat.state.unwrap(), user_inputs=user_inputs or [{}])
|
|
581
564
|
except FormValidationError:
|
|
582
565
|
logger.exception("Validation errors", user_inputs=user_inputs)
|
|
583
566
|
raise
|
|
584
567
|
|
|
568
|
+
store_input_state(pstat.process_id, user_input, "user_input")
|
|
569
|
+
|
|
585
570
|
resume_func = get_execution_context()["resume"]
|
|
586
|
-
return resume_func(process,
|
|
571
|
+
return resume_func(process, user=user, broadcast_func=broadcast_func)
|
|
587
572
|
|
|
588
573
|
|
|
589
574
|
def ensure_correct_callback_token(pstat: ProcessStat, *, token: str) -> None:
|
|
@@ -809,6 +794,12 @@ def _get_running_processes() -> list[ProcessTable]:
|
|
|
809
794
|
return list(db.session.scalars(stmt))
|
|
810
795
|
|
|
811
796
|
|
|
797
|
+
def set_process_status(process: ProcessTable, status: ProcessStatus) -> None:
|
|
798
|
+
process.last_status = status
|
|
799
|
+
db.session.add(process)
|
|
800
|
+
db.session.commit()
|
|
801
|
+
|
|
802
|
+
|
|
812
803
|
def marshall_processes(engine_settings: EngineSettingsTable, new_global_lock: bool) -> EngineSettingsTable | None:
|
|
813
804
|
"""Manage processes depending on the engine status.
|
|
814
805
|
|
|
@@ -831,6 +822,7 @@ def marshall_processes(engine_settings: EngineSettingsTable, new_global_lock: bo
|
|
|
831
822
|
|
|
832
823
|
# Resume all the running processes
|
|
833
824
|
for process in _get_running_processes():
|
|
825
|
+
set_process_status(process, ProcessStatus.RESUMED)
|
|
834
826
|
resume_process(process, user=SYSTEM_USER)
|
|
835
827
|
|
|
836
828
|
elif not engine_settings.global_lock and new_global_lock:
|