GeneralManager 0.46.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 (198) hide show
  1. {generalmanager-0.46.0/src/GeneralManager.egg-info → generalmanager-0.46.1}/PKG-INFO +1 -1
  2. {generalmanager-0.46.0 → generalmanager-0.46.1}/pyproject.toml +1 -1
  3. {generalmanager-0.46.0 → generalmanager-0.46.1/src/GeneralManager.egg-info}/PKG-INFO +1 -1
  4. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/SOURCES.txt +1 -0
  5. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/cache_decorator.py +29 -29
  6. generalmanager-0.46.1/src/general_manager/cache/dependency_cache.py +154 -0
  7. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/dependency_publish.py +25 -23
  8. {generalmanager-0.46.0 → generalmanager-0.46.1}/LICENSE +0 -0
  9. {generalmanager-0.46.0 → generalmanager-0.46.1}/README.md +0 -0
  10. {generalmanager-0.46.0 → generalmanager-0.46.1}/setup.cfg +0 -0
  11. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  12. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/requires.txt +0 -0
  13. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/GeneralManager.egg-info/top_level.txt +0 -0
  14. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/__init__.py +0 -0
  15. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/__init__.py +0 -0
  16. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/api.py +0 -0
  17. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/bucket.py +0 -0
  18. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/cache.py +0 -0
  19. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/factory.py +0 -0
  20. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/general_manager.py +0 -0
  21. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/interface.py +0 -0
  22. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/manager.py +0 -0
  23. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/measurement.py +0 -0
  24. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/permission.py +0 -0
  25. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/rule.py +0 -0
  26. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/search.py +0 -0
  27. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/_types/utils.py +0 -0
  28. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/__init__.py +0 -0
  29. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql.py +0 -0
  30. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_errors.py +0 -0
  31. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_mutations.py +0 -0
  32. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_resolvers.py +0 -0
  33. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_search.py +0 -0
  34. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
  35. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_subscriptions.py +0 -0
  36. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/graphql_view.py +0 -0
  37. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/mutation.py +0 -0
  38. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/property.py +0 -0
  39. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/registry.py +0 -0
  40. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/remote_api.py +0 -0
  41. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/remote_invalidation.py +0 -0
  42. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/api/remote_invalidation_client.py +0 -0
  43. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/apps.py +0 -0
  44. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/bootstrap.py +0 -0
  45. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/bucket/__init__.py +0 -0
  46. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/bucket/base_bucket.py +0 -0
  47. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/bucket/calculation_bucket.py +0 -0
  48. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/bucket/database_bucket.py +0 -0
  49. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/bucket/group_bucket.py +0 -0
  50. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/bucket/request_bucket.py +0 -0
  51. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/__init__.py +0 -0
  52. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/cache_tracker.py +0 -0
  53. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/dependency_index.py +0 -0
  54. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/model_dependency_collector.py +0 -0
  55. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/run_context.py +0 -0
  56. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/cache/signals.py +0 -0
  57. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/conf.py +0 -0
  58. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/factory/__init__.py +0 -0
  59. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/factory/auto_factory.py +0 -0
  60. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/factory/factories.py +0 -0
  61. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/factory/factory_methods.py +0 -0
  62. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/__init__.py +0 -0
  63. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/base_interface.py +0 -0
  64. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/__init__.py +0 -0
  65. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/calculation.py +0 -0
  66. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/database.py +0 -0
  67. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/remote_manager.py +0 -0
  68. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/bundles/request.py +0 -0
  69. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/__init__.py +0 -0
  70. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/base.py +0 -0
  71. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/builtin.py +0 -0
  72. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
  73. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
  74. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
  75. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/configuration.py +0 -0
  76. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/core/observability.py +0 -0
  77. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/core/utils.py +0 -0
  78. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/exceptions.py +0 -0
  79. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
  80. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
  81. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
  82. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/factory.py +0 -0
  83. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
  84. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
  85. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/history.py +0 -0
  86. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
  87. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
  88. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm/support.py +0 -0
  89. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
  90. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
  91. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
  92. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
  93. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
  94. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
  95. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
  96. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
  97. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/registry.py +0 -0
  98. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
  99. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
  100. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/__init__.py +0 -0
  101. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
  102. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
  103. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/__init__.py +0 -0
  104. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/calculation.py +0 -0
  105. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/database.py +0 -0
  106. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/existing_model.py +0 -0
  107. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/read_only.py +0 -0
  108. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
  109. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/interfaces/request.py +0 -0
  110. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/__init__.py +0 -0
  111. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_builder.py +0 -0
  112. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
  113. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/manifests/capability_models.py +0 -0
  114. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/orm_interface.py +0 -0
  115. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/requests.py +0 -0
  116. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/__init__.py +0 -0
  117. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
  118. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/errors.py +0 -0
  119. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/interface/utils/models.py +0 -0
  120. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/logging.py +0 -0
  121. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/management/commands/search_index.py +0 -0
  122. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
  123. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/management/commands/shell.py +0 -0
  124. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
  125. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
  126. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/manager/__init__.py +0 -0
  127. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/manager/general_manager.py +0 -0
  128. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/manager/group_manager.py +0 -0
  129. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/manager/input.py +0 -0
  130. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/manager/meta.py +0 -0
  131. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/measurement/__init__.py +0 -0
  132. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/measurement/measurement.py +0 -0
  133. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/measurement/measurement_field.py +0 -0
  134. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/metrics/__init__.py +0 -0
  135. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/metrics/graphql.py +0 -0
  136. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/migrations/0001_initial.py +0 -0
  137. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
  138. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
  139. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/migrations/__init__.py +0 -0
  140. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/models.py +0 -0
  141. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/__init__.py +0 -0
  142. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/audit.py +0 -0
  143. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/base_permission.py +0 -0
  144. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/graphql_capabilities.py +0 -0
  145. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/manager_based_permission.py +0 -0
  146. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/mutation_permission.py +0 -0
  147. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/permission_checks.py +0 -0
  148. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/permission_data_manager.py +0 -0
  149. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/permission/utils.py +0 -0
  150. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/public_api_registry.py +0 -0
  151. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/py.typed +0 -0
  152. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/rule/__init__.py +0 -0
  153. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/rule/handler.py +0 -0
  154. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/rule/rule.py +0 -0
  155. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/__init__.py +0 -0
  156. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/async_tasks.py +0 -0
  157. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/backend.py +0 -0
  158. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/backend_registry.py +0 -0
  159. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/backends/__init__.py +0 -0
  160. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/backends/dev.py +0 -0
  161. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/backends/meilisearch.py +0 -0
  162. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/backends/opensearch.py +0 -0
  163. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/backends/typesense.py +0 -0
  164. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/config.py +0 -0
  165. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/indexer.py +0 -0
  166. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/registry.py +0 -0
  167. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/search/utils.py +0 -0
  168. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/seeding/__init__.py +0 -0
  169. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/seeding/manager_landscape.py +0 -0
  170. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/__init__.py +0 -0
  171. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/args_to_kwargs.py +0 -0
  172. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/filter_parser.py +0 -0
  173. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/format_string.py +0 -0
  174. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/json_encoder.py +0 -0
  175. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/make_cache_key.py +0 -0
  176. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/none_to_zero.py +0 -0
  177. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/path_mapping.py +0 -0
  178. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/public_api.py +0 -0
  179. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/testing.py +0 -0
  180. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/utils/type_checks.py +0 -0
  181. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/__init__.py +0 -0
  182. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/actions.py +0 -0
  183. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/backend_registry.py +0 -0
  184. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/__init__.py +0 -0
  185. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/celery.py +0 -0
  186. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/local.py +0 -0
  187. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/backends/n8n.py +0 -0
  188. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/config.py +0 -0
  189. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/engine.py +0 -0
  190. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/event_registry.py +0 -0
  191. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/events.py +0 -0
  192. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/models.py +0 -0
  193. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/signal_bridge.py +0 -0
  194. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/tasks.py +0 -0
  195. {generalmanager-0.46.0 → generalmanager-0.46.1}/src/general_manager/workflow/telemetry.py +0 -0
  196. {generalmanager-0.46.0 → generalmanager-0.46.1}/tests/test_settings.py +0 -0
  197. {generalmanager-0.46.0 → generalmanager-0.46.1}/tests/test_urls.py +0 -0
  198. {generalmanager-0.46.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.46.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.46.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.46.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,6 +51,7 @@ 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
55
56
  src/general_manager/cache/dependency_publish.py
56
57
  src/general_manager/cache/model_dependency_collector.py
@@ -16,6 +16,11 @@ from typing import (
16
16
  from django.core.cache import cache as django_cache
17
17
 
18
18
  from general_manager.cache.cache_tracker import DependencyTracker
19
+ from general_manager.cache.dependency_cache import (
20
+ DependencyCacheHit,
21
+ read_dependency_cache_hit,
22
+ replay_dependency_cache_hit,
23
+ )
19
24
  from general_manager.cache.dependency_index import (
20
25
  Dependency,
21
26
  get_dependency_generation,
@@ -26,7 +31,7 @@ from general_manager.cache.dependency_publish import (
26
31
  acquire_compute_lease,
27
32
  publish_dependency_cache_entry,
28
33
  release_compute_lease,
29
- wait_for_cached_dependency_value,
34
+ wait_for_cached_dependency_hit,
30
35
  )
31
36
  from general_manager.cache.run_context import ensure_calculation_run_context
32
37
  from general_manager.cache.model_dependency_collector import ModelDependencyCollector
@@ -179,52 +184,48 @@ def cached(
179
184
  )
180
185
  return result
181
186
 
182
- deps_key = f"{key}:deps"
183
-
184
- def track_cached_dependencies() -> None:
185
- cached_deps = cache_backend.get(deps_key)
186
- if cached_deps:
187
- for class_name, operation, identifier in cached_deps:
188
- DependencyTracker.track(class_name, operation, identifier)
189
-
190
- cached_result = cache_backend.get(key, _SENTINEL)
191
- if cached_result is not _SENTINEL:
192
- track_cached_dependencies()
187
+ def return_cached_hit(hit: DependencyCacheHit, message: str) -> object:
188
+ replay_dependency_cache_hit(hit)
193
189
  logger.debug(
194
- "cache hit",
190
+ message,
195
191
  context={
196
192
  "function": func.__qualname__,
197
193
  "key": key,
198
194
  "scope": scope,
199
195
  },
200
196
  )
201
- return cached_result
197
+ return hit.value
198
+
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")
202
206
 
203
207
  lease = acquire_compute_lease(key)
204
208
  while lease is None:
205
- cached_result = wait_for_cached_dependency_value(
209
+ cached_hit = wait_for_cached_dependency_hit(
206
210
  cache_backend,
207
211
  key,
208
212
  sentinel=_SENTINEL,
209
213
  )
210
- if cached_result is not _SENTINEL:
211
- track_cached_dependencies()
212
- logger.debug(
214
+ if cached_hit is not _SENTINEL:
215
+ return return_cached_hit(
216
+ cached_hit,
213
217
  "cache hit after waiting for dependency publish",
214
- context={
215
- "function": func.__qualname__,
216
- "key": key,
217
- "scope": scope,
218
- },
219
218
  )
220
- return cached_result
221
219
  lease = acquire_compute_lease(key)
222
220
 
223
221
  try:
224
- cached_result = cache_backend.get(key, _SENTINEL)
225
- if cached_result is not _SENTINEL:
226
- track_cached_dependencies()
227
- return cached_result
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")
228
229
 
229
230
  started_generation = get_dependency_generation()
230
231
  with DependencyTracker() as dependencies:
@@ -240,7 +241,6 @@ def cached(
240
241
  try:
241
242
  publish_dependency_cache_entry(
242
243
  cache_key=key,
243
- deps_key=deps_key,
244
244
  result=result,
245
245
  dependencies=dependencies,
246
246
  cache_backend=cache_backend,
@@ -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
@@ -5,10 +5,15 @@ from __future__ import annotations
5
5
  import time
6
6
  import uuid
7
7
  from dataclasses import dataclass
8
- from typing import Any, Callable, Iterable, Protocol
8
+ from typing import Any, Callable, Iterable
9
9
 
10
10
  from django.core.cache import cache as coordination_cache
11
11
 
12
+ from general_manager.cache.dependency_cache import (
13
+ DependencyCacheBackend,
14
+ make_dependency_cache_entry,
15
+ read_dependency_cache_hit,
16
+ )
12
17
  from general_manager.cache.dependency_index import (
13
18
  LOCK_TIMEOUT,
14
19
  Dependency,
@@ -34,14 +39,6 @@ class CacheComputeLease:
34
39
  token: str
35
40
 
36
41
 
37
- class DependencyCacheBackend(Protocol):
38
- def get(self, key: str, default: Any = None) -> Any:
39
- raise NotImplementedError
40
-
41
- def set(self, key: str, value: Any, timeout: int | None = None) -> None:
42
- raise NotImplementedError
43
-
44
-
45
42
  RecordManyDependenciesFn = Callable[[Iterable[tuple[str, Iterable[Dependency]]]], None]
46
43
 
47
44
  COMPUTE_LOCK_PREFIX = "dependency_cache_compute_lock"
@@ -72,26 +69,32 @@ def release_compute_lease(lease: CacheComputeLease) -> None:
72
69
  """Release a compute lease without risking deletion of a newer owner.
73
70
 
74
71
  Django's cache API does not provide an atomic compare-and-delete operation.
75
- Leaving the lease to expire avoids a check-then-delete race where an expired
76
- lease could delete another worker's freshly acquired token.
72
+ Checking the owner token first keeps normal recomputes fast while avoiding
73
+ deletion when the lease has already been replaced by another worker.
77
74
  """
78
- return None
75
+ if coordination_cache.get(lease.key) != lease.token:
76
+ return
77
+ coordination_cache.delete(lease.key)
79
78
 
80
79
 
81
- def wait_for_cached_dependency_value(
80
+ def wait_for_cached_dependency_hit(
82
81
  cache_backend: DependencyCacheBackend,
83
82
  cache_key: str,
84
83
  timeout_seconds: float = LOCK_TIMEOUT,
85
84
  sentinel: Any = _WAIT_MISS,
86
85
  ) -> Any:
87
- """Poll for a cached dependency value until it appears or the wait expires."""
86
+ """Poll for a dependency-cache hit until it appears or the wait expires."""
88
87
  deadline = time.monotonic() + timeout_seconds
89
88
  delay = WAIT_INITIAL_DELAY
90
89
 
91
90
  while True:
92
- cached_value = cache_backend.get(cache_key, sentinel)
93
- if cached_value is not sentinel:
94
- return cached_value
91
+ cached_hit = read_dependency_cache_hit(
92
+ cache_backend,
93
+ cache_key,
94
+ sentinel=sentinel,
95
+ )
96
+ if cached_hit is not sentinel:
97
+ return cached_hit
95
98
 
96
99
  remaining = deadline - time.monotonic()
97
100
  if remaining <= 0:
@@ -111,7 +114,6 @@ def _ensure_publish_current(started_generation: int) -> None:
111
114
  def publish_dependency_cache_entry(
112
115
  *,
113
116
  cache_key: str,
114
- deps_key: str,
115
117
  result: Any,
116
118
  dependencies: Iterable[Dependency],
117
119
  cache_backend: DependencyCacheBackend,
@@ -142,12 +144,12 @@ def publish_dependency_cache_entry(
142
144
  if dependency_set:
143
145
  _record_dependencies_locked(idx, cache_key, dependency_set)
144
146
  _ensure_publish_current(started_generation)
145
- cache_backend.set(deps_key, dependency_set, timeout)
146
147
  set_full_index(idx)
147
- cache_backend.set(cache_key, result, timeout)
148
- return
149
148
 
150
- cache_backend.set(deps_key, dependency_set, timeout)
151
- cache_backend.set(cache_key, result, timeout)
149
+ cache_backend.set(
150
+ cache_key,
151
+ make_dependency_cache_entry(result, dependency_set),
152
+ timeout,
153
+ )
152
154
  finally:
153
155
  release_lock()
File without changes