Packages

Context carries request scoped values and deadlines

Current section

Files

Jump to
ctx src ctx.erl
Raw

src/ctx.erl

-module(ctx).
-export([set/3,
get/2,
get/3,
deadline/2,
done/1,
with_value/2,
with_values/1,
with_deadline/1,
with_deadline_after/2]).
-export_type([ctx/0]).
-type ctx() :: #{values := #{term() => term()},
deadline => {timer:time(), timer:time()} | infinity}.
-spec set(ctx(), term(), term()) -> ctx().
set(Ctx=#{values := Values}, Key, Value) ->
Ctx#{values => maps:put(Key, Value, Values)}.
-spec get(ctx(), term()) -> ctx().
get(#{values := Values}, Key) ->
maps:get(Key, Values).
-spec get(ctx(), term(), term()) -> term().
get(#{values := Values}, Key, Default) ->
maps:get(Key, Values, Default).
-spec with_value(term(), term()) -> ctx().
with_value(Key, Value) ->
#{values => #{Key => Value}}.
-spec with_values(#{term() => term()}) -> ctx().
with_values(Values) ->
#{values => Values}.
-spec with_deadline(integer()) -> ctx().
with_deadline(Deadline) ->
#{values => #{},
deadline => Deadline}.
-spec with_deadline_after(integer(), erlang:time_unit()) -> ctx().
with_deadline_after(After, Unit) ->
with_deadline_after(#{values => #{}}, After, Unit).
-spec with_deadline_after(ctx(), integer(), erlang:time_unit()) -> ctx().
with_deadline_after(Ctx, After, Unit) ->
Ctx#{deadline => deadline(After, Unit)}.
done(#{deadline := {Deadline, _}}) ->
erlang:monotonic_time() =< Deadline;
done(_) ->
false.
%% internal
deadline(After, Unit) ->
Offset = erlang:time_offset(),
ConvertedTime = erlang:convert_time_unit(After, Unit, native),
{erlang:monotonic_time() + ConvertedTime, Offset}.
%% start_deadline_timer(Time) ->
%% erlang:start_timer(Time, self(), deadline_reached).