-module(db_pool@internal@state). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/db_pool/internal/state.gleam"). -export([new/0, max_size/2, on_open/2, on_close/2, on_interval/2, interval/2, build/2, with_selector/2, current_size/1, queue_size/1, active_size/1, dequeue/5, current_connection/2, checkout/4, enqueue/6, expire/5, shutdown/1, ping/2, close/1]). -export_type([waiting/2, active/1, builder/2, state/3]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. ?MODULEDOC(false). -opaque waiting(FQZ, FRA) :: {waiting, gleam@erlang@process:pid_(), gleam@erlang@process:monitor(), gleam@erlang@process:subject({ok, FQZ} | {error, FRA}), gleam@erlang@process:timer()}. -opaque active(FRB) :: {active, FRB, gleam@erlang@process:monitor()}. -opaque builder(FRC, FRD) :: {builder, integer(), fun(() -> {ok, FRC} | {error, FRD}), fun((FRC) -> {ok, nil} | {error, FRD}), fun((FRC) -> nil), integer()}. -opaque state(FRE, FRF, FRG) :: {state, gleam@erlang@process:selector(FRF), integer(), integer(), fun(() -> {ok, FRE} | {error, FRG}), fun((FRE) -> {ok, nil} | {error, FRG}), fun((FRE) -> nil), integer(), list(FRE), gleam@dict:dict(gleam@erlang@process:pid_(), active(FRE)), db_pool@internal@queue:queue(integer(), waiting(FRE, FRG))}. -file("src/db_pool/internal/state.gleam", 38). ?DOC(false). -spec new() -> builder(any(), any()). new() -> {builder, 1, fun() -> erlang:error(#{gleam_error => panic, message => <<"(db_pool) on_open not configured"/utf8>>, file => <>, module => <<"db_pool/internal/state"/utf8>>, function => <<"new"/utf8>>, line => 41}) end, fun(_) -> {ok, nil} end, fun(_) -> nil end, 1000}. -file("src/db_pool/internal/state.gleam", 48). ?DOC(false). -spec max_size(builder(FRL, FRM), integer()) -> builder(FRL, FRM). max_size(State, Max_size) -> {builder, Max_size, erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State)}. -file("src/db_pool/internal/state.gleam", 52). ?DOC(false). -spec on_open(builder(FRR, FRS), fun(() -> {ok, FRR} | {error, FRS})) -> builder(FRR, FRS). on_open(State, Handle_open) -> {builder, erlang:element(2, State), Handle_open, erlang:element(4, State), erlang:element(5, State), erlang:element(6, State)}. -file("src/db_pool/internal/state.gleam", 59). ?DOC(false). -spec on_close(builder(FRZ, FSA), fun((FRZ) -> {ok, nil} | {error, FSA})) -> builder(FRZ, FSA). on_close(State, Handle_close) -> {builder, erlang:element(2, State), erlang:element(3, State), Handle_close, erlang:element(5, State), erlang:element(6, State)}. -file("src/db_pool/internal/state.gleam", 66). ?DOC(false). -spec on_interval(builder(FSH, FSI), fun((FSH) -> nil)) -> builder(FSH, FSI). on_interval(State, Handle_interval) -> {builder, erlang:element(2, State), erlang:element(3, State), erlang:element(4, State), Handle_interval, erlang:element(6, State)}. -file("src/db_pool/internal/state.gleam", 73). ?DOC(false). -spec interval(builder(FSN, FSO), integer()) -> builder(FSN, FSO). interval(State, Interval) -> {builder, erlang:element(2, State), erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), Interval}. -file("src/db_pool/internal/state.gleam", 101). ?DOC(false). -spec build(builder(FST, FSU), gleam@erlang@process:selector(FSX)) -> {ok, state(FST, FSX, FSU)} | {error, binary()}. build(Builder, Selector) -> Connections = begin _pipe = gleam@list:repeat(<<""/utf8>>, erlang:element(2, Builder)), _pipe@1 = gleam@list:try_map( _pipe, fun(_) -> (erlang:element(3, Builder))() end ), gleam@result:map_error( _pipe@1, fun(_) -> <<"(db_pool) Failed to open connections"/utf8>> end ) end, gleam@result:map( Connections, fun(Idle) -> {state, Selector, erlang:element(2, Builder), erlang:element(2, Builder), erlang:element(3, Builder), erlang:element(4, Builder), erlang:element(5, Builder), erlang:element(6, Builder), Idle, maps:new(), db_pool@internal@queue:new(<<"db_pool_queue"/utf8>>)} end ). -file("src/db_pool/internal/state.gleam", 127). ?DOC(false). -spec with_selector( state(any(), FTF, any()), fun((gleam@erlang@process:selector(FTF)) -> FTL) ) -> FTL. with_selector(State, Next) -> Next(erlang:element(2, State)). -file("src/db_pool/internal/state.gleam", 134). ?DOC(false). -spec current_size(state(any(), any(), any())) -> integer(). current_size(State) -> erlang:element(4, State). -file("src/db_pool/internal/state.gleam", 138). ?DOC(false). -spec queue_size(state(any(), any(), any())) -> integer(). queue_size(State) -> _pipe = db_pool@internal@queue:size(erlang:element(11, State)), gleam@result:unwrap(_pipe, 0). -file("src/db_pool/internal/state.gleam", 142). ?DOC(false). -spec active_size(state(any(), any(), any())) -> integer(). active_size(State) -> maps:size(erlang:element(10, State)). -file("src/db_pool/internal/state.gleam", 146). ?DOC(false). -spec with_active( state(FUE, FUF, FUG), gleam@erlang@process:pid_(), fun((active(FUE)) -> state(FUE, FUF, FUG)) ) -> state(FUE, FUF, FUG). with_active(State, Caller, Next) -> _pipe = gleam_stdlib:map_get(erlang:element(10, State), Caller), _pipe@1 = gleam@result:map(_pipe, Next), gleam@result:unwrap(_pipe@1, State). -file("src/db_pool/internal/state.gleam", 156). ?DOC(false). -spec dequeue( state(FUR, FUS, FUT), gleam@option:option(FUR), gleam@erlang@process:pid_(), fun((gleam@erlang@process:down()) -> FUS), fun((gleam@erlang@process:subject({ok, FUR} | {error, FUT}), FUR) -> nil) ) -> state(FUR, FUS, FUT). dequeue(State, Conn, Caller, Mapping, Handler) -> with_active( State, Caller, fun(Prev) -> gleam@option:map( Conn, fun(Conn@1) -> _assert_subject = erlang:element(2, Prev), case _assert_subject =:= Conn@1 of true -> nil; false -> erlang:error(#{gleam_error => assert, message => <<"Assertion failed."/utf8>>, file => <>, module => <<"db_pool/internal/state"/utf8>>, function => <<"dequeue"/utf8>>, line => 166, kind => binary_operator, operator => '==', left => #{kind => expression, value => _assert_subject, start => 4076, 'end' => 4085 }, right => #{kind => expression, value => Conn@1, start => 4089, 'end' => 4093 }, start => 4069, 'end' => 4093, expression_start => 4076}) end end ), _pipe@4 = begin gleam@result:'try'( db_pool@internal@queue:first_lookup( erlang:element(11, State) ), fun(_use0) -> {Time_sent, Waiting} = _use0, gleam@result:map( db_pool@internal@queue:delete_key( erlang:element(11, State), Time_sent ), fun(_) -> Monitor = gleam@erlang@process:monitor( erlang:element(2, Waiting) ), Next = {active, erlang:element(2, Prev), Monitor}, Active = begin _pipe = erlang:element(10, State), _pipe@1 = gleam@dict:delete(_pipe, Caller), gleam@dict:insert( _pipe@1, erlang:element(2, Waiting), Next ) end, gleam@erlang@process:cancel_timer( erlang:element(5, Waiting) ), gleam@erlang@process:demonitor_process( erlang:element(3, Prev) ), Selector = begin _pipe@2 = erlang:element(2, State), _pipe@3 = gleam@erlang@process:deselect_specific_monitor( _pipe@2, erlang:element(3, Prev) ), gleam@erlang@process:select_specific_monitor( _pipe@3, erlang:element(3, Next), Mapping ) end, State@1 = {state, Selector, erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), erlang:element(9, State), Active, erlang:element(11, State)}, Handler( erlang:element(4, Waiting), erlang:element(2, Prev) ), State@1 end ) end ) end, gleam@result:lazy_unwrap( _pipe@4, fun() -> Idle = gleam@list:prepend( erlang:element(9, State), erlang:element(2, Prev) ), {state, erlang:element(2, State), erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), Idle, erlang:element(10, State), erlang:element(11, State)} end ) end ). -file("src/db_pool/internal/state.gleam", 256). ?DOC(false). -spec current_connection(state(FVP, any(), any()), gleam@erlang@process:pid_()) -> {ok, FVP} | {error, nil}. current_connection(State, Caller) -> _pipe = gleam_stdlib:map_get(erlang:element(10, State), Caller), gleam@result:map(_pipe, fun(Active) -> erlang:element(2, Active) end). -file("src/db_pool/internal/state.gleam", 202). ?DOC(false). -spec checkout( state(FVE, FVF, FVG), gleam@erlang@process:pid_(), fun((gleam@erlang@process:down()) -> FVF), fun((FVE) -> nil) ) -> {ok, state(FVE, FVF, FVG)} | {error, nil}. checkout(State, Caller, Handle_down, Next) -> _pipe = current_connection(State, Caller), _pipe@1 = gleam@result:map( _pipe, fun(Conn) -> Next(Conn), State end ), gleam@result:lazy_or(_pipe@1, fun() -> case erlang:element(9, State) of [] when erlang:element(4, State) < erlang:element(3, State) -> _pipe@2 = (erlang:element(5, State))(), _pipe@4 = gleam@result:map( _pipe@2, fun(Conn@1) -> Next(Conn@1), Monitor = gleam@erlang@process:monitor(Caller), Activated = {active, Conn@1, Monitor}, Active = gleam@dict:insert( erlang:element(10, State), Caller, Activated ), Selector = begin _pipe@3 = erlang:element(2, State), gleam@erlang@process:select_specific_monitor( _pipe@3, erlang:element(3, Activated), Handle_down ) end, {state, Selector, erlang:element(3, State), erlang:element(4, State) + 1, erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), erlang:element(9, State), Active, erlang:element(11, State)} end ), gleam@result:replace_error(_pipe@4, nil); [] -> {error, nil}; [Conn@2 | Idle] -> Next(Conn@2), Monitor@1 = gleam@erlang@process:monitor(Caller), Activated@1 = {active, Conn@2, Monitor@1}, Active@1 = gleam@dict:insert( erlang:element(10, State), Caller, Activated@1 ), Selector@1 = begin _pipe@5 = erlang:element(2, State), gleam@erlang@process:select_specific_monitor( _pipe@5, erlang:element(3, Activated@1), Handle_down ) end, {ok, {state, Selector@1, erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), Idle, Active@1, erlang:element(11, State)}} end end). -file("src/db_pool/internal/state.gleam", 264). ?DOC(false). -spec enqueue( state(FVX, FVY, FVZ), gleam@erlang@process:pid_(), gleam@erlang@process:subject({ok, FVX} | {error, FVZ}), integer(), fun((integer(), integer()) -> FVY), fun((gleam@erlang@process:down()) -> FVY) ) -> state(FVX, FVY, FVZ). enqueue(State, Caller, Client, Timeout, Handle_timeout, Handle_down) -> Now_in_ms = db_pool@internal:now_in_ms(), Subject = gleam@erlang@process:new_subject(), Timer = gleam@erlang@process:send_after( Subject, Timeout, Handle_timeout(Now_in_ms, Timeout) ), Monitor = gleam@erlang@process:monitor(Caller), Waiting = {waiting, Caller, Monitor, Client, Timer}, case db_pool@internal@queue:insert( erlang:element(11, State), Now_in_ms, Waiting ) of {ok, nil} -> nil; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"db_pool/internal/state"/utf8>>, function => <<"enqueue"/utf8>>, line => 280, value => _assert_fail, start => 7035, 'end' => 7101, pattern_start => 7046, pattern_end => 7053}) end, Selector = begin _pipe = erlang:element(2, State), _pipe@1 = gleam@erlang@process:select(_pipe, Subject), gleam@erlang@process:select_specific_monitor( _pipe@1, erlang:element(3, Waiting), Handle_down ) end, {state, Selector, erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), erlang:element(9, State), erlang:element(10, State), erlang:element(11, State)}. -file("src/db_pool/internal/state.gleam", 290). ?DOC(false). -spec expire( state(FWJ, FWK, FWL), integer(), integer(), fun((gleam@erlang@process:subject({ok, FWJ} | {error, FWL})) -> nil), fun((integer(), integer()) -> FWK) ) -> state(FWJ, FWK, FWL). expire(State, Sent, Timeout, Next, Extend) -> _pipe = db_pool@internal@queue:lookup(erlang:element(11, State), Sent), _pipe@1 = gleam@result:map( _pipe, fun(Waiting) -> Now = db_pool@internal:now_in_ms(), gleam@bool:lazy_guard( (Now < (Sent + Timeout)), fun() -> gleam@erlang@process:cancel_timer( erlang:element(5, Waiting) ), Subject = gleam@erlang@process:new_subject(), Timer = gleam@erlang@process:send_after( Subject, Timeout, Extend(Sent, Timeout) ), case db_pool@internal@queue:insert( erlang:element(11, State), Sent, {waiting, erlang:element(2, Waiting), erlang:element(3, Waiting), erlang:element(4, Waiting), Timer} ) of {ok, nil} -> nil; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"db_pool/internal/state"/utf8>>, function => <<"expire"/utf8>>, line => 307, value => _assert_fail, start => 7828, 'end' => 7916, pattern_start => 7839, pattern_end => 7846}) end, Selector = gleam@erlang@process:select( erlang:element(2, State), Subject ), {state, Selector, erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), erlang:element(9, State), erlang:element(10, State), erlang:element(11, State)} end, fun() -> case db_pool@internal@queue:delete_key( erlang:element(11, State), Sent ) of {ok, nil} -> nil; _assert_fail@1 -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"db_pool/internal/state"/utf8>>, function => <<"expire"/utf8>>, line => 315, value => _assert_fail@1, start => 8024, 'end' => 8080, pattern_start => 8035, pattern_end => 8042}) end, Next(erlang:element(4, Waiting)), gleam@erlang@process:cancel_timer( erlang:element(5, Waiting) ), gleam@erlang@process:demonitor_process( erlang:element(3, Waiting) ), Selector@1 = gleam@erlang@process:deselect_specific_monitor( erlang:element(2, State), erlang:element(3, Waiting) ), {state, Selector@1, erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), erlang:element(9, State), erlang:element(10, State), erlang:element(11, State)} end ) end ), gleam@result:unwrap(_pipe@1, State). -file("src/db_pool/internal/state.gleam", 330). ?DOC(false). -spec shutdown(state(any(), any(), any())) -> nil. shutdown(State) -> case maps:size(erlang:element(10, State)) of 0 -> gleam@list:each(erlang:element(9, State), erlang:element(6, State)); _ -> nil end. -file("src/db_pool/internal/state.gleam", 337). ?DOC(false). -spec ping(state(FXB, FXC, FXD), FXC) -> state(FXB, FXC, FXD). ping(State, Message) -> gleam@list:each(erlang:element(9, State), erlang:element(7, State)), Subject = gleam@erlang@process:new_subject(), _ = gleam@erlang@process:send_after( Subject, erlang:element(8, State), Message ), Selector = gleam@erlang@process:select(erlang:element(2, State), Subject), {state, Selector, erlang:element(3, State), erlang:element(4, State), erlang:element(5, State), erlang:element(6, State), erlang:element(7, State), erlang:element(8, State), erlang:element(9, State), erlang:element(10, State), erlang:element(11, State)}. -file("src/db_pool/internal/state.gleam", 349). ?DOC(false). -spec close(state(any(), any(), any())) -> nil. close(State) -> case gleam@list:try_each(erlang:element(9, State), erlang:element(6, State)) of {ok, nil} -> nil; _assert_fail -> erlang:error(#{gleam_error => let_assert, message => <<"Pattern match failed, no pattern matched the value."/utf8>>, file => <>, module => <<"db_pool/internal/state"/utf8>>, function => <<"close"/utf8>>, line => 350, value => _assert_fail, start => 8894, 'end' => 8960, pattern_start => 8905, pattern_end => 8912}) end, nil.