def wait.loop

mylsm-lsm-store@0.6.0.1 · src/DbLock.bend:271

import mylsm-lsm-store@0.6.0.1/src/DbLock.bend as DbLock
import Base
import mylsm-lsm-store@0.6.0.1/src/DurableError.bend as DurableError
import mylsm-lsm-store@0.6.0.1/src/Fs.bend as Fs

271# Runs lock, clock, and sleep transitions with one decreasing structural fuel.
272def wait.loop(fuel: Nat, state: WaitState) -> IO(Result<&1, &1, DurableError.Error, Lock>):
273  match fuel:
274    case 0n:
275      wait.exhausted(state)
276    case 1n+rest:
277      match state:
278        case TryLock{file, started_us, timeout_ms, backoff_ms, operation, path}:
279          do IO<Result<&1, &1, DurableError.Error, Lock>>:
280            pair : File & Result<&1, &1, U32 & String, Unit> <- DbLock.try_lock(file)
281            wait.loop(rest, LockAttempt{pair, started_us, timeout_ms,
282              backoff_ms, operation, path})
283        case LockAttempt{pair, started_us, timeout_ms, backoff_ms, operation, path}:
284          match pair:
285            case (file, Done{Unit{}}):
286              IO.pure(Result<&1, &1, DurableError.Error, Lock>, Done{Lock{file}})
287            case (file, Fail{error}):
288              wait.loop(rest, wait.attempt.state(wait.attempt.decision(error),
289                file, started_us, timeout_ms, backoff_ms, operation, path))
290        case ReadClock{file, started_us, timeout_ms, backoff_ms, operation, path, purpose}:
291          do IO<Result<&1, &1, DurableError.Error, Lock>>:
292            result : Result<&1, &1, U32 & String, Nat> <- Fs.clock_monotonic()
293            wait.loop(rest, ClockSample{file, started_us, timeout_ms,
294              backoff_ms, operation, path, purpose, result})
295        case ClockSample{file, +started_us, +timeout_ms, +backoff_ms,
296            operation, path, purpose, result}:
297          match result:
298            case Fail{error}:
299              wait.host_error(file, error, operation, path)
300            case Done{now_us}:
301              +elapsed_us = Nat.sub(now_us, started_us)
302              +elapsed_ms = Nat.div(elapsed_us, 1000n)
303              wait.loop(rest, wait.clock.decision(purpose, file, started_us,
304                timeout_ms, backoff_ms, operation, path, elapsed_ms))
305        case Pause{file, started_us, timeout_ms, backoff_ms, operation, path, duration_ms}:
306          do IO<Result<&1, &1, DurableError.Error, Lock>>:
307            result : Result<&1, &1, U32 & String, Unit> <- Fs.sleep_ms(duration_ms)
308            wait.loop(rest, PauseResult{file, started_us, timeout_ms,
309              backoff_ms, operation, path, result})
310        case PauseResult{file, started_us, timeout_ms, backoff_ms, operation, path, result}:
311          match result:
312            case Fail{error}:
313              wait.host_error(file, error, operation, path)
314            case Done{Unit{}}:
315              wait.loop(rest, ReadClock{file, started_us, timeout_ms,
316                backoff_ms, operation, path, CheckDeadline{}})
317        case WaitFatal{file, error, operation, path}:
318          lock_failed(file, error, operation, path)
319        case WaitExpired{file, operation, path}:
320          wait.timeout(file, operation, path)

Uses (27)

Used by (1)