Returns a monotonic clock measurement, if supported by the underlying platform.
Returns a monotonic clock measurement, if supported by the underlying platform.
This is the pure equivalent of Java's System.nanoTime
,
or of CLOCK_MONOTONIC
from Linux's clock_gettime()
.
timer.clockMonotonic(NANOSECONDS)
The returned value can have nanoseconds resolution and represents
the number of time units elapsed since some fixed but arbitrary
origin time. Usually this is the Unix epoch, but that's not
a guarantee, as due to the limits of Long
this will overflow in
the future (263 is about 292 years in nanoseconds) and the
implementation reserves the right to change the origin.
The return value should not be considered related to wall-clock time, the primary use-case being to take time measurements and compute differences between such values, for example in order to measure the time it took to execute a task.
As a matter of implementation detail, Monix's Scheduler
implementations use System.nanoTime
and the JVM will use
CLOCK_MONOTONIC
when available, instead of CLOCK_REALTIME
(see clock_gettime()
on Linux) and it is up to the underlying
platform to implement it correctly.
And be warned, there are platforms that don't have a correct
implementation of CLOCK_MONOTONIC
. For example at the moment of
writing there is no standard way for such a clock on top of
JavaScript and the situation isn't so clear cut for the JVM
either, see:
The JVM tries to do the right thing and at worst the resolution
and behavior will be that of System.currentTimeMillis
.
The recommendation is to use this monotonic clock when doing measurements of execution time, or if you value monotonically increasing values more than a correspondence to wall-time, or otherwise prefer clockRealTime.
Returns the current time, as a Unix timestamp (number of time units since the Unix epoch).
Returns the current time, as a Unix timestamp (number of time units since the Unix epoch).
This is the equivalent of Java's System.currentTimeMillis
,
or of CLOCK_REALTIME
from Linux's clock_gettime()
.
The provided TimeUnit
determines the time unit of the output,
its precision, but not necessarily its resolution, which is
implementation dependent. For example this will return the number
of milliseconds since the epoch:
import scala.concurrent.duration.MILLISECONDS
scheduler.clockRealTime(MILLISECONDS)
N.B. the resolution is limited by the underlying implementation
and by the underlying CPU and OS. If the implementation uses
System.currentTimeMillis
, then it can't have a better
resolution than 1 millisecond, plus depending on underlying
runtime (e.g. Node.js) it might return multiples of 10
milliseconds or more.
See clockMonotonic, for fetching a monotonic value that may be better suited for doing time measurements.
Schedules the given command
for execution at some time in the future.
Schedules the given command
for execution at some time in the future.
The command may execute in a new thread, in a pooled thread, in the calling thread, basically at the discretion of the Scheduler implementation.
The ExecutionModel is a specification of how run-loops and producers should behave in regards to executing tasks either synchronously or asynchronously.
The ExecutionModel is a specification of how run-loops and producers should behave in regards to executing tasks either synchronously or asynchronously.
Reports that an asynchronous computation failed.
Reports that an asynchronous computation failed.
Schedules a periodic task that becomes enabled first after the given initial delay, and subsequently with the given period.
Schedules a periodic task that becomes enabled first after the given
initial delay, and subsequently with the given period. Executions will
commence after initialDelay
then initialDelay + period
, then
initialDelay + 2 * period
and so on.
If any execution of the task encounters an exception, subsequent executions are suppressed. Otherwise, the task will only terminate via cancellation or termination of the scheduler. If any execution of this task takes longer than its period, then subsequent executions may start late, but will not concurrently execute.
For example the following schedules a message to be printed to standard output approximately every 10 seconds with an initial delay of 5 seconds:
val task = scheduler.scheduleAtFixedRate(5, 10, TimeUnit.SECONDS, new Runnable { def run() = print("Repeated message") }) // later if you change your mind ... task.cancel()
is the time to wait until the first execution happens
is the time to wait between 2 successive executions of the task
is the time unit used for the initialDelay
and the period
parameters
is the callback to be executed
a cancelable that can be used to cancel the execution of this repeated task at any time.
Schedules a task to run in the future, after initialDelay
.
Schedules a task to run in the future, after initialDelay
.
For example the following schedules a message to be printed to standard output after 5 minutes:
val task = scheduler.scheduleOnce(5, TimeUnit.MINUTES, new Runnable { def run() = print("Hello, world!") }) // later if you change your mind ... task.cancel()
is the time to wait until the execution happens
is the time unit used for initialDelay
is the callback to be executed
a Cancelable
that can be used to cancel the created task
before execution.
Schedules for execution a periodic task that is first executed after the given initial delay and subsequently with the given delay between the termination of one execution and the commencement of the next.
Schedules for execution a periodic task that is first executed after the given initial delay and subsequently with the given delay between the termination of one execution and the commencement of the next.
For example the following schedules a message to be printed to standard output every 10 seconds with an initial delay of 5 seconds:
val task = s.scheduleWithFixedDelay(5, 10, TimeUnit.SECONDS, new Runnable { def run() = print("Repeated message") }) // later if you change your mind ... task.cancel()
is the time to wait until the first execution happens
is the time to wait between 2 successive executions of the task
is the time unit used for the initialDelay
and the delay
parameters
is the callback to be executed
a cancelable that can be used to cancel the execution of this repeated task at any time.
Returns the internal state of the TestScheduler
, useful for testing
that certain execution conditions have been met.
Triggers execution by going through the queue of scheduled tasks and executing them all, until no tasks remain in the queue to execute.
Triggers execution by going through the queue of scheduled tasks and executing them all, until no tasks remain in the queue to execute.
Order of execution isn't guaranteed, the queued Runnable
s are
being shuffled in order to simulate the needed non-determinism
that happens with multi-threading.
implicit val ec = TestScheduler() val f = Future(1 + 1).map(_ + 1) // Execution is momentarily suspended in TestContext assert(f.value == None) // Simulating async execution: ec.tick() assert(f.value, Some(Success(2)))
The optional parameter can be used for simulating time:
implicit val ec = TestScheduler() val f = Task.sleep(10.seconds).map(_ => 10).runAsync // Not yet completed, because this does not simulate time passing: ctx.tick() assert(f.value == None) // Simulating time passing: ctx.tick(10.seconds) assert(f.value == Some(Success(10))
is an optional parameter for simulating time passing
Executes just one tick, one task, from the internal queue, useful for testing that some runnable will definitely be executed next.
Executes just one tick, one task, from the internal queue, useful for testing that some runnable will definitely be executed next.
Returns a boolean indicating that tasks were available and that the head of the queue has been executed, so normally you have this equivalence:
while (ec.tickOne()) {} // ... is equivalent with: ec.tick()
Note that task extraction has a random factor, the behavior being like tick, in order to simulate non-determinism. So you can't rely on some ordering of execution if multiple tasks are waiting execution.
true
if a task was available in the internal queue, and
was executed, or false
otherwise
Given a function that will receive the underlying
ExecutionModel,
returns a new Scheduler reference, based on the source,
that exposes the transformed ExecutionModel
when queried by means of the executionModel property.
Given a function that will receive the underlying
ExecutionModel,
returns a new Scheduler reference, based on the source,
that exposes the transformed ExecutionModel
when queried by means of the executionModel property.
This method enables reusing global scheduler references in a local scope, but with a slightly modified execution model to inject.
The contract of this method (things you can rely on):
Scheduler
must not be modified in any wayScheduler
in every way except for
the execution modelSample:
import monix.execution.Scheduler.global implicit val scheduler = { val em = global.executionModel global.withExecutionModel(em.withAutoCancelableLoops(true)) }
Scheduler and a provider of
cats.effect.Timer
instances, that can simulate async boundaries and time passage, useful for testing purposes.Usage for simulating an
ExecutionContext
:TestScheduler
can also simulate the passage of time:We are also able to build a
cats.effect.Timer
from anyScheduler
and for any data type:We can now simulate time passage for
cats.effect.IO
as well:Simulating time makes this pretty useful for testing race conditions: