View Source TimeQueue (time_queue v0.9.6)
Implements a timers queue based on a list of maps. The queue can be encoded as JSON.
The performance will be worse for large queues in regard to the previous gb_trees based implementation, although the difference is negligible for small queues (<= 1000 entries).
All map keys are shrinked to a single letter as this queue is intended to be encoded and published to HTTP clients over the wire, mutiple times.
The queue keys are a map composed of the timestamp (t
) of an event
and an unique integer (u
).
No erlang timers or processes are used, as the queue is only a data structure. The advantage is that the queue can be persisted on storage and keeps working after restarting the runtime. The queue maintain its own list of unique integers to avoir relying on BEAM unique integers as they are reset on VM restarts.
The main drawback of a functional queue is that the queue entries must be manually checked for expired timers.
Link to this section Summary
Functions
Deletes an event from the queue and returns the new queue.
Deletes all entries from the queue whose values are equal to unwanted
.
Adds a new event to the queue with a TTL and the current system time as now/0
.
Adds a new event to the queue with a TTL relative to the given timestamp in milliseconds.
Adds a new event to the queue with an absolute timestamp.
Returns a new queue with entries for whom the given callback returned a truthy value.
Returns a new queue with entries for whom the given callback returned a truthy value.
Creates an empty time queue.
This function is used internally to determine the current time when using
functions enqueue/3
, pop/1
, pop_event/1
and peek_event/1
.
Returns the next value of the queue or a delay in milliseconds before the next value.
Returns the next value of the queue, or a delay, according to the given current time in milliseconds.
Alias for peek_event/1
.
Alias for peek_event/2
.
Returns the next event of the queue or a delay in milliseconds before the next value.
Returns the next event of the queue according to the given current time in milliseconds.
Extracts the next event in the queue or returns a delay.
Extracts the next event in the queue according to the given current time in milliseconds.
Alias for pop_event/1
.
Alias for pop_event/2
.
Extracts the next event in the queue with the current system time as now/0
.
Extracts the next event in the queue according to the given current time in milliseconds.
Returns the number of entries in the queue.
Provides a GenServer
compatible timeout from the queue.
Returns the time reference of a queue event. This reference is used as a key to identify a unique event.
Returns the value of a queue event.
Link to this section Types
Specs
Specs
event()
Specs
event_value() :: any()
Specs
peek_event_return() :: :empty | {:delay, tref(), non_neg_integer()} | {:ok, event()}
Specs
peek_return() :: :empty | {:delay, tref(), non_neg_integer()} | {:ok, event_value()}
Specs
pop_event_return() :: :empty | {:delay, tref(), non_neg_integer()} | {:ok, event(), t()}
Specs
pop_return() :: :empty | {:delay, tref(), non_neg_integer()} | {:ok, event_value(), t()}
Specs
t()
Specs
timespec() :: {pos_integer(), timespec_unit()}
Specs
timespec_unit() :: :ms | :second | :seconds | :minute | :minutes | :hour | :hours | :day | :days | :week | :weeks
Specs
timestamp_ms() :: pos_integer()
Specs
tref()
Specs
Link to this section Functions
Specs
Deletes an event from the queue and returns the new queue.
It accepts a time reference or a full event. When an event is given, its time reference will be used to find the event to delete, meaning the queue event will be deleted even if the value of the passed event was tampered.
The function does not fail if the event cannot be found and simply returns the queue as-is.
Specs
Deletes all entries from the queue whose values are equal to unwanted
.
Specs
enqueue(t(), ttl(), any()) :: enqueue_return()
Adds a new event to the queue with a TTL and the current system time as now/0
.
See enqueue/4
.
Specs
enqueue(t(), ttl(), any(), now :: integer()) :: enqueue_return()
Adds a new event to the queue with a TTL relative to the given timestamp in milliseconds.
Returns {:ok, tref, new_queue}
where tref
is a timer reference.
Specs
enqueue_abs(t(), end_time :: integer(), value :: any()) :: enqueue_return()
Adds a new event to the queue with an absolute timestamp.
Returns {:ok, tref, new_queue}
where tref
is a timer reference.
Specs
Returns a new queue with entries for whom the given callback returned a truthy value.
Use filter_val/2
to filter only using values.
Specs
Returns a new queue with entries for whom the given callback returned a truthy value.
Unlinke filter/2
, the callback is only passed the event value.
Specs
new() :: t()
Creates an empty time queue.
iex> tq = TimeQueue.new()
iex> TimeQueue.peek_event(tq)
:empty
Specs
now() :: integer()
This function is used internally to determine the current time when using
functions enqueue/3
, pop/1
, pop_event/1
and peek_event/1
.
It is a simple alias to :erlang.system_time(:millisecond)
. TimeQueue does
not use monotonic time since it already manages its own unique identifiers for
queue entries.
Specs
peek(t()) :: peek_return()
Returns the next value of the queue or a delay in milliseconds before the next value.
See peek/2
.
Specs
peek(t(), now :: timestamp_ms()) :: peek_return()
Returns the next value of the queue, or a delay, according to the given current time in milliseconds.
Just like pop/2
vs. pop_event/2
, peek
wil only return {:ok, value}
when a timeout is reached whereas peek_event
will return {:ok, event}
.
Specs
peek_entry(t()) :: peek_event_return()
Alias for peek_event/1
.
Specs
peek_entry(t(), now :: timestamp_ms()) :: peek_event_return()
Alias for peek_event/2
.
Specs
peek_event(t()) :: peek_event_return()
Returns the next event of the queue or a delay in milliseconds before the next value.
event values can be retrieved with TimeQueue.value/1
.
See peek_event/2
.
Specs
peek_event(t(), now :: timestamp_ms()) :: peek_event_return()
Returns the next event of the queue according to the given current time in milliseconds.
Possible return values are:
:empty
{:ok, event}
if the timestamp of the first event is<=
to the given current time.{:delay, tref, ms}
if the timestamp of the first event is>
to the given current time. The remaining amount of milliseconds is returned.
Example
iex> {:ok, tref, tq} = TimeQueue.new() |> TimeQueue.enqueue(100, :hello, _now = 0)
iex> {:delay, ^tref, 80} = TimeQueue.peek_event(tq, _now = 20)
iex> {:ok, _} = TimeQueue.peek_event(tq, _now = 100)
Specs
pop(t()) :: pop_return()
Extracts the next event in the queue or returns a delay.
See pop/2
.
Specs
pop(t(), now :: timestamp_ms()) :: pop_return()
Extracts the next event in the queue according to the given current time in milliseconds.
Much like pop_event/2
but the tuple returned when an event time is reached
(returns with :ok
) success will only contain the value inserted in the
queue.
Possible return values are:
:empty
{:ok, value, new_queue}
if the timestamp of the first event is<=
to the given current time. The event is deleted fromnew_queue
.{:delay, tref, ms}
if the timestamp of the first event is>
to the given current time. The remaining amount of milliseconds is returned.
Example
iex> {:ok, tref, tq} = TimeQueue.new() |> TimeQueue.enqueue(100, :hello, _now = 0)
iex> {:delay, ^tref, 80} = TimeQueue.pop(tq, _now = 20)
iex> {:ok, value, _} = TimeQueue.pop(tq, _now = 100)
iex> value
:hello
Specs
pop_entry(t()) :: pop_event_return()
Alias for pop_event/1
.
Specs
pop_entry(t(), now :: timestamp_ms()) :: pop_event_return()
Alias for pop_event/2
.
Specs
pop_event(t()) :: pop_event_return()
Extracts the next event in the queue with the current system time as now/0
.
See pop_event/2
.
Specs
pop_event(t(), now :: timestamp_ms()) :: pop_event_return()
Extracts the next event in the queue according to the given current time in milliseconds.
Possible return values are:
:empty
{:ok, event, new_queue}
if the timestamp of the first event is<=
to the given current time. The event is deleted fromnew_queue
.{:delay, tref, ms}
if the timestamp of the first event is>
to the given current time. The remaining amount of milliseconds is returned.
Example
iex> {:ok, tref, tq} = TimeQueue.new() |> TimeQueue.enqueue(100, :hello, _now = 0)
iex> {:delay, ^tref, 80} = TimeQueue.pop_event(tq, _now = 20)
iex> {:ok, event, _} = TimeQueue.pop_event(tq, _now = 100)
iex> TimeQueue.value(event)
:hello
Specs
Returns the number of entries in the queue.
Specs
timeout(t(), now :: timestamp_ms()) :: non_neg_integer() | :infinity
Provides a GenServer
compatible timeout from the queue.
Accepts the current time as a second argument or will default to the current system time.
Returns:
:infinity
when the queue is empty.0
when there the next event time has been reached.- The delay to the next event otherwise.
Specs
Returns the time reference of a queue event. This reference is used as a key to identify a unique event.
iex> tq = TimeQueue.new()
iex> {:ok, tref, tq} = TimeQueue.enqueue(tq, 10, :my_value)
iex> Process.sleep(10)
iex> {:ok, event} = TimeQueue.peek_event(tq)
iex> tref == TimeQueue.tref(event)
true
Specs
Returns the value of a queue event.
iex> tq = TimeQueue.new()
iex> {:ok, _, tq} = TimeQueue.enqueue(tq, 10, :my_value)
iex> Process.sleep(10)
iex> {:ok, event} = TimeQueue.peek_event(tq)
iex> TimeQueue.value(event)
:my_value