-module(sprocket@internal@utils@timer). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([timer/2, interval/2, now/0, convert_time_unit/3, timed_operation/2]). -export_type([timer_msg/0, timed_operation/0, time_unit/0]). -type timer_msg() :: cancel | {timeout, fun(() -> nil)} | {interval, gleam@erlang@process:subject(timer_msg()), integer(), fun(() -> nil)}. -type timed_operation() :: {timed_operation, binary(), integer()}. -type time_unit() :: native | microsecond. -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 17). -spec handle_timer_message(timer_msg(), integer()) -> gleam@otp@actor:next(timer_msg(), integer()). handle_timer_message(Msg, State) -> case Msg of cancel -> {stop, normal}; {timeout, Cb} -> Cb(), {stop, normal}; {interval, Actor, Interval_ms, Cb@1} -> Cb@1(), gleam@erlang@process:send_after( Actor, Interval_ms, {interval, Actor, Interval_ms, Cb@1} ), gleam@otp@actor:continue(State) end. -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 37). -spec timer(integer(), fun(() -> nil)) -> gleam@erlang@process:timer(). timer(Interval_ms, Callback) -> _assert_subject = begin _pipe = gleam@otp@actor:start(Interval_ms, fun handle_timer_message/2), gleam@result:map_error( _pipe, fun(Error) -> sprocket@internal@logger:error( <<"timer.timer: failed to start timer actor"/utf8>> ), Error end ) end, {ok, Actor} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"sprocket/internal/utils/timer"/utf8>>, function => <<"timer"/utf8>>, line => 38}) end, gleam@erlang@process:send_after(Actor, Interval_ms, {timeout, Callback}). -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 49). -spec interval(integer(), fun(() -> nil)) -> fun(() -> nil). interval(Interval_ms, Callback) -> _assert_subject = begin _pipe = gleam@otp@actor:start(Interval_ms, fun handle_timer_message/2), gleam@result:map_error( _pipe, fun(Error) -> sprocket@internal@logger:error( <<"timer.interval: failed to start timer actor"/utf8>> ), Error end ) end, {ok, Actor} = case _assert_subject of {ok, _} -> _assert_subject; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, value => _assert_fail, module => <<"sprocket/internal/utils/timer"/utf8>>, function => <<"interval"/utf8>>, line => 50}) end, gleam@erlang@process:send_after( Actor, Interval_ms, {interval, Actor, Interval_ms, Callback} ), fun() -> gleam@otp@actor:send(Actor, cancel) end. -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 102). -spec now() -> integer(). now() -> erlang:monotonic_time(). -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 75). -spec begin_timed_operation(binary()) -> timed_operation(). begin_timed_operation(Label) -> sprocket@internal@logger:debug( gleam@string:concat([<<"Starting "/utf8>>, Label, <<"..."/utf8>>]) ), {timed_operation, Label, erlang:monotonic_time()}. -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 105). -spec convert_time_unit(integer(), time_unit(), time_unit()) -> integer(). convert_time_unit(A, B, C) -> erlang:convert_time_unit(A, B, C). -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 81). -spec complete_timed_operation(timed_operation()) -> integer(). complete_timed_operation(Op) -> Elapsed = erlang:convert_time_unit( erlang:monotonic_time() - erlang:element(3, Op), native, microsecond ), Formatted_elapsed = case Elapsed > 1000 of true -> gleam@string:append( erlang:integer_to_binary(Elapsed div 1000), <<"ms"/utf8>> ); false -> gleam@string:append( erlang:integer_to_binary(Elapsed), <<"µs"/utf8>> ) end, _pipe = gleam@string:concat( [erlang:element(2, Op), <<" completed in "/utf8>>, Formatted_elapsed] ), sprocket@internal@logger:debug(_pipe), Elapsed. -file("/home/runner/work/sprocket/sprocket/src/sprocket/internal/utils/timer.gleam", 63). -spec timed_operation(binary(), fun(() -> KMI)) -> KMI. timed_operation(Label, Cb) -> Op_timer = begin_timed_operation(Label), Result = Cb(), complete_timed_operation(Op_timer), Result.