Relationships
#3580 Finer-grained method locking: a long-running method on one definition blocks unrelated objects managed by the same definition
Opened by randybias · 10/17/2026
Problem
The model concurrency reference says a method holds a per-instance lock (.swamp/data/<modelType>/<modelId>/.lock) for its whole run, where "instance" means the model definition. Combined with the common pattern of one definition per resource kind (one dns-record definition whose methods take the target record name as an argument, or one vm definition managing many VMs), this means operations on different real-world objects serialize behind each other.
The effect is most visible with long-running methods. A method that polls until something is ready (for example waiting several minutes for a host to accept SSH or a cluster to become ready) holds the lock for the whole poll, so an unrelated get or create for a different object on the same definition waits until the poll finishes, or fails with a lock timeout. Parallel workflow steps that target different objects through the same definition also run one at a time.
Proposed solution
Some way to lock more finely than the whole definition, for example:
- an optional per-method lock key, e.g.
lock: { key: (args) => args.name }or a declared argument name, so two runs on the same definition only contend when they touch the same data instance; and/or - an opt-out for read-only methods (
lock: "none"or"shared"), so aget/syncdoes not queue behind a longwaiton another object.
If finer locking is not planned, it would help to state the consequence explicitly in the concurrency docs: that the lock is per definition, so a one-definition-per-kind design serializes all instances, and that long polls should be split out (e.g. into a separate definition) when concurrency matters.
Alternatives
Creating one definition per object avoids the contention, but it multiplies definitions and loses the ergonomics of a single definition per kind.
Open
No activity in this phase yet.
Sign in to post a ripple.