mirror of
https://github.com/tiennm99/DocsGPT.git
synced 2026-10-14 16:16:48 +00:00
fix(db): make compression-point deduplication atomic
The duplicate check for append_compression_point ran as a SELECT before the UPDATE, so two sessions persisting the same point could both pass it. The predicate now lives inside the UPDATE's CASE expression and is evaluated under the row lock; a point without query_index or compressed_summary never matches and is always appended. Adds a two-session regression test that races the same point and expects one.
This commit is contained in:
1 parent
1f86139b9c
commit
fdba261d11
2 files changed
+78
-38
No files matched your search
@@ -393,6 +393,46 @@ class TestCompressionMetadata:
|
||||
points = repo.get(conv["id"], "user-1")["compression_metadata"]["compression_points"]
|
||||
assert [p["query_index"] for p in points] == [3, 5]
|
||||
|
||||
def test_append_compression_point_dedupes_across_concurrent_sessions(self, pg_engine):
|
||||
"""The duplicate check runs inside the UPDATE, under the row lock, so
|
||||
two sessions racing to persist the same point store it once."""
|
||||
import threading
|
||||
import time
|
||||
|
||||
with pg_engine.connect() as setup:
|
||||
with setup.begin():
|
||||
conv = _repo(setup).create("user-1", "c")
|
||||
point = {"query_index": 3, "compressed_summary": "S", "original_token_count": 90}
|
||||
results, errors = [], []
|
||||
|
||||
def append(hold_before_commit):
|
||||
try:
|
||||
with pg_engine.connect() as conn:
|
||||
with conn.begin():
|
||||
results.append(
|
||||
_repo(conn).append_compression_point(
|
||||
conv["id"], dict(point), max_points=3
|
||||
)
|
||||
)
|
||||
time.sleep(hold_before_commit)
|
||||
except Exception as exc: # pragma: no cover - surfaced by the assertion
|
||||
errors.append(exc)
|
||||
|
||||
first = threading.Thread(target=append, args=(0.5,))
|
||||
second = threading.Thread(target=append, args=(0.0,))
|
||||
first.start()
|
||||
time.sleep(0.1) # second blocks on the row lock until first commits
|
||||
second.start()
|
||||
first.join()
|
||||
second.join()
|
||||
|
||||
assert not errors
|
||||
assert results == [True, True]
|
||||
with pg_engine.connect() as conn:
|
||||
fetched = _repo(conn).get(conv["id"], "user-1")
|
||||
points = fetched["compression_metadata"]["compression_points"]
|
||||
assert [p["query_index"] for p in points] == [3]
|
||||
|
||||
|
||||
class TestResolveAgentRef:
|
||||
"""The repo must translate Mongo ObjectId-shaped ``agent_id`` values
|
||||
|
||||
Reference in new issue
Block a user