memgres 0.13.1__tar.gz → 0.13.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 (166) hide show
  1. {memgres-0.13.1 → memgres-0.13.2}/PKG-INFO +1 -1
  2. {memgres-0.13.1 → memgres-0.13.2}/memgres/_version.py +1 -1
  3. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0023_relink_after_parser_fix.sql +14 -1
  4. {memgres-0.13.1 → memgres-0.13.2}/memgres/relink.py +27 -0
  5. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/app.css +2 -0
  6. {memgres-0.13.1 → memgres-0.13.2}/memgres.egg-info/PKG-INFO +1 -1
  7. {memgres-0.13.1 → memgres-0.13.2}/tests/test_links.py +28 -0
  8. {memgres-0.13.1 → memgres-0.13.2}/LICENSE +0 -0
  9. {memgres-0.13.1 → memgres-0.13.2}/README.md +0 -0
  10. {memgres-0.13.1 → memgres-0.13.2}/memgres/__init__.py +0 -0
  11. {memgres-0.13.1 → memgres-0.13.2}/memgres/admin.py +0 -0
  12. {memgres-0.13.1 → memgres-0.13.2}/memgres/admin_cli.py +0 -0
  13. {memgres-0.13.1 → memgres-0.13.2}/memgres/blame.py +0 -0
  14. {memgres-0.13.1 → memgres-0.13.2}/memgres/bootstrap.py +0 -0
  15. {memgres-0.13.1 → memgres-0.13.2}/memgres/config.py +0 -0
  16. {memgres-0.13.1 → memgres-0.13.2}/memgres/delimiters.py +0 -0
  17. {memgres-0.13.1 → memgres-0.13.2}/memgres/diffing.py +0 -0
  18. {memgres-0.13.1 → memgres-0.13.2}/memgres/embed_worker.py +0 -0
  19. {memgres-0.13.1 → memgres-0.13.2}/memgres/embeddings.py +0 -0
  20. {memgres-0.13.1 → memgres-0.13.2}/memgres/healthcheck.py +0 -0
  21. {memgres-0.13.1 → memgres-0.13.2}/memgres/identity.py +0 -0
  22. {memgres-0.13.1 → memgres-0.13.2}/memgres/indexing.py +0 -0
  23. {memgres-0.13.1 → memgres-0.13.2}/memgres/info.py +0 -0
  24. {memgres-0.13.1 → memgres-0.13.2}/memgres/lines.py +0 -0
  25. {memgres-0.13.1 → memgres-0.13.2}/memgres/links.py +0 -0
  26. {memgres-0.13.1 → memgres-0.13.2}/memgres/mcp_server.py +0 -0
  27. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0001_core.sql +0 -0
  28. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0002_identity.sql +0 -0
  29. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0003_history_author.sql +0 -0
  30. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0004_title.sql +0 -0
  31. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0005_chunk_index.sql +0 -0
  32. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0006_reader_floor.sql +0 -0
  33. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0007_embed_retry.sql +0 -0
  34. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0008_service_roles.sql +0 -0
  35. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0009_create_namespace_right.sql +0 -0
  36. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0010_namespace_alias.sql +0 -0
  37. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0011_drop_default_namespace.sql +0 -0
  38. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0012_user_profile.sql +0 -0
  39. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0013_hash_version.sql +0 -0
  40. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0014_access_request_no_fk.sql +0 -0
  41. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0015_normalize_tags.sql +0 -0
  42. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0016_valid_at.sql +0 -0
  43. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0017_memory_link.sql +0 -0
  44. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0018_links_built.sql +0 -0
  45. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0019_memory_usage.sql +0 -0
  46. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0020_memory_usage_no_fk.sql +0 -0
  47. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0021_enrollment_key.sql +0 -0
  48. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0022_user_disabled.sql +0 -0
  49. {memgres-0.13.1 → memgres-0.13.2}/memgres/migrations/0024_web_panel.sql +0 -0
  50. {memgres-0.13.1 → memgres-0.13.2}/memgres/paths.py +0 -0
  51. {memgres-0.13.1 → memgres-0.13.2}/memgres/periodic.py +0 -0
  52. {memgres-0.13.1 → memgres-0.13.2}/memgres/reembed.py +0 -0
  53. {memgres-0.13.1 → memgres-0.13.2}/memgres/schema.py +0 -0
  54. {memgres-0.13.1 → memgres-0.13.2}/memgres/search.py +0 -0
  55. {memgres-0.13.1 → memgres-0.13.2}/memgres/segments.py +0 -0
  56. {memgres-0.13.1 → memgres-0.13.2}/memgres/server.py +0 -0
  57. {memgres-0.13.1 → memgres-0.13.2}/memgres/store.py +0 -0
  58. {memgres-0.13.1 → memgres-0.13.2}/memgres/tags.py +0 -0
  59. {memgres-0.13.1 → memgres-0.13.2}/memgres/token_cli.py +0 -0
  60. {memgres-0.13.1 → memgres-0.13.2}/memgres/vector/__init__.py +0 -0
  61. {memgres-0.13.1 → memgres-0.13.2}/memgres/vector/base.py +0 -0
  62. {memgres-0.13.1 → memgres-0.13.2}/memgres/vector/pgvector.py +0 -0
  63. {memgres-0.13.1 → memgres-0.13.2}/memgres/vector/qdrant.py +0 -0
  64. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/__init__.py +0 -0
  65. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/admission.py +0 -0
  66. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/auth_routes.py +0 -0
  67. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/memory.py +0 -0
  68. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/oidc.py +0 -0
  69. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/oidc_config.py +0 -0
  70. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/people.py +0 -0
  71. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/routes.py +0 -0
  72. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/sessions.py +0 -0
  73. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/spaces.py +0 -0
  74. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/OFL-JetBrainsMono.txt +0 -0
  75. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/OFL-Onest.txt +0 -0
  76. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/jetbrainsmono-cyrillic-ext.woff2 +0 -0
  77. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/jetbrainsmono-cyrillic.woff2 +0 -0
  78. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/jetbrainsmono-latin-ext.woff2 +0 -0
  79. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/jetbrainsmono-latin.woff2 +0 -0
  80. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/onest-cyrillic-ext.woff2 +0 -0
  81. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/onest-cyrillic.woff2 +0 -0
  82. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/onest-latin-ext.woff2 +0 -0
  83. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts/onest-latin.woff2 +0 -0
  84. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/fonts.css +0 -0
  85. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/index.html +0 -0
  86. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/account.js +0 -0
  87. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/admin.js +0 -0
  88. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/api.js +0 -0
  89. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/app.js +0 -0
  90. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/gate.js +0 -0
  91. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/i18n.js +0 -0
  92. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/md.js +0 -0
  93. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/memory.js +0 -0
  94. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/people.js +0 -0
  95. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/signins.js +0 -0
  96. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/space.js +0 -0
  97. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/tokens.js +0 -0
  98. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/ui.js +0 -0
  99. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/js/viz.js +0 -0
  100. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/locales/en.json +0 -0
  101. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/locales/ru.json +0 -0
  102. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/vendor/LICENSE-d3.txt +0 -0
  103. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/vendor/LICENSE-dompurify.txt +0 -0
  104. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/vendor/LICENSE-marked.txt +0 -0
  105. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/vendor/d3.min.js +0 -0
  106. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/vendor/marked.esm.js +0 -0
  107. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/static/vendor/purify.es.js +0 -0
  108. {memgres-0.13.1 → memgres-0.13.2}/memgres/web/tokens.py +0 -0
  109. {memgres-0.13.1 → memgres-0.13.2}/memgres/worker.py +0 -0
  110. {memgres-0.13.1 → memgres-0.13.2}/memgres.egg-info/SOURCES.txt +0 -0
  111. {memgres-0.13.1 → memgres-0.13.2}/memgres.egg-info/dependency_links.txt +0 -0
  112. {memgres-0.13.1 → memgres-0.13.2}/memgres.egg-info/entry_points.txt +0 -0
  113. {memgres-0.13.1 → memgres-0.13.2}/memgres.egg-info/requires.txt +0 -0
  114. {memgres-0.13.1 → memgres-0.13.2}/memgres.egg-info/top_level.txt +0 -0
  115. {memgres-0.13.1 → memgres-0.13.2}/pyproject.toml +0 -0
  116. {memgres-0.13.1 → memgres-0.13.2}/setup.cfg +0 -0
  117. {memgres-0.13.1 → memgres-0.13.2}/tests/test_admin_two_way.py +0 -0
  118. {memgres-0.13.1 → memgres-0.13.2}/tests/test_blame_integration.py +0 -0
  119. {memgres-0.13.1 → memgres-0.13.2}/tests/test_chunk_index.py +0 -0
  120. {memgres-0.13.1 → memgres-0.13.2}/tests/test_claim_and_reembed.py +0 -0
  121. {memgres-0.13.1 → memgres-0.13.2}/tests/test_config.py +0 -0
  122. {memgres-0.13.1 → memgres-0.13.2}/tests/test_diffing.py +0 -0
  123. {memgres-0.13.1 → memgres-0.13.2}/tests/test_embed_worker.py +0 -0
  124. {memgres-0.13.1 → memgres-0.13.2}/tests/test_embeddings.py +0 -0
  125. {memgres-0.13.1 → memgres-0.13.2}/tests/test_enrollment.py +0 -0
  126. {memgres-0.13.1 → memgres-0.13.2}/tests/test_healthcheck.py +0 -0
  127. {memgres-0.13.1 → memgres-0.13.2}/tests/test_identity_integration.py +0 -0
  128. {memgres-0.13.1 → memgres-0.13.2}/tests/test_lexical_match.py +0 -0
  129. {memgres-0.13.1 → memgres-0.13.2}/tests/test_limits.py +0 -0
  130. {memgres-0.13.1 → memgres-0.13.2}/tests/test_list.py +0 -0
  131. {memgres-0.13.1 → memgres-0.13.2}/tests/test_mcp_admin_tools.py +0 -0
  132. {memgres-0.13.1 → memgres-0.13.2}/tests/test_mcp_error_messages.py +0 -0
  133. {memgres-0.13.1 → memgres-0.13.2}/tests/test_mcp_http_transport.py +0 -0
  134. {memgres-0.13.1 → memgres-0.13.2}/tests/test_mcp_instructions.py +0 -0
  135. {memgres-0.13.1 → memgres-0.13.2}/tests/test_mcp_recall_schema.py +0 -0
  136. {memgres-0.13.1 → memgres-0.13.2}/tests/test_mcp_tool_visibility.py +0 -0
  137. {memgres-0.13.1 → memgres-0.13.2}/tests/test_mcp_tool_visibility_http.py +0 -0
  138. {memgres-0.13.1 → memgres-0.13.2}/tests/test_migration_upgrade.py +0 -0
  139. {memgres-0.13.1 → memgres-0.13.2}/tests/test_multi_space_search.py +0 -0
  140. {memgres-0.13.1 → memgres-0.13.2}/tests/test_path_addressing.py +0 -0
  141. {memgres-0.13.1 → memgres-0.13.2}/tests/test_qdrant_ca.py +0 -0
  142. {memgres-0.13.1 → memgres-0.13.2}/tests/test_qdrant_integration.py +0 -0
  143. {memgres-0.13.1 → memgres-0.13.2}/tests/test_replace_build.py +0 -0
  144. {memgres-0.13.1 → memgres-0.13.2}/tests/test_require_title.py +0 -0
  145. {memgres-0.13.1 → memgres-0.13.2}/tests/test_required_fields.py +0 -0
  146. {memgres-0.13.1 → memgres-0.13.2}/tests/test_retention.py +0 -0
  147. {memgres-0.13.1 → memgres-0.13.2}/tests/test_roles_bootstrap.py +0 -0
  148. {memgres-0.13.1 → memgres-0.13.2}/tests/test_search_integration.py +0 -0
  149. {memgres-0.13.1 → memgres-0.13.2}/tests/test_security_followups.py +0 -0
  150. {memgres-0.13.1 → memgres-0.13.2}/tests/test_security_integration.py +0 -0
  151. {memgres-0.13.1 → memgres-0.13.2}/tests/test_segments.py +0 -0
  152. {memgres-0.13.1 → memgres-0.13.2}/tests/test_segments_store.py +0 -0
  153. {memgres-0.13.1 → memgres-0.13.2}/tests/test_server_info.py +0 -0
  154. {memgres-0.13.1 → memgres-0.13.2}/tests/test_server_integration.py +0 -0
  155. {memgres-0.13.1 → memgres-0.13.2}/tests/test_snippets.py +0 -0
  156. {memgres-0.13.1 → memgres-0.13.2}/tests/test_store_integration.py +0 -0
  157. {memgres-0.13.1 → memgres-0.13.2}/tests/test_tags.py +0 -0
  158. {memgres-0.13.1 → memgres-0.13.2}/tests/test_token_sink.py +0 -0
  159. {memgres-0.13.1 → memgres-0.13.2}/tests/test_usage.py +0 -0
  160. {memgres-0.13.1 → memgres-0.13.2}/tests/test_valid_at.py +0 -0
  161. {memgres-0.13.1 → memgres-0.13.2}/tests/test_web_memory.py +0 -0
  162. {memgres-0.13.1 → memgres-0.13.2}/tests/test_web_oidc.py +0 -0
  163. {memgres-0.13.1 → memgres-0.13.2}/tests/test_web_people.py +0 -0
  164. {memgres-0.13.1 → memgres-0.13.2}/tests/test_web_session.py +0 -0
  165. {memgres-0.13.1 → memgres-0.13.2}/tests/test_web_tokens.py +0 -0
  166. {memgres-0.13.1 → memgres-0.13.2}/tests/test_write_ergonomics.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memgres
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: Drop-in memory for AI agents: one Postgres, lexical + semantic recall, diff-versioned history, GDPR-erasable.
5
5
  Author: mozgsml
6
6
  License-Expression: MIT
@@ -8,4 +8,4 @@ here at release; nowhere else carries the number.
8
8
  PEP 440: a ``.devN`` suffix marks an unreleased build ahead of the last tag.
9
9
  """
10
10
 
11
- __version__ = "0.13.1"
11
+ __version__ = "0.13.2"
@@ -13,4 +13,17 @@
13
13
  --
14
14
  -- Additive by nature — an older client reading this database is no worse off
15
15
  -- than it was, so the compatibility floor does not move.
16
- UPDATE memgres_meta SET links_built = false;
16
+ -- ONCE. Every migration file runs again at every start (they are meant to be
17
+ -- idempotent), and a bare UPDATE here cleared the flag on every start — so every
18
+ -- start rebuilt the whole link graph, and two servers starting together raced on
19
+ -- it. The marker column makes the clearing happen the first time only; on a
20
+ -- database that has been through this file before, it happens one last time.
21
+ DO $$
22
+ BEGIN
23
+ IF NOT EXISTS (SELECT 1 FROM information_schema.columns
24
+ WHERE table_schema = current_schema() AND table_name = 'memgres_meta'
25
+ AND column_name = 'relinked_after_0023') THEN
26
+ ALTER TABLE memgres_meta ADD COLUMN relinked_after_0023 boolean NOT NULL DEFAULT true;
27
+ UPDATE memgres_meta SET links_built = false;
28
+ END IF;
29
+ END $$;
@@ -20,6 +20,12 @@ _log = logging.getLogger("memgres.relink")
20
20
 
21
21
  BATCH = 500
22
22
 
23
+ # One rebuild at a time across processes. Two servers starting together (the MCP
24
+ # door and the REST/panel door) both found the flag clear and rebuilt at once,
25
+ # and one of them died on the other's rows. A session-level advisory lock: held
26
+ # for the rebuild, gone with the connection if the process is.
27
+ LOCK_KEY = 0x6D656D67_6C6E6B # "memglnk"
28
+
23
29
 
24
30
  class _NoEmbedder:
25
31
  """Stands in for an embedder so `Store` does not build the real one. The
@@ -55,11 +61,32 @@ def rebuild(conn, cfg, *, force: bool = False) -> int:
55
61
  the flag false — so the server came up serving a link graph that was perfectly
56
62
  empty while saying it had built one. Owning the commit here means the work is
57
63
  durable when this returns, whatever the caller does next."""
64
+ with conn.cursor() as cur:
65
+ cur.execute("SELECT pg_try_advisory_lock(%s)", (LOCK_KEY,))
66
+ mine = cur.fetchone()[0]
67
+ if not mine:
68
+ conn.commit()
69
+ _log.info("the link index is being rebuilt by another process; not starting a second pass")
70
+ return 0
71
+ try:
72
+ return _rebuild(conn, cfg, force=force)
73
+ finally:
74
+ try:
75
+ with conn.cursor() as cur:
76
+ cur.execute("SELECT pg_advisory_unlock(%s)", (LOCK_KEY,))
77
+ conn.commit()
78
+ except Exception: # a broken connection releases the lock by closing
79
+ pass
80
+
81
+
82
+ def _rebuild(conn, cfg, *, force: bool) -> int:
58
83
  from .store import Store
59
84
  with conn.cursor() as cur:
85
+ # read under the lock: another process may have just finished
60
86
  cur.execute("SELECT links_built FROM memgres_meta")
61
87
  row = cur.fetchone()
62
88
  if row and row[0] and not force:
89
+ conn.commit()
63
90
  return 0
64
91
 
65
92
  # `_sync_links` touches neither embeddings nor vectors; passing a
@@ -487,3 +487,5 @@ a.person:hover { color: var(--focus); box-shadow: inset 0 -1px 0 var(--focus); }
487
487
  .node.hubnode .halo { opacity: .12; stroke-width: 18; }
488
488
  .node.hubnode.sel .halo { opacity: .22; }
489
489
  @media (prefers-reduced-motion: reduce) { .spinner, .search.busy::before { animation-duration: 2.4s; } }
490
+ /* the results header — the query and × — stays put while the list scrolls under it */
491
+ .results > .res-head { position: sticky; top: -14px; z-index: 2; margin: -14px -14px 0; padding: 14px 14px 10px; background: var(--panel); border-radius: 14px 14px 0 0; box-shadow: 0 1px 0 var(--line-soft); }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: memgres
3
- Version: 0.13.1
3
+ Version: 0.13.2
4
4
  Summary: Drop-in memory for AI agents: one Postgres, lexical + semantic recall, diff-versioned history, GDPR-erasable.
5
5
  Author: mozgsml
6
6
  License-Expression: MIT
@@ -778,3 +778,31 @@ def test_an_expired_referrer_is_left_alone(monkeypatch):
778
778
  body, seq = cur.fetchone()
779
779
  assert body == "see [[ops.a]]" and seq == 1
780
780
  conn.close()
781
+
782
+
783
+ def test_starting_again_does_not_clear_the_flag(store):
784
+ """Migrations run at every start. The one that asked for a rebuild after the
785
+ parser fix used to clear the flag every time, so every start rebuilt the
786
+ whole graph — and two servers starting together raced on it."""
787
+ from memgres.relink import rebuild
788
+ store.write(body="see [[ops.deploy]]", path="notes.a")
789
+ rebuild(store._conn, store.cfg, force=True)
790
+ with psycopg.connect(DSN) as conn:
791
+ migrate(conn, store.cfg)
792
+ conn.commit()
793
+ with conn.cursor() as cur:
794
+ cur.execute("SELECT links_built FROM memgres_meta")
795
+ assert cur.fetchone()[0] is True
796
+
797
+
798
+ def test_a_second_process_does_not_rebuild_alongside_the_first(store):
799
+ from memgres.relink import LOCK_KEY, rebuild
800
+ store.write(body="see [[ops.deploy]]", path="notes.a")
801
+ with store._conn.cursor() as cur:
802
+ cur.execute("UPDATE memgres_meta SET links_built = false")
803
+ store._conn.commit()
804
+ with psycopg.connect(DSN, autocommit=True) as other:
805
+ other.execute("SELECT pg_advisory_lock(%s)", (LOCK_KEY,)) # "another server is rebuilding"
806
+ assert rebuild(store._conn, store.cfg) == 0 # skips, no error
807
+ other.execute("SELECT pg_advisory_unlock(%s)", (LOCK_KEY,))
808
+ assert rebuild(store._conn, store.cfg) == 1 # and runs once it is free
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes