LockUpgrade
Helpers for the common "check under a read lock, then optionally re-run under a write lock" pattern.
Attributes
- Source
- LockUpgrade.scala
- Graph
-
- Supertypes
-
class Objecttrait Matchableclass Any
- Self type
-
LockUpgrade.type
Members list
Type members
Classlikes
Attributes
- Source
- LockUpgrade.scala
- Supertypes
-
trait Enumtrait Serializabletrait Producttrait Equalsclass Objecttrait Matchableclass AnyShow all
Attributes
- Source
- LockUpgrade.scala
- Supertypes
-
class Objecttrait Matchableclass Any
Value members
Concrete methods
Retryable read-then-write upgrade.
Retryable read-then-write upgrade.
- Acquire Read, run
readBody. If Decision.Complete, return. - If Decision.Escalate, release Read and try Write non-blocking (
tryAcquireWrite). If that succeeds, runwriteBodyunder the Write lease and return. - If
tryAcquireWritereturns scala.Left (lock contended),awaitStateChangefor a bounded interval, then loop back to step 1.
Non-blocking try-Write turns long bounded waits into fast cache-hit re-probes: when launcher A is publishing under Write and B wants to compute the same task, B's blocking-Write would wait for A's publish AND for A's downgraded Read (retained for A's downstreams). With try-Write + retry, B fails its Write attempt, then re-acquires Read (which shares with A's Read), and readBody sees the just-published cache and returns Decision.Complete — no Write needed. The bounded awaitStateChange keeps the retry cheap: the lock notifyAlls on every close/downgrade, so retries fire exactly when a re-probe might newly succeed.
tryAcquireWrite MUST NOT register the caller as a queued writer (i.e., must not increment any waiter counter that gates Read acquisition); otherwise the caller's own next Read attempt would trip writer-priority and the retry loop would stall.
Attributes
- Source
- LockUpgrade.scala