erlang: gen_server behaviour (+10 tests)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Has been cancelled
This commit is contained in:
@@ -814,3 +814,58 @@
|
||||
(er-mk-atom mod)
|
||||
(er-mk-atom name)))))
|
||||
(er-apply-fun (get mod-env name) vs)))))
|
||||
|
||||
;; ── gen_server (OTP-lite) ───────────────────────────────────────
|
||||
;; A minimal gen_server behaviour — `start_link/2`, `call/2`, `cast/2`,
|
||||
;; `stop/1`, plus the receive loop dispatching `Mod:handle_call/3`,
|
||||
;; `Mod:handle_cast/2`, `Mod:handle_info/2`. Loaded into the user
|
||||
;; module registry on demand via `(er-load-gen-server!)`.
|
||||
(define
|
||||
er-gen-server-source
|
||||
"-module(gen_server).
|
||||
start_link(Mod, Args) ->
|
||||
spawn(fun () ->
|
||||
case Mod:init(Args) of
|
||||
{ok, State} -> gen_server:loop(Mod, State);
|
||||
{stop, Reason} -> exit(Reason)
|
||||
end
|
||||
end).
|
||||
call(Pid, Req) ->
|
||||
Ref = make_ref(),
|
||||
Pid ! {'$gen_call', {self(), Ref}, Req},
|
||||
receive {Ref, Reply} -> Reply end.
|
||||
cast(Pid, Msg) ->
|
||||
Pid ! {'$gen_cast', Msg},
|
||||
ok.
|
||||
stop(Pid) ->
|
||||
gen_server:call(Pid, '$gen_stop').
|
||||
loop(Mod, State) ->
|
||||
receive
|
||||
{'$gen_call', {From, Ref}, '$gen_stop'} ->
|
||||
From ! {Ref, ok};
|
||||
{'$gen_call', {From, Ref}, Req} ->
|
||||
case Mod:handle_call(Req, From, State) of
|
||||
{reply, Reply, NewState} ->
|
||||
From ! {Ref, Reply},
|
||||
gen_server:loop(Mod, NewState);
|
||||
{noreply, NewState} ->
|
||||
gen_server:loop(Mod, NewState);
|
||||
{stop, Reason, Reply, NewState} ->
|
||||
From ! {Ref, Reply},
|
||||
exit(Reason)
|
||||
end;
|
||||
{'$gen_cast', Msg} ->
|
||||
case Mod:handle_cast(Msg, State) of
|
||||
{noreply, NewState} -> gen_server:loop(Mod, NewState);
|
||||
{stop, Reason, NewState} -> exit(Reason)
|
||||
end;
|
||||
Other ->
|
||||
case Mod:handle_info(Other, State) of
|
||||
{noreply, NewState} -> gen_server:loop(Mod, NewState);
|
||||
{stop, Reason, NewState} -> exit(Reason)
|
||||
end
|
||||
end.")
|
||||
|
||||
(define
|
||||
er-load-gen-server!
|
||||
(fn () (erlang-load-module er-gen-server-source)))
|
||||
|
||||
Reference in New Issue
Block a user