Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Intended for qualified import
import Test.Util.OracularClock (OracularClock(..)) import qualified Test.Util.OracularClock as OracularClock
Synopsis
- data EndOfDaysException = EndOfDaysException
- data OracularClock m = OracularClock {
- blockUntilSlot ∷ SlotNo → m Bool
- delayUntilNextSlot ∷ m NominalDiffTime
- finiteSystemTime ∷ SystemTime m
- getCurrentSlot ∷ m SlotNo
- forkEachSlot_ ∷ HasCallStack ⇒ ResourceRegistry m → String → (SlotNo → m ()) → m (m ())
- waitUntilDone ∷ m ()
- forkEachSlot ∷ HasCallStack ⇒ ResourceRegistry m → OracularClock m → String → (SlotNo → m ()) → m (m ())
- mkOracularClock ∷ ∀ m. IOLike m ⇒ SystemTime m → NumSlots → Future → OracularClock m
Documentation
data EndOfDaysException Source #
A thread used an OracularClock
well after it was exhausted
A thread using an exhausted OracularClock
first briefly delays, so that
finalizers etc have a chance to terminate it. If that tear down isn't prompt
enough, the thread then throws this exception, which we don't catch
anywhere.
Instances
data OracularClock m Source #
A clock that knows the future
This clock's closure contains a SystemTime
, a Future
, and a
NumSlots
. Once all NumSlots
have passed, the clock is exhausted and
all of its methods begin throwing EndOfDaysException
.
Notably, waitUntilDone
blocks until the the clock is exhausted; so the
continuation of that call should promptly reap other threads using this
clock because they will otherwise soon raise EndOfDaysException
.
Note: Though the wallclock-slot correspondence depends on the ledger state,
we have designed our ledgers so that all nodes necessarily use the same
correspondence in the absence of a Common Prefix violation. This ensures all
nodes adopt the same timeline, which must be the Future
that this clock
anticipates.
OracularClock | |
|
forkEachSlot ∷ HasCallStack ⇒ ResourceRegistry m → OracularClock m → String → (SlotNo → m ()) → m (m ()) Source #
Forks a thread that executes an action at the onset of each slot
Returns an action that cancels the thread.
INVARIANT: In io-sim
, there is no race:
and hence finiteSystemTime
.systemTimeCurrentgetCurrentSlot
called
from within the given action will always return the correct slot.
See the discussion of ticker threads in getCurrentSlot
.
mkOracularClock ∷ ∀ m. IOLike m ⇒ SystemTime m → NumSlots → Future → OracularClock m Source #
See OracularClock
NOTE: Every method relies only on the given SystemTime
. For example,
there is no internal ticker thread underlying this OracularClock
. This
design avoids the risk of certain kinds of races, particularly with respect
to
hardForkBlockchainTime
which also only relies on SystemTime
.
PREREQUISITE: The only assumption about the given SystemTime
is that
its systemCurrentTime
ticks before any threadDelay
-ed thread
scheduled to wake-up then does so. The defaultSystemTime
in the mock
IO
monad provided by io-sim
satisfies this assumption.