Feat: Declare concurrency scope and data-plane contracts on storage ABCs (collection registry stack 4/5) by edwinyyyu · Pull Request #1531 · MemMachine/MemMachine · GitHub
Skip to content

Feat: Declare concurrency scope and data-plane contracts on storage ABCs (collection registry stack 4/5) - #1531

Closed
edwinyyyu wants to merge 2 commits into
MemMachine:mainfrom
edwinyyyu:feat/concurrency-scope
Closed

Feat: Declare concurrency scope and data-plane contracts on storage ABCs (collection registry stack 4/5)#1531
edwinyyyu wants to merge 2 commits into
MemMachine:mainfrom
edwinyyyu:feat/concurrency-scope

Conversation

@edwinyyyu

@edwinyyyu edwinyyyu commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Purpose of the change

Make the multi-process capability from #1526/#1527 reachable through the API contract. After those PRs, QdrantVectorStore supports multiple processes managing the same collections — but the VectorStore ABC still said a collection "must be managed by at most one process at a time", so no consumer was permitted to rely on it. This PR replaces that blanket sentence with a declared, per-instance concurrency scope, and states the data-plane contracts that multi-process consumers need to know (#1525).

Stacked on the open-or-create removal PR; only the last commit is new to this PR.

Description

ConcurrencyScope (common/data_types.py): PROCESS < MACHINE < CLUSTER — the widest deployment boundary within which concurrent instances of a component may safely manage the same resources. An IntEnum, ordered by breadth, so the effective scope of a composed system is the min of its parts' scopes.

Declared on the ABCsVectorStore, SegmentStore, and CollectionRegistry gain an abstract concurrency_scope property, and the one-process-per-collection/partition sentences are rewritten to defer to it: concurrent management of the same collection/partition is safe within the declared scope; beyond it, consumers shard names, as before.

Declared by the implementations:

Component Scope Why
QdrantVectorStore min(CLUSTER, registry.concurrency_scope) Qdrant is shareable across machines; the collection registry governs
SQLAlchemyCollectionRegistry CLUSTER on PostgreSQL, MACHINE on file-backed SQLite the CAS is as wide as the database's reach
SQLAlchemySegmentStore CLUSTER on PostgreSQL, MACHINE on SQLite already safe cross-process via unique-constraint create and row locks
MilvusVectorStore PROCESS collection bookkeeping guarded only by in-process locks (widened by the Milvus registry PR later in this stack)
SQLiteVectorStore PROCESS search-engine state lives in process memory
SQLiteVecVectorStore PROCESS check-then-write bookkeeping within one process

So a Qdrant store backed by a PostgreSQL registry declares CLUSTER, and one backed by a shared SQLite file declares MACHINE — the deployment can introspect what it is allowed to do instead of relying on out-of-band knowledge.

Data-plane contracts stated on VectorStoreCollection (documentation only; both are pre-existing properties that multi-process deployment makes worth stating):

  • Visibility: a returned write is durably accepted but not guaranteed visible to a subsequent query, from this instance or any other — consumers must not build on read-your-writes.
  • Authority: stored properties and property filters operate on the collection's own copy of a record, with no freshness guarantee relative to any external source of truth; consumers governed by an external authority (e.g. SQL as the record of access-determining attributes) must re-validate results against it.

Design doc: design/concurrency_scopes.md.

Fixes/Closes

Related to #1525 (contract half of the redesign).

Type of change

  • New feature (non-breaking change which adds functionality)

(Adding an abstract property is breaking for out-of-tree VectorStore/SegmentStore/CollectionRegistry implementations, which must now declare a scope.)

How Has This Been Tested?

  • Unit Test
  • Integration Test

Scope assertions per implementation: qdrant with a SQLite registry declares MACHINE and with a PostgreSQL registry (integration) declares CLUSTER; the SQLAlchemy segment store and config registry assert dialect-based scopes across the sqlite/PG fixture matrix; Milvus and both SQLite stores assert PROCESS.

Test Results: 1897 passed (default run); 585 passed (targeted integration run); ruff check, ruff format --check, ty check packages clean (no new diagnostics).

Checklist

  • I have signed the commit(s) within this pull request
  • My code follows the style guidelines of this project (See STYLE_GUIDE.md)
  • I have performed a self-review of my own code
  • I have commented my code
  • My changes generate no new warnings
  • I have added unit tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Further comments

Milvus's PROCESS declaration is honest at this point in the stack; the final PR moves Milvus onto the collection registry and widens it to min(CLUSTER, registry scope).

@edwinyyyu edwinyyyu changed the title Feat: Declare concurrency scope and data-plane contracts on storage ABCs Feat: Declare concurrency scope and data-plane contracts on storage ABCs (4/4) Aug 26, 2026
@edwinyyyu
edwinyyyu force-pushed the feat/concurrency-scope branch 3 times, most recently from ef1bae0 to dda78a0 Compare August 27, 2026 17:27
@edwinyyyu edwinyyyu changed the title Feat: Declare concurrency scope and data-plane contracts on storage ABCs (4/4) Feat: Declare concurrency scope and data-plane contracts on storage ABCs (4/5) Aug 27, 2026
@edwinyyyu edwinyyyu changed the title Feat: Declare concurrency scope and data-plane contracts on storage ABCs (4/5) Feat: Declare concurrency scope and data-plane contracts on storage ABCs (collection registry stack 4/5) Aug 27, 2026
@edwinyyyu
edwinyyyu force-pushed the feat/concurrency-scope branch 11 times, most recently from e08744b to bc5e69f Compare August 28, 2026 00:25
@edwinyyyu
edwinyyyu force-pushed the feat/concurrency-scope branch from bc5e69f to 452fbab Compare August 28, 2026 00:50
@edwinyyyu
edwinyyyu force-pushed the feat/concurrency-scope branch 3 times, most recently from 25d78a3 to 8e1021e Compare August 31, 2026 22:44
@edwinyyyu
edwinyyyu force-pushed the feat/concurrency-scope branch from 8e1021e to aaf8011 Compare September 1, 2026 22:19
edwinyyyu added a commit to edwinyyyu/MemMachine that referenced this pull request Sep 3, 2026
Adopt MemMachine#1531's ConcurrencyScope: every component computes its scope
from its params, a composition's scope is the minimum of its parts',
the deployment declares the scope it runs at, and startup refuses any
component narrower than that. The horizontal scaling requirement is
stated at cluster scope; the SQLite stores declare process or machine
and are held to every contract within it. Scope declarations are
tabulated, the file lock is named as what gives SQLite-backed stores
machine scope, and "large deployment" wording is replaced by scope.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MbYdqGZsuws6Z2WHYfCCR5
edwinyyyu added a commit to edwinyyyu/MemMachine that referenced this pull request Sep 3, 2026
…as reference

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MbYdqGZsuws6Z2WHYfCCR5
@edwinyyyu
edwinyyyu force-pushed the feat/concurrency-scope branch from aaf8011 to e832fae Compare September 3, 2026 16:57
@edwinyyyu

Copy link
Copy Markdown
Contributor Author

@edwinyyyu edwinyyyu closed this Sep 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant