GeneralManager 0.45.0__tar.gz → 0.46.1__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.
- {generalmanager-0.45.0/src/GeneralManager.egg-info → generalmanager-0.46.1}/PKG-INFO +1 -1
- {generalmanager-0.45.0 → generalmanager-0.46.1}/pyproject.toml +1 -1
- {generalmanager-0.45.0 → generalmanager-0.46.1/src/GeneralManager.egg-info}/PKG-INFO +1 -1
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/SOURCES.txt +2 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/cache_decorator.py +97 -22
- generalmanager-0.46.1/src/general_manager/cache/dependency_cache.py +154 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/dependency_index.py +224 -92
- generalmanager-0.46.1/src/general_manager/cache/dependency_publish.py +155 -0
- generalmanager-0.46.1/src/general_manager/cache/signals.py +114 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/testing.py +23 -4
- generalmanager-0.45.0/src/general_manager/cache/signals.py +0 -85
- {generalmanager-0.45.0 → generalmanager-0.46.1}/LICENSE +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/README.md +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/setup.cfg +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/requires.txt +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/api.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/bucket.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/cache.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/factory.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/general_manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/interface.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/measurement.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/permission.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/rule.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/search.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/utils.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_errors.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_mutations.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_resolvers.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_search.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_subscriptions.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_view.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/mutation.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/property.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/registry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/remote_api.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/remote_invalidation.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/remote_invalidation_client.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/apps.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bootstrap.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/base_bucket.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/calculation_bucket.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/database_bucket.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/group_bucket.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/request_bucket.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/cache_tracker.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/run_context.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/conf.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/auto_factory.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/factories.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/factory_methods.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/base_interface.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/calculation.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/database.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/remote_manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/request.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/base.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/builtin.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/configuration.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/core/observability.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/core/utils.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/exceptions.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/factory.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/history.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/support.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/registry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/calculation.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/database.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/existing_model.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/read_only.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/request.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_builder.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_models.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/orm_interface.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/requests.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/errors.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/models.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/logging.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/search_index.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/shell.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/general_manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/group_manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/input.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/meta.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/measurement/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/measurement/measurement.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/measurement/measurement_field.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/metrics/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/metrics/graphql.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/0001_initial.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/models.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/audit.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/base_permission.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/graphql_capabilities.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/manager_based_permission.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/mutation_permission.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/permission_checks.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/permission_data_manager.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/utils.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/public_api_registry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/py.typed +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/rule/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/rule/handler.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/rule/rule.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/async_tasks.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backend.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backend_registry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/dev.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/meilisearch.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/opensearch.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/typesense.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/config.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/indexer.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/registry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/utils.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/seeding/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/seeding/manager_landscape.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/args_to_kwargs.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/filter_parser.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/format_string.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/json_encoder.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/make_cache_key.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/none_to_zero.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/path_mapping.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/public_api.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/type_checks.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/actions.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backend_registry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/__init__.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/celery.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/local.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/n8n.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/config.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/engine.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/event_registry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/events.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/models.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/signal_bridge.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/tasks.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/telemetry.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/tests/test_settings.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/tests/test_urls.py +0 -0
- {generalmanager-0.45.0 → generalmanager-0.46.1}/tests/testing_asgi.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.46.1
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "GeneralManager"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.46.1"
|
|
8
8
|
description = "Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
authors = [{ name = "Tim Kleindick", email = "tkleindick@yahoo.de" }]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: GeneralManager
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.46.1
|
|
4
4
|
Summary: Modular Django-based data management framework with ORM, GraphQL, fine-grained permissions, rule validation, calculations and caching.
|
|
5
5
|
Author-email: Tim Kleindick <tkleindick@yahoo.de>
|
|
6
6
|
License: MIT License
|
|
@@ -51,7 +51,9 @@ src/general_manager/bucket/request_bucket.py
|
|
|
51
51
|
src/general_manager/cache/__init__.py
|
|
52
52
|
src/general_manager/cache/cache_decorator.py
|
|
53
53
|
src/general_manager/cache/cache_tracker.py
|
|
54
|
+
src/general_manager/cache/dependency_cache.py
|
|
54
55
|
src/general_manager/cache/dependency_index.py
|
|
56
|
+
src/general_manager/cache/dependency_publish.py
|
|
55
57
|
src/general_manager/cache/model_dependency_collector.py
|
|
56
58
|
src/general_manager/cache/run_context.py
|
|
57
59
|
src/general_manager/cache/signals.py
|
{generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/cache_decorator.py
RENAMED
|
@@ -1,12 +1,38 @@
|
|
|
1
1
|
"""Helpers for caching GeneralManager computations with dependency tracking."""
|
|
2
2
|
|
|
3
3
|
from functools import wraps
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import (
|
|
5
|
+
Any,
|
|
6
|
+
Callable,
|
|
7
|
+
Iterable,
|
|
8
|
+
Literal,
|
|
9
|
+
Optional,
|
|
10
|
+
Protocol,
|
|
11
|
+
Set,
|
|
12
|
+
TypeVar,
|
|
13
|
+
cast,
|
|
14
|
+
)
|
|
5
15
|
|
|
6
16
|
from django.core.cache import cache as django_cache
|
|
7
17
|
|
|
8
18
|
from general_manager.cache.cache_tracker import DependencyTracker
|
|
9
|
-
from general_manager.cache.
|
|
19
|
+
from general_manager.cache.dependency_cache import (
|
|
20
|
+
DependencyCacheHit,
|
|
21
|
+
read_dependency_cache_hit,
|
|
22
|
+
replay_dependency_cache_hit,
|
|
23
|
+
)
|
|
24
|
+
from general_manager.cache.dependency_index import (
|
|
25
|
+
Dependency,
|
|
26
|
+
get_dependency_generation,
|
|
27
|
+
record_dependencies,
|
|
28
|
+
)
|
|
29
|
+
from general_manager.cache.dependency_publish import (
|
|
30
|
+
CachePublishAborted,
|
|
31
|
+
acquire_compute_lease,
|
|
32
|
+
publish_dependency_cache_entry,
|
|
33
|
+
release_compute_lease,
|
|
34
|
+
wait_for_cached_dependency_hit,
|
|
35
|
+
)
|
|
10
36
|
from general_manager.cache.run_context import ensure_calculation_run_context
|
|
11
37
|
from general_manager.cache.model_dependency_collector import ModelDependencyCollector
|
|
12
38
|
from general_manager.logging import get_logger
|
|
@@ -158,34 +184,83 @@ def cached(
|
|
|
158
184
|
)
|
|
159
185
|
return result
|
|
160
186
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
cached_result = cache_backend.get(key, _SENTINEL)
|
|
164
|
-
if cached_result is not _SENTINEL:
|
|
165
|
-
# saved dependencies are added to the current tracker
|
|
166
|
-
cached_deps = cache_backend.get(deps_key)
|
|
167
|
-
if cached_deps:
|
|
168
|
-
for class_name, operation, identifier in cached_deps:
|
|
169
|
-
DependencyTracker.track(class_name, operation, identifier)
|
|
187
|
+
def return_cached_hit(hit: DependencyCacheHit, message: str) -> object:
|
|
188
|
+
replay_dependency_cache_hit(hit)
|
|
170
189
|
logger.debug(
|
|
171
|
-
|
|
190
|
+
message,
|
|
172
191
|
context={
|
|
173
192
|
"function": func.__qualname__,
|
|
174
193
|
"key": key,
|
|
175
|
-
"
|
|
194
|
+
"scope": scope,
|
|
176
195
|
},
|
|
177
196
|
)
|
|
178
|
-
return
|
|
197
|
+
return hit.value
|
|
179
198
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
199
|
+
cached_hit = read_dependency_cache_hit(
|
|
200
|
+
cache_backend,
|
|
201
|
+
key,
|
|
202
|
+
sentinel=_SENTINEL,
|
|
203
|
+
)
|
|
204
|
+
if cached_hit is not _SENTINEL:
|
|
205
|
+
return return_cached_hit(cached_hit, "cache hit")
|
|
206
|
+
|
|
207
|
+
lease = acquire_compute_lease(key)
|
|
208
|
+
while lease is None:
|
|
209
|
+
cached_hit = wait_for_cached_dependency_hit(
|
|
210
|
+
cache_backend,
|
|
211
|
+
key,
|
|
212
|
+
sentinel=_SENTINEL,
|
|
213
|
+
)
|
|
214
|
+
if cached_hit is not _SENTINEL:
|
|
215
|
+
return return_cached_hit(
|
|
216
|
+
cached_hit,
|
|
217
|
+
"cache hit after waiting for dependency publish",
|
|
218
|
+
)
|
|
219
|
+
lease = acquire_compute_lease(key)
|
|
186
220
|
|
|
187
|
-
|
|
188
|
-
|
|
221
|
+
try:
|
|
222
|
+
cached_hit = read_dependency_cache_hit(
|
|
223
|
+
cache_backend,
|
|
224
|
+
key,
|
|
225
|
+
sentinel=_SENTINEL,
|
|
226
|
+
)
|
|
227
|
+
if cached_hit is not _SENTINEL:
|
|
228
|
+
return return_cached_hit(cached_hit, "cache hit")
|
|
229
|
+
|
|
230
|
+
started_generation = get_dependency_generation()
|
|
231
|
+
with DependencyTracker() as dependencies:
|
|
232
|
+
result = func(*args, **kwargs)
|
|
233
|
+
ModelDependencyCollector.add_args(dependencies, args, kwargs)
|
|
234
|
+
|
|
235
|
+
def record_many(
|
|
236
|
+
entries: Iterable[tuple[str, Iterable[Dependency]]],
|
|
237
|
+
) -> None:
|
|
238
|
+
for entry_key, entry_dependencies in entries:
|
|
239
|
+
record_fn(entry_key, set(entry_dependencies))
|
|
240
|
+
|
|
241
|
+
try:
|
|
242
|
+
publish_dependency_cache_entry(
|
|
243
|
+
cache_key=key,
|
|
244
|
+
result=result,
|
|
245
|
+
dependencies=dependencies,
|
|
246
|
+
cache_backend=cache_backend,
|
|
247
|
+
timeout=timeout,
|
|
248
|
+
started_generation=started_generation,
|
|
249
|
+
record_many_fn=(
|
|
250
|
+
None if record_fn is record_dependencies else record_many
|
|
251
|
+
),
|
|
252
|
+
)
|
|
253
|
+
except CachePublishAborted:
|
|
254
|
+
logger.debug(
|
|
255
|
+
"dependency cache publish aborted",
|
|
256
|
+
context={
|
|
257
|
+
"function": func.__qualname__,
|
|
258
|
+
"key": key,
|
|
259
|
+
"scope": scope,
|
|
260
|
+
},
|
|
261
|
+
)
|
|
262
|
+
finally:
|
|
263
|
+
release_compute_lease(lease)
|
|
189
264
|
|
|
190
265
|
logger.debug(
|
|
191
266
|
"cache miss recorded",
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""Internal helpers for dependency-scoped cache entry reads."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass
|
|
6
|
+
from typing import Any, Iterable, Mapping, Protocol, TypeGuard
|
|
7
|
+
|
|
8
|
+
from general_manager.cache.cache_tracker import DependencyTracker
|
|
9
|
+
from general_manager.cache.dependency_index import Dependency
|
|
10
|
+
|
|
11
|
+
DEPENDENCY_CACHE_ENTRY_VERSION = 1
|
|
12
|
+
_MISSING = object()
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
@dataclass(frozen=True, slots=True)
|
|
16
|
+
class DependencyCacheEntry:
|
|
17
|
+
"""Persisted dependency-cache payload stored at the main cache key."""
|
|
18
|
+
|
|
19
|
+
version: int
|
|
20
|
+
value: Any
|
|
21
|
+
dependencies: frozenset[Dependency]
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@dataclass(frozen=True, slots=True)
|
|
25
|
+
class DependencyCacheHit:
|
|
26
|
+
"""In-memory representation of a dependency-cache hit."""
|
|
27
|
+
|
|
28
|
+
value: Any
|
|
29
|
+
dependencies: frozenset[Dependency]
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class DependencyCacheBackend(Protocol):
|
|
33
|
+
def get(self, key: str, default: Any = None) -> Any:
|
|
34
|
+
"""Return a cached value or *default* when absent."""
|
|
35
|
+
...
|
|
36
|
+
|
|
37
|
+
def set(self, key: str, value: Any, timeout: int | None = None) -> None:
|
|
38
|
+
"""Store a cached value."""
|
|
39
|
+
...
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class DependencyCacheGetManyBackend(DependencyCacheBackend, Protocol):
|
|
43
|
+
def get_many(self, keys: Iterable[str]) -> Mapping[str, Any]:
|
|
44
|
+
"""Return cached values for all found keys."""
|
|
45
|
+
...
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def make_dependency_cache_entry(
|
|
49
|
+
value: Any,
|
|
50
|
+
dependencies: Iterable[Dependency],
|
|
51
|
+
) -> DependencyCacheEntry:
|
|
52
|
+
"""Build the current persisted dependency-cache payload."""
|
|
53
|
+
return DependencyCacheEntry(
|
|
54
|
+
version=DEPENDENCY_CACHE_ENTRY_VERSION,
|
|
55
|
+
value=value,
|
|
56
|
+
dependencies=frozenset(dependencies),
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def read_dependency_cache_hit(
|
|
61
|
+
cache_backend: DependencyCacheBackend,
|
|
62
|
+
cache_key: str,
|
|
63
|
+
*,
|
|
64
|
+
sentinel: Any = _MISSING,
|
|
65
|
+
) -> DependencyCacheHit | Any:
|
|
66
|
+
"""Read one dependency-cache entry, including legacy split entries."""
|
|
67
|
+
payload = cache_backend.get(cache_key, sentinel)
|
|
68
|
+
if payload is sentinel:
|
|
69
|
+
return sentinel
|
|
70
|
+
combined_hit = _combined_payload_to_hit(payload)
|
|
71
|
+
if combined_hit is _MISSING:
|
|
72
|
+
return sentinel
|
|
73
|
+
if combined_hit is not None:
|
|
74
|
+
return combined_hit
|
|
75
|
+
dependency_payload = cache_backend.get(_legacy_deps_key(cache_key), ())
|
|
76
|
+
return DependencyCacheHit(
|
|
77
|
+
value=payload,
|
|
78
|
+
dependencies=frozenset(dependency_payload or ()),
|
|
79
|
+
)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def read_many_dependency_cache_hits(
|
|
83
|
+
cache_backend: DependencyCacheBackend,
|
|
84
|
+
cache_keys: Iterable[str],
|
|
85
|
+
) -> dict[str, DependencyCacheHit]:
|
|
86
|
+
"""Bulk-read dependency-cache hits for known keys."""
|
|
87
|
+
keys = tuple(dict.fromkeys(cache_keys))
|
|
88
|
+
if not keys:
|
|
89
|
+
return {}
|
|
90
|
+
if not _supports_get_many(cache_backend):
|
|
91
|
+
return _read_many_without_get_many(cache_backend, keys)
|
|
92
|
+
|
|
93
|
+
payloads = cache_backend.get_many(keys)
|
|
94
|
+
hits: dict[str, DependencyCacheHit] = {}
|
|
95
|
+
legacy_keys: list[str] = []
|
|
96
|
+
for key in keys:
|
|
97
|
+
if key not in payloads:
|
|
98
|
+
continue
|
|
99
|
+
combined_hit = _combined_payload_to_hit(payloads[key])
|
|
100
|
+
if combined_hit is _MISSING:
|
|
101
|
+
continue
|
|
102
|
+
if isinstance(combined_hit, DependencyCacheHit):
|
|
103
|
+
hits[key] = combined_hit
|
|
104
|
+
continue
|
|
105
|
+
legacy_keys.append(key)
|
|
106
|
+
|
|
107
|
+
if legacy_keys:
|
|
108
|
+
deps_keys = {_legacy_deps_key(key): key for key in legacy_keys}
|
|
109
|
+
legacy_deps = cache_backend.get_many(deps_keys.keys())
|
|
110
|
+
for deps_key, key in deps_keys.items():
|
|
111
|
+
hits[key] = DependencyCacheHit(
|
|
112
|
+
value=payloads[key],
|
|
113
|
+
dependencies=frozenset(legacy_deps.get(deps_key, ()) or ()),
|
|
114
|
+
)
|
|
115
|
+
return hits
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def replay_dependency_cache_hit(hit: DependencyCacheHit) -> None:
|
|
119
|
+
"""Replay cached dependencies into active dependency tracking scopes."""
|
|
120
|
+
for class_name, operation, identifier in hit.dependencies:
|
|
121
|
+
DependencyTracker.track(class_name, operation, identifier)
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _legacy_deps_key(cache_key: str) -> str:
|
|
125
|
+
return f"{cache_key}:deps"
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _combined_payload_to_hit(payload: Any) -> DependencyCacheHit | None | object:
|
|
129
|
+
if not isinstance(payload, DependencyCacheEntry):
|
|
130
|
+
return None
|
|
131
|
+
if payload.version != DEPENDENCY_CACHE_ENTRY_VERSION:
|
|
132
|
+
return _MISSING
|
|
133
|
+
return DependencyCacheHit(
|
|
134
|
+
value=payload.value,
|
|
135
|
+
dependencies=payload.dependencies,
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def _supports_get_many(
|
|
140
|
+
cache_backend: DependencyCacheBackend,
|
|
141
|
+
) -> TypeGuard[DependencyCacheGetManyBackend]:
|
|
142
|
+
return callable(getattr(cache_backend, "get_many", None))
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
def _read_many_without_get_many(
|
|
146
|
+
cache_backend: DependencyCacheBackend,
|
|
147
|
+
cache_keys: tuple[str, ...],
|
|
148
|
+
) -> dict[str, DependencyCacheHit]:
|
|
149
|
+
hits: dict[str, DependencyCacheHit] = {}
|
|
150
|
+
for key in cache_keys:
|
|
151
|
+
hit = read_dependency_cache_hit(cache_backend, key, sentinel=_MISSING)
|
|
152
|
+
if hit is not _MISSING:
|
|
153
|
+
hits[key] = hit
|
|
154
|
+
return hits
|