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.
Files changed (199) hide show
  1. {generalmanager-0.45.0/src/GeneralManager.egg-info → generalmanager-0.46.1}/PKG-INFO +1 -1
  2. {generalmanager-0.45.0 → generalmanager-0.46.1}/pyproject.toml +1 -1
  3. {generalmanager-0.45.0 → generalmanager-0.46.1/src/GeneralManager.egg-info}/PKG-INFO +1 -1
  4. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/SOURCES.txt +2 -0
  5. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/cache_decorator.py +97 -22
  6. generalmanager-0.46.1/src/general_manager/cache/dependency_cache.py +154 -0
  7. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/dependency_index.py +224 -92
  8. generalmanager-0.46.1/src/general_manager/cache/dependency_publish.py +155 -0
  9. generalmanager-0.46.1/src/general_manager/cache/signals.py +114 -0
  10. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/testing.py +23 -4
  11. generalmanager-0.45.0/src/general_manager/cache/signals.py +0 -85
  12. {generalmanager-0.45.0 → generalmanager-0.46.1}/LICENSE +0 -0
  13. {generalmanager-0.45.0 → generalmanager-0.46.1}/README.md +0 -0
  14. {generalmanager-0.45.0 → generalmanager-0.46.1}/setup.cfg +0 -0
  15. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  16. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/requires.txt +0 -0
  17. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
  18. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/__init__.py +0 -0
  19. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/__init__.py +0 -0
  20. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/api.py +0 -0
  21. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/bucket.py +0 -0
  22. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/cache.py +0 -0
  23. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/factory.py +0 -0
  24. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/general_manager.py +0 -0
  25. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/interface.py +0 -0
  26. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/manager.py +0 -0
  27. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/measurement.py +0 -0
  28. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/permission.py +0 -0
  29. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/rule.py +0 -0
  30. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/search.py +0 -0
  31. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/_types/utils.py +0 -0
  32. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/__init__.py +0 -0
  33. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql.py +0 -0
  34. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_errors.py +0 -0
  35. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_mutations.py +0 -0
  36. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_resolvers.py +0 -0
  37. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_search.py +0 -0
  38. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
  39. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_subscriptions.py +0 -0
  40. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_view.py +0 -0
  41. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/mutation.py +0 -0
  42. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/property.py +0 -0
  43. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/registry.py +0 -0
  44. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/remote_api.py +0 -0
  45. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/remote_invalidation.py +0 -0
  46. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/api/remote_invalidation_client.py +0 -0
  47. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/apps.py +0 -0
  48. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bootstrap.py +0 -0
  49. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/__init__.py +0 -0
  50. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/base_bucket.py +0 -0
  51. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/calculation_bucket.py +0 -0
  52. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/database_bucket.py +0 -0
  53. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/group_bucket.py +0 -0
  54. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/bucket/request_bucket.py +0 -0
  55. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/__init__.py +0 -0
  56. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/cache_tracker.py +0 -0
  57. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
  58. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/cache/run_context.py +0 -0
  59. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/conf.py +0 -0
  60. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/__init__.py +0 -0
  61. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/auto_factory.py +0 -0
  62. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/factories.py +0 -0
  63. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/factory/factory_methods.py +0 -0
  64. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/__init__.py +0 -0
  65. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/base_interface.py +0 -0
  66. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/__init__.py +0 -0
  67. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/calculation.py +0 -0
  68. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/database.py +0 -0
  69. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/remote_manager.py +0 -0
  70. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/request.py +0 -0
  71. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/__init__.py +0 -0
  72. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/base.py +0 -0
  73. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/builtin.py +0 -0
  74. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
  75. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
  76. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
  77. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/configuration.py +0 -0
  78. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/core/observability.py +0 -0
  79. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/core/utils.py +0 -0
  80. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/exceptions.py +0 -0
  81. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
  82. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
  83. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
  84. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/factory.py +0 -0
  85. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
  86. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
  87. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/history.py +0 -0
  88. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
  89. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
  90. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/support.py +0 -0
  91. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
  92. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
  93. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
  94. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
  95. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
  96. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
  97. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
  98. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
  99. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/registry.py +0 -0
  100. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
  101. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
  102. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/__init__.py +0 -0
  103. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
  104. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
  105. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/__init__.py +0 -0
  106. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/calculation.py +0 -0
  107. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/database.py +0 -0
  108. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/existing_model.py +0 -0
  109. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/read_only.py +0 -0
  110. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
  111. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/request.py +0 -0
  112. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/__init__.py +0 -0
  113. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_builder.py +0 -0
  114. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
  115. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_models.py +0 -0
  116. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/orm_interface.py +0 -0
  117. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/requests.py +0 -0
  118. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/__init__.py +0 -0
  119. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
  120. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/errors.py +0 -0
  121. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/models.py +0 -0
  122. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/logging.py +0 -0
  123. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/search_index.py +0 -0
  124. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
  125. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/shell.py +0 -0
  126. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
  127. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
  128. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/__init__.py +0 -0
  129. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/general_manager.py +0 -0
  130. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/group_manager.py +0 -0
  131. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/input.py +0 -0
  132. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/manager/meta.py +0 -0
  133. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/measurement/__init__.py +0 -0
  134. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/measurement/measurement.py +0 -0
  135. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/measurement/measurement_field.py +0 -0
  136. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/metrics/__init__.py +0 -0
  137. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/metrics/graphql.py +0 -0
  138. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/0001_initial.py +0 -0
  139. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
  140. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
  141. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/migrations/__init__.py +0 -0
  142. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/models.py +0 -0
  143. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/__init__.py +0 -0
  144. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/audit.py +0 -0
  145. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/base_permission.py +0 -0
  146. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/graphql_capabilities.py +0 -0
  147. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/manager_based_permission.py +0 -0
  148. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/mutation_permission.py +0 -0
  149. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/permission_checks.py +0 -0
  150. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/permission_data_manager.py +0 -0
  151. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/permission/utils.py +0 -0
  152. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/public_api_registry.py +0 -0
  153. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/py.typed +0 -0
  154. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/rule/__init__.py +0 -0
  155. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/rule/handler.py +0 -0
  156. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/rule/rule.py +0 -0
  157. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/__init__.py +0 -0
  158. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/async_tasks.py +0 -0
  159. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backend.py +0 -0
  160. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backend_registry.py +0 -0
  161. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/__init__.py +0 -0
  162. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/dev.py +0 -0
  163. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/meilisearch.py +0 -0
  164. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/opensearch.py +0 -0
  165. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/backends/typesense.py +0 -0
  166. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/config.py +0 -0
  167. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/indexer.py +0 -0
  168. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/registry.py +0 -0
  169. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/search/utils.py +0 -0
  170. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/seeding/__init__.py +0 -0
  171. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/seeding/manager_landscape.py +0 -0
  172. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/__init__.py +0 -0
  173. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/args_to_kwargs.py +0 -0
  174. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/filter_parser.py +0 -0
  175. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/format_string.py +0 -0
  176. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/json_encoder.py +0 -0
  177. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/make_cache_key.py +0 -0
  178. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/none_to_zero.py +0 -0
  179. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/path_mapping.py +0 -0
  180. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/public_api.py +0 -0
  181. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/utils/type_checks.py +0 -0
  182. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/__init__.py +0 -0
  183. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/actions.py +0 -0
  184. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backend_registry.py +0 -0
  185. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/__init__.py +0 -0
  186. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/celery.py +0 -0
  187. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/local.py +0 -0
  188. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/n8n.py +0 -0
  189. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/config.py +0 -0
  190. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/engine.py +0 -0
  191. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/event_registry.py +0 -0
  192. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/events.py +0 -0
  193. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/models.py +0 -0
  194. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/signal_bridge.py +0 -0
  195. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/tasks.py +0 -0
  196. {generalmanager-0.45.0 → generalmanager-0.46.1}/src/general_manager/workflow/telemetry.py +0 -0
  197. {generalmanager-0.45.0 → generalmanager-0.46.1}/tests/test_settings.py +0 -0
  198. {generalmanager-0.45.0 → generalmanager-0.46.1}/tests/test_urls.py +0 -0
  199. {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.45.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.45.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.45.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
@@ -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 Any, Callable, Literal, Optional, Protocol, Set, TypeVar, cast
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.dependency_index import Dependency, record_dependencies
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
- deps_key = f"{key}:deps"
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
- "cache hit",
190
+ message,
172
191
  context={
173
192
  "function": func.__qualname__,
174
193
  "key": key,
175
- "dependency_count": len(cached_deps) if cached_deps else 0,
194
+ "scope": scope,
176
195
  },
177
196
  )
178
- return cached_result
197
+ return hit.value
179
198
 
180
- with DependencyTracker() as dependencies:
181
- result = func(*args, **kwargs)
182
- ModelDependencyCollector.add_args(dependencies, args, kwargs)
183
-
184
- cache_backend.set(key, result, timeout)
185
- cache_backend.set(deps_key, dependencies, timeout)
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
- if dependencies and timeout is None:
188
- record_fn(key, dependencies)
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