GeneralManager 0.69.0__tar.gz → 0.69.2__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 (298) hide show
  1. {generalmanager-0.69.0/src/GeneralManager.egg-info → generalmanager-0.69.2}/PKG-INFO +1 -1
  2. {generalmanager-0.69.0 → generalmanager-0.69.2}/pyproject.toml +1 -1
  3. {generalmanager-0.69.0 → generalmanager-0.69.2/src/GeneralManager.egg-info}/PKG-INFO +1 -1
  4. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/run_context.py +169 -8
  5. generalmanager-0.69.2/src/general_manager/cache/run_context_lru.py +1389 -0
  6. generalmanager-0.69.0/src/general_manager/cache/run_context_lru.py +0 -460
  7. {generalmanager-0.69.0 → generalmanager-0.69.2}/LICENSE +0 -0
  8. {generalmanager-0.69.0 → generalmanager-0.69.2}/README.md +0 -0
  9. {generalmanager-0.69.0 → generalmanager-0.69.2}/setup.cfg +0 -0
  10. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/GeneralManager.egg-info/SOURCES.txt +0 -0
  11. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/GeneralManager.egg-info/dependency_links.txt +0 -0
  12. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/GeneralManager.egg-info/requires.txt +0 -0
  13. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/GeneralManager.egg-info/top_level.txt +0 -0
  14. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/__init__.py +0 -0
  15. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/__init__.py +0 -0
  16. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/api.py +0 -0
  17. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/bucket.py +0 -0
  18. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/cache.py +0 -0
  19. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/dataframes.py +0 -0
  20. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/factory.py +0 -0
  21. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/general_manager.py +0 -0
  22. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/interface.py +0 -0
  23. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/manager.py +0 -0
  24. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/measurement.py +0 -0
  25. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/permission.py +0 -0
  26. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/rule.py +0 -0
  27. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/search.py +0 -0
  28. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/_types/utils.py +0 -0
  29. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/__init__.py +0 -0
  30. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql.py +0 -0
  31. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_as_of.py +0 -0
  32. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_errors.py +0 -0
  33. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_mutations.py +0 -0
  34. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_prefetch.py +0 -0
  35. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_relations.py +0 -0
  36. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_resolvers.py +0 -0
  37. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_search.py +0 -0
  38. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_subscription_consumer.py +0 -0
  39. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_subscriptions.py +0 -0
  40. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_view.py +0 -0
  41. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_warmup.py +0 -0
  42. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_warmup_registry.py +0 -0
  43. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/graphql_warmup_tasks.py +0 -0
  44. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/mutation.py +0 -0
  45. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/notification_batching.py +0 -0
  46. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/property.py +0 -0
  47. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/registry.py +0 -0
  48. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/remote_api.py +0 -0
  49. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/remote_invalidation.py +0 -0
  50. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/api/remote_invalidation_client.py +0 -0
  51. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/apps.py +0 -0
  52. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/as_of.py +0 -0
  53. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bootstrap.py +0 -0
  54. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bucket/__init__.py +0 -0
  55. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bucket/base_bucket.py +0 -0
  56. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bucket/calculation_bucket.py +0 -0
  57. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bucket/database_bucket.py +0 -0
  58. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bucket/group_bucket.py +0 -0
  59. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bucket/indexing.py +0 -0
  60. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/bucket/request_bucket.py +0 -0
  61. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/__init__.py +0 -0
  62. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/cache_decorator.py +0 -0
  63. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/cache_tracker.py +0 -0
  64. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/data_change_context.py +0 -0
  65. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/dependency_cache.py +0 -0
  66. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/dependency_index.py +0 -0
  67. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/dependency_matching.py +0 -0
  68. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/dependency_publish.py +0 -0
  69. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/dependency_shards.py +0 -0
  70. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/model_dependency_collector.py +0 -0
  71. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/cache/signals.py +0 -0
  72. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/__init__.py +0 -0
  73. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/audit.py +0 -0
  74. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/bootstrap.py +0 -0
  75. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/checks.py +0 -0
  76. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/consumer.py +0 -0
  77. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/errors.py +0 -0
  78. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/__init__.py +0 -0
  79. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/__main__.py +0 -0
  80. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/baseline.py +0 -0
  81. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/datasets/basic_queries.yaml +0 -0
  82. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/datasets/demo_readiness.yaml +0 -0
  83. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/datasets/edge_cases.yaml +0 -0
  84. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/datasets/follow_ups.yaml +0 -0
  85. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/datasets/large_schema.yaml +0 -0
  86. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/datasets/multi_hop.yaml +0 -0
  87. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/diagnostics.py +0 -0
  88. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/fingerprints.py +0 -0
  89. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/fixtures.py +0 -0
  90. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/judges/__init__.py +0 -0
  91. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/judges/answer_quality.py +0 -0
  92. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/judges/contract.py +0 -0
  93. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/judges/result_accuracy.py +0 -0
  94. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/judges/tool_sequence.py +0 -0
  95. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/readiness.py +0 -0
  96. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/runner.py +0 -0
  97. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/evals/traces.py +0 -0
  98. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/grounding.py +0 -0
  99. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/models.py +0 -0
  100. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/providers/__init__.py +0 -0
  101. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/providers/_shared.py +0 -0
  102. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/providers/anthropic.py +0 -0
  103. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/providers/base.py +0 -0
  104. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/providers/google.py +0 -0
  105. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/providers/ollama.py +0 -0
  106. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/providers/openai.py +0 -0
  107. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/rate_limits.py +0 -0
  108. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/routing.py +0 -0
  109. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/schema_index.py +0 -0
  110. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/settings.py +0 -0
  111. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/signals.py +0 -0
  112. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/system_prompt.py +0 -0
  113. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/tool_metadata.py +0 -0
  114. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/tools.py +0 -0
  115. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/chat/views.py +0 -0
  116. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/conf.py +0 -0
  117. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/dataframes/__init__.py +0 -0
  118. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/dataframes/measurements.py +0 -0
  119. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/factory/__init__.py +0 -0
  120. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/factory/auto_factory.py +0 -0
  121. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/factory/factories.py +0 -0
  122. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/factory/factory_methods.py +0 -0
  123. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/__init__.py +0 -0
  124. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/base_interface.py +0 -0
  125. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/bundles/__init__.py +0 -0
  126. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/bundles/calculation.py +0 -0
  127. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/bundles/database.py +0 -0
  128. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/bundles/remote_manager.py +0 -0
  129. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/bundles/request.py +0 -0
  130. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/__init__.py +0 -0
  131. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/base.py +0 -0
  132. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/builtin.py +0 -0
  133. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/calculation/__init__.py +0 -0
  134. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/calculation/_compat.py +0 -0
  135. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/calculation/lifecycle.py +0 -0
  136. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/configuration.py +0 -0
  137. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/core/observability.py +0 -0
  138. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/core/utils.py +0 -0
  139. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/exceptions.py +0 -0
  140. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/existing_model/__init__.py +0 -0
  141. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/existing_model/_compat.py +0 -0
  142. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/existing_model/resolution.py +0 -0
  143. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/factory.py +0 -0
  144. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm/__init__.py +0 -0
  145. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm/_compat.py +0 -0
  146. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm/history.py +0 -0
  147. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm/lifecycle.py +0 -0
  148. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm/mutations.py +0 -0
  149. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm/support.py +0 -0
  150. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm_utils/__init__.py +0 -0
  151. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm_utils/django_manager_utils.py +0 -0
  152. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm_utils/field_descriptors.py +0 -0
  153. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/orm_utils/payload_normalizer.py +0 -0
  154. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/read_only/__init__.py +0 -0
  155. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/read_only/_compat.py +0 -0
  156. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/read_only/_types.py +0 -0
  157. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/read_only/lifecycle.py +0 -0
  158. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/read_only/management.py +0 -0
  159. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/registry.py +0 -0
  160. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/remote_manager.py +0 -0
  161. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/capabilities/request/__init__.py +0 -0
  162. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/infrastructure/__init__.py +0 -0
  163. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/infrastructure/startup_hooks.py +0 -0
  164. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/infrastructure/system_checks.py +0 -0
  165. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/interfaces/__init__.py +0 -0
  166. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/interfaces/calculation.py +0 -0
  167. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/interfaces/database.py +0 -0
  168. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/interfaces/existing_model.py +0 -0
  169. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/interfaces/read_only.py +0 -0
  170. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/interfaces/remote_manager.py +0 -0
  171. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/interfaces/request.py +0 -0
  172. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/manifests/__init__.py +0 -0
  173. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/manifests/capability_builder.py +0 -0
  174. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/manifests/capability_manifest.py +0 -0
  175. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/manifests/capability_models.py +0 -0
  176. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/orm_interface.py +0 -0
  177. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/requests.py +0 -0
  178. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/utils/__init__.py +0 -0
  179. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/utils/database_interface_protocols.py +0 -0
  180. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/utils/errors.py +0 -0
  181. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/utils/history.py +0 -0
  182. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/interface/utils/models.py +0 -0
  183. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/logging.py +0 -0
  184. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/chat_cleanup.py +0 -0
  185. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/cleanup_upload_intents.py +0 -0
  186. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/graphql_warmup.py +0 -0
  187. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/graphql_warmup_refresh_due.py +0 -0
  188. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/search_index.py +0 -0
  189. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/search_reconcile.py +0 -0
  190. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/seed_manager_landscape.py +0 -0
  191. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/shell.py +0 -0
  192. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/workflow_drain_outbox.py +0 -0
  193. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/management/commands/workflow_replay_dead_letters.py +0 -0
  194. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/manager/__init__.py +0 -0
  195. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/manager/general_manager.py +0 -0
  196. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/manager/group_manager.py +0 -0
  197. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/manager/input.py +0 -0
  198. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/manager/meta.py +0 -0
  199. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/measurement/__init__.py +0 -0
  200. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/measurement/measurement.py +0 -0
  201. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/measurement/measurement_field.py +0 -0
  202. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/metrics/__init__.py +0 -0
  203. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/metrics/graphql.py +0 -0
  204. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0001_initial.py +0 -0
  205. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0002_workflow_outbox_scaling_indexes.py +0 -0
  206. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0003_workflow_execution_correlation_constraint.py +0 -0
  207. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0004_chat_persistence_models.py +0 -0
  208. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0004_search_index_state.py +0 -0
  209. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0005_merge_chat_search.py +0 -0
  210. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0006_chat_pending_confirmation_scoped_ids.py +0 -0
  211. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0007_upload_intent.py +0 -0
  212. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0008_upload_finalization_versions.py +0 -0
  213. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0009_upload_cleanup_state.py +0 -0
  214. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0010_chat_pending_confirmation_portable_uniqueness.py +0 -0
  215. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/0011_search_index_state_dirty_generation.py +0 -0
  216. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/migrations/__init__.py +0 -0
  217. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/models.py +0 -0
  218. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/__init__.py +0 -0
  219. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/audit.py +0 -0
  220. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/base_permission.py +0 -0
  221. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/graphql_capabilities.py +0 -0
  222. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/manager_based_permission.py +0 -0
  223. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/mutation_permission.py +0 -0
  224. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/permission_checks.py +0 -0
  225. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/permission_data_manager.py +0 -0
  226. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/permission/utils.py +0 -0
  227. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/public_api_registry.py +0 -0
  228. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/py.typed +0 -0
  229. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/rule/__init__.py +0 -0
  230. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/rule/handler.py +0 -0
  231. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/rule/rule.py +0 -0
  232. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/__init__.py +0 -0
  233. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/async_tasks.py +0 -0
  234. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/backend.py +0 -0
  235. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/backend_registry.py +0 -0
  236. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/backends/__init__.py +0 -0
  237. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/backends/dev.py +0 -0
  238. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/backends/meilisearch.py +0 -0
  239. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/backends/opensearch.py +0 -0
  240. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/backends/typesense.py +0 -0
  241. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/checks.py +0 -0
  242. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/config.py +0 -0
  243. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/indexer.py +0 -0
  244. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/invalidation.py +0 -0
  245. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/m2m_invalidation.py +0 -0
  246. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/models.py +0 -0
  247. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/reconciliation.py +0 -0
  248. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/registry.py +0 -0
  249. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/tasks.py +0 -0
  250. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/search/utils.py +0 -0
  251. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/seeding/__init__.py +0 -0
  252. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/seeding/manager_landscape.py +0 -0
  253. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/__init__.py +0 -0
  254. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/adapters.py +0 -0
  255. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/checks.py +0 -0
  256. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/config.py +0 -0
  257. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/errors.py +0 -0
  258. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/finalization.py +0 -0
  259. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/graphql.py +0 -0
  260. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/graphql_types.py +0 -0
  261. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/metrics.py +0 -0
  262. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/models.py +0 -0
  263. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/public.py +0 -0
  264. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/s3.py +0 -0
  265. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/services.py +0 -0
  266. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/tokens.py +0 -0
  267. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/types.py +0 -0
  268. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/urls.py +0 -0
  269. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/uploads/views.py +0 -0
  270. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/__init__.py +0 -0
  271. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/args_to_kwargs.py +0 -0
  272. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/filter_parser.py +0 -0
  273. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/format_string.py +0 -0
  274. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/json_encoder.py +0 -0
  275. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/make_cache_key.py +0 -0
  276. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/none_to_zero.py +0 -0
  277. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/path_mapping.py +0 -0
  278. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/public_api.py +0 -0
  279. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/testing.py +0 -0
  280. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/utils/type_checks.py +0 -0
  281. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/__init__.py +0 -0
  282. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/actions.py +0 -0
  283. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/backend_registry.py +0 -0
  284. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/backends/__init__.py +0 -0
  285. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/backends/celery.py +0 -0
  286. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/backends/local.py +0 -0
  287. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/backends/n8n.py +0 -0
  288. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/config.py +0 -0
  289. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/engine.py +0 -0
  290. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/event_registry.py +0 -0
  291. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/events.py +0 -0
  292. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/models.py +0 -0
  293. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/signal_bridge.py +0 -0
  294. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/tasks.py +0 -0
  295. {generalmanager-0.69.0 → generalmanager-0.69.2}/src/general_manager/workflow/telemetry.py +0 -0
  296. {generalmanager-0.69.0 → generalmanager-0.69.2}/tests/test_settings.py +0 -0
  297. {generalmanager-0.69.0 → generalmanager-0.69.2}/tests/test_urls.py +0 -0
  298. {generalmanager-0.69.0 → generalmanager-0.69.2}/tests/testing_asgi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: GeneralManager
3
- Version: 0.69.0
3
+ Version: 0.69.2
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.69.0"
7
+ version = "0.69.2"
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.69.0
3
+ Version: 0.69.2
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
@@ -6,6 +6,7 @@ from collections import defaultdict
6
6
  from collections.abc import Callable, Hashable, Iterable, Mapping
7
7
  from contextvars import ContextVar, Token
8
8
  from dataclasses import dataclass
9
+ from threading import RLock, get_ident
9
10
  from types import TracebackType
10
11
  from typing import TYPE_CHECKING, Optional, TypeVar, cast
11
12
 
@@ -43,8 +44,10 @@ ORM_BUCKET_EXISTS_PREFIX = "orm_bucket_exists"
43
44
  BUCKET_INDEX_PREFIX = "bucket_index"
44
45
  TRUSTED_ORM_MANAGER_PREFIX = "trusted_orm_manager"
45
46
  DEFAULT_DEPENDENCY_CACHE_PUBLISH_BATCH_SIZE = 1000
47
+ RUN_CONTEXT_TOUCH_BATCH_SIZE = 64
46
48
  logger = get_logger("cache.run_context")
47
49
  OrmModelRowKey = tuple[Hashable, Hashable | None]
50
+ PendingRunCacheTouch = tuple[RunCacheNamespace, Hashable]
48
51
 
49
52
 
50
53
  @dataclass(frozen=True)
@@ -104,9 +107,18 @@ class CalculationRunContext:
104
107
  ] = {}
105
108
  self._dependency_cache_publish_batch_size = dependency_cache_publish_batch_size
106
109
  self._tokens: list[Token[CalculationRunContext | None]] = []
110
+ self._run_cache_touch_lock = RLock()
111
+ self._pending_run_cache_touches: dict[PendingRunCacheTouch, None] = {}
112
+ self._last_pending_run_cache_touch: PendingRunCacheTouch | None = None
113
+ self._run_cache_touch_count = 0
114
+ self._run_cache_touch_thread_id: int | None = None
115
+ max_bytes = resolve_run_context_cache_max_bytes()
116
+ self._run_cache_mode_generation = -1
117
+ self._run_cache_budget_enabled = max_bytes is not None
118
+ self._run_cache_recency_enabled = False
107
119
  run_context_cache_budget.register(
108
120
  self,
109
- resolve_run_context_cache_max_bytes(),
121
+ max_bytes,
110
122
  )
111
123
 
112
124
  def _iter_run_cache_entries(
@@ -119,31 +131,54 @@ class CalculationRunContext:
119
131
  if key not in self._dependency_cache_pending_publications:
120
132
  yield "dependency_hits", key, hit
121
133
 
134
+ def _set_run_cache_modes(
135
+ self,
136
+ budget_enabled: bool,
137
+ recency_enabled: bool,
138
+ generation: int,
139
+ ) -> None:
140
+ """Refresh owner hints after a generated coordinator transition."""
141
+ with self._run_cache_touch_lock:
142
+ if generation < self._run_cache_mode_generation:
143
+ return
144
+ self._run_cache_mode_generation = generation
145
+ self._run_cache_budget_enabled = budget_enabled
146
+ self._run_cache_recency_enabled = recency_enabled
147
+ if not budget_enabled or not recency_enabled:
148
+ self._pending_run_cache_touches.clear()
149
+ self._last_pending_run_cache_touch = None
150
+ self._run_cache_touch_count = 0
151
+
122
152
  def _evict_run_cache_entry(
123
153
  self,
124
154
  namespace: RunCacheNamespace,
125
155
  key: Hashable,
126
156
  ) -> None:
127
157
  """Remove one entry selected by the process-wide coordinator."""
158
+ self._discard_run_cache_touch((namespace, key))
128
159
  if namespace == "values":
129
160
  self._values.pop(key, None)
130
161
  elif key not in self._dependency_cache_pending_publications:
131
162
  self._dependency_cache_hits.pop(cast(str, key), None)
132
163
 
133
164
  def _store_run_value(self, scoped_key: Hashable, value: object) -> None:
165
+ self._flush_run_cache_touches()
134
166
  self._values[scoped_key] = value
135
167
  run_context_cache_budget.track(self, "values", scoped_key, value)
136
168
 
137
169
  def _remove_run_value(self, scoped_key: Hashable) -> None:
170
+ self._discard_run_cache_touch(("values", scoped_key))
138
171
  if scoped_key in self._values:
139
172
  del self._values[scoped_key]
140
173
  run_context_cache_budget.remove(self, "values", scoped_key)
141
174
 
142
175
  def _refresh_run_value(self, scoped_key: Hashable) -> None:
176
+ self._discard_run_cache_touch(("values", scoped_key))
143
177
  try:
144
178
  value = self._values[scoped_key]
145
179
  except KeyError:
146
180
  return
181
+ self._flush_run_cache_touches()
147
182
  run_context_cache_budget.refresh(self, "values", scoped_key, value)
148
183
 
149
184
  def _store_dependency_cache_hit(
@@ -151,26 +186,132 @@ class CalculationRunContext:
151
186
  key: str,
152
187
  hit: DependencyCacheHit,
153
188
  ) -> None:
189
+ is_pending_publication = key in self._dependency_cache_pending_publications
190
+ if not is_pending_publication:
191
+ self._flush_run_cache_touches()
154
192
  self._dependency_cache_hits[key] = hit
155
- if key in self._dependency_cache_pending_publications:
193
+ if is_pending_publication:
194
+ self._discard_run_cache_touch(("dependency_hits", key))
156
195
  run_context_cache_budget.remove(self, "dependency_hits", key)
157
196
  else:
158
197
  run_context_cache_budget.track(self, "dependency_hits", key, hit)
159
198
 
160
199
  def _remove_dependency_cache_hit(self, key: str) -> None:
200
+ self._discard_run_cache_touch(("dependency_hits", key))
161
201
  if key in self._dependency_cache_hits:
162
202
  del self._dependency_cache_hits[key]
163
203
  run_context_cache_budget.remove(self, "dependency_hits", key)
164
204
 
165
205
  def _refresh_dependency_cache_hit(self, key: str) -> None:
206
+ self._discard_run_cache_touch(("dependency_hits", key))
166
207
  if key in self._dependency_cache_pending_publications:
167
208
  return
168
209
  try:
169
210
  hit = self._dependency_cache_hits[key]
170
211
  except KeyError:
171
212
  return
213
+ self._flush_run_cache_touches()
172
214
  run_context_cache_budget.refresh(self, "dependency_hits", key, hit)
173
215
 
216
+ def _queue_run_cache_touch(
217
+ self,
218
+ namespace: RunCacheNamespace,
219
+ key: Hashable,
220
+ ) -> None:
221
+ pending_key = (namespace, key)
222
+ with self._run_cache_touch_lock:
223
+ if (
224
+ not self._run_cache_budget_enabled
225
+ or not self._run_cache_recency_enabled
226
+ ):
227
+ return
228
+ if pending_key != self._last_pending_run_cache_touch:
229
+ self._pending_run_cache_touches.pop(pending_key, None)
230
+ self._pending_run_cache_touches[pending_key] = None
231
+ self._last_pending_run_cache_touch = pending_key
232
+ self._queue_repeated_run_cache_touch(pending_key)
233
+
234
+ def _queue_repeated_run_cache_touch(
235
+ self,
236
+ pending_key: PendingRunCacheTouch,
237
+ ) -> bool:
238
+ touch_immediately = False
239
+ touches_to_flush: tuple[PendingRunCacheTouch, ...] = ()
240
+ mode_generation = -1
241
+ with self._run_cache_touch_lock:
242
+ if (
243
+ not self._run_cache_budget_enabled
244
+ or not self._run_cache_recency_enabled
245
+ ):
246
+ return False
247
+ if self._run_cache_touch_thread_id != get_ident():
248
+ touch_immediately = True
249
+ mode_generation = self._run_cache_mode_generation
250
+ elif pending_key != self._last_pending_run_cache_touch:
251
+ return False
252
+ else:
253
+ count = self._run_cache_touch_count + 1
254
+ if count < RUN_CONTEXT_TOUCH_BATCH_SIZE:
255
+ self._run_cache_touch_count = count
256
+ return True
257
+ touches_to_flush, mode_generation = (
258
+ self._take_run_cache_touches_locked()
259
+ )
260
+ if touch_immediately:
261
+ run_context_cache_budget.touch(
262
+ self,
263
+ *pending_key,
264
+ mode_generation=mode_generation,
265
+ )
266
+ return True
267
+ run_context_cache_budget.touch_many(
268
+ self,
269
+ touches_to_flush,
270
+ mode_generation=mode_generation,
271
+ )
272
+ return True
273
+
274
+ def _touch_run_cache_entry(
275
+ self,
276
+ namespace: RunCacheNamespace,
277
+ key: Hashable,
278
+ ) -> None:
279
+ pending_key: PendingRunCacheTouch = (namespace, key)
280
+ if not self._queue_repeated_run_cache_touch(pending_key):
281
+ self._queue_run_cache_touch(namespace, key)
282
+
283
+ def _discard_run_cache_touch(self, pending_key: PendingRunCacheTouch) -> None:
284
+ with self._run_cache_touch_lock:
285
+ self._pending_run_cache_touches.pop(pending_key, None)
286
+ if pending_key == self._last_pending_run_cache_touch:
287
+ self._last_pending_run_cache_touch = next(
288
+ reversed(self._pending_run_cache_touches),
289
+ None,
290
+ )
291
+
292
+ def _take_run_cache_touches_locked(
293
+ self,
294
+ ) -> tuple[tuple[PendingRunCacheTouch, ...], int]:
295
+ touches = tuple(self._pending_run_cache_touches)
296
+ mode_generation = self._run_cache_mode_generation
297
+ self._pending_run_cache_touches.clear()
298
+ self._last_pending_run_cache_touch = None
299
+ self._run_cache_touch_count = 0
300
+ return touches, mode_generation
301
+
302
+ def _flush_run_cache_touches(self) -> None:
303
+ with self._run_cache_touch_lock:
304
+ if not self._pending_run_cache_touches:
305
+ self._last_pending_run_cache_touch = None
306
+ self._run_cache_touch_count = 0
307
+ return
308
+ touches, mode_generation = self._take_run_cache_touches_locked()
309
+ run_context_cache_budget.touch_many(
310
+ self,
311
+ touches,
312
+ mode_generation=mode_generation,
313
+ )
314
+
174
315
  @staticmethod
175
316
  def _scoped_key(key: Hashable) -> Hashable:
176
317
  """Namespace a run value by the active historical snapshot."""
@@ -182,9 +323,17 @@ class CalculationRunContext:
182
323
  def __enter__(self) -> "CalculationRunContext":
183
324
  """Activate this context and return it for the `with` block."""
184
325
  if not self._tokens:
326
+ max_bytes = resolve_run_context_cache_max_bytes()
327
+ with self._run_cache_touch_lock:
328
+ self._pending_run_cache_touches.clear()
329
+ self._last_pending_run_cache_touch = None
330
+ self._run_cache_touch_count = 0
331
+ self._run_cache_touch_thread_id = get_ident()
332
+ self._run_cache_budget_enabled = max_bytes is not None
333
+ self._run_cache_recency_enabled = False
185
334
  run_context_cache_budget.register(
186
335
  self,
187
- resolve_run_context_cache_max_bytes(),
336
+ max_bytes,
188
337
  )
189
338
  self._tokens.append(_active_context.set(self))
190
339
  return self
@@ -219,6 +368,12 @@ class CalculationRunContext:
219
368
 
220
369
  token = self._tokens.pop()
221
370
  is_outermost_exit = not self._tokens
371
+ if is_outermost_exit:
372
+ with self._run_cache_touch_lock:
373
+ self._pending_run_cache_touches.clear()
374
+ self._last_pending_run_cache_touch = None
375
+ self._run_cache_touch_count = 0
376
+ self._run_cache_touch_thread_id = None
222
377
  try:
223
378
  if is_outermost_exit:
224
379
  if exc_type is None:
@@ -253,7 +408,8 @@ class CalculationRunContext:
253
408
  value = loader()
254
409
  self._store_run_value(scoped_key, value)
255
410
  return value
256
- run_context_cache_budget.touch(self, "values", scoped_key)
411
+ if self._run_cache_recency_enabled:
412
+ self._touch_run_cache_entry("values", scoped_key)
257
413
  return cast(T, value)
258
414
 
259
415
  def get(self, key: Hashable, default: object = None) -> object:
@@ -263,7 +419,8 @@ class CalculationRunContext:
263
419
  value = self._values[scoped_key]
264
420
  except KeyError:
265
421
  return default
266
- run_context_cache_budget.touch(self, "values", scoped_key)
422
+ if self._run_cache_recency_enabled:
423
+ self._touch_run_cache_entry("values", scoped_key)
267
424
  return value
268
425
 
269
426
  def set(self, key: Hashable, value: object) -> None:
@@ -294,8 +451,11 @@ class CalculationRunContext:
294
451
  hit = self._dependency_cache_hits[key]
295
452
  except KeyError:
296
453
  return default
297
- if key not in self._dependency_cache_pending_publications:
298
- run_context_cache_budget.touch(self, "dependency_hits", key)
454
+ if (
455
+ self._run_cache_recency_enabled
456
+ and key not in self._dependency_cache_pending_publications
457
+ ):
458
+ self._touch_run_cache_entry("dependency_hits", key)
299
459
  return hit
300
460
 
301
461
  def buffer_dependency_cache_publication(
@@ -718,7 +878,8 @@ class CalculationRunContext:
718
878
  scoped_key = self._scoped_key(key)
719
879
  if scoped_key not in self._values:
720
880
  return False
721
- run_context_cache_budget.touch(self, "values", scoped_key)
881
+ if self._run_cache_recency_enabled:
882
+ self._touch_run_cache_entry("values", scoped_key)
722
883
  return True
723
884
 
724
885
  def __contains__(self, key: Hashable) -> bool: