fix: mongo backend — sync close() + fail-loud via raw collection
two regressions in the [mongo] storage backend: (1) the four finally blocks did 'await db.close()' but the mongo lib's close() became synchronous this session, so await None raised TypeError on every op — dropped the await. (2) the backend consumed mongo's swallow-and-return-default wrapped methods raw, conflating a driver error with 'no document / not initialized' in the lib that gates authority; it now goes through the raw db.collection(name) escape hatch (the motor collection, which raises) and raises on a no-op upsert, matching the CLI's fail-loud stance. Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
parent
2d01805427
commit
13bf77f0f4
@ -6,6 +6,14 @@ self-contained per call. no module-level client and no shared event loop, so it
|
||||
never collides with a running loop. a per-call connect is an accepted tradeoff
|
||||
for a one-shot admin CLI. requires envelope_authorizer[mongo]; without it every
|
||||
method raises a clear RuntimeError.
|
||||
|
||||
fail-loud: operations go through the mongo lib's RAW collection escape hatch
|
||||
(`db.collection(name)`, the motor collection — which raises) rather than the
|
||||
swallow-and-return-default wrapped methods. this is an auth backend; conflating
|
||||
a backend error with "no document / not initialized" in the thing that gates
|
||||
authority is the worst place for the swallow anti-pattern, so a driver error
|
||||
propagates and a no-op upsert raises instead of silently reporting success.
|
||||
`close()` is synchronous on the mongo lib (motor's close is sync) — not awaited.
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
@ -36,33 +44,38 @@ class MongoStore(StorageBackend):
|
||||
async def _get(self, fingerprint: str) -> Optional[dict]:
|
||||
db = Mongo(self.uri, self.database)
|
||||
try:
|
||||
return await db.get_document(self.collection, {"_id": fingerprint})
|
||||
return await db.collection(self.collection).find_one({"_id": fingerprint})
|
||||
finally:
|
||||
await db.close()
|
||||
db.close()
|
||||
|
||||
async def _get_all(self) -> List[dict]:
|
||||
db = Mongo(self.uri, self.database)
|
||||
try:
|
||||
return await db.get_documents(self.collection, {})
|
||||
cursor = db.collection(self.collection).find({})
|
||||
return await cursor.to_list(length=None)
|
||||
finally:
|
||||
await db.close()
|
||||
db.close()
|
||||
|
||||
async def _save(self, doc: dict) -> None:
|
||||
db = Mongo(self.uri, self.database)
|
||||
try:
|
||||
await db.update_document(
|
||||
self.collection, {"_id": doc["_id"]}, doc, do_upsert=True
|
||||
result = await db.collection(self.collection).replace_one(
|
||||
{"_id": doc["_id"]}, doc, upsert=True
|
||||
)
|
||||
if not (result.matched_count or result.upserted_id):
|
||||
raise RuntimeError(
|
||||
f"mongo upsert affected no document for _id={doc['_id']!r}"
|
||||
)
|
||||
finally:
|
||||
await db.close()
|
||||
db.close()
|
||||
|
||||
async def _delete(self, fingerprint: str) -> bool:
|
||||
db = Mongo(self.uri, self.database)
|
||||
try:
|
||||
removed = await db.delete_document(self.collection, {"_id": fingerprint})
|
||||
return bool(removed)
|
||||
result = await db.collection(self.collection).delete_one({"_id": fingerprint})
|
||||
return result.deleted_count > 0
|
||||
finally:
|
||||
await db.close()
|
||||
db.close()
|
||||
|
||||
def get(self, fingerprint: str) -> Optional[dict]:
|
||||
"""return the key doc with this `_id`, or None"""
|
||||
|
||||
Loading…
Reference in New Issue
Block a user