erlang: send_after to registered name + gen_server timeout returns (T5+T6, 771/771)
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 33s
T5 — send_after addresses a registered atom name; the delayed message
lands in that process's mailbox (destination resolved at fire time,
dead/unregistered targets drop silently).
T6 — gen_server loop now handles the {reply,R,S,T} / {noreply,S,T}
timeout-bearing callback returns by scheduling {timeout} to itself via
send_after; handle_info({timeout}, S) fires when no other message
arrives first. Sanity-checks the library hookup.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1265,8 +1265,15 @@
|
|||||||
{reply, Reply, NewState} ->
|
{reply, Reply, NewState} ->
|
||||||
From ! {Ref, Reply},
|
From ! {Ref, Reply},
|
||||||
gen_server:loop(Mod, NewState);
|
gen_server:loop(Mod, NewState);
|
||||||
|
{reply, Reply, NewState, Timeout} ->
|
||||||
|
From ! {Ref, Reply},
|
||||||
|
erlang:send_after(Timeout, self(), {timeout}),
|
||||||
|
gen_server:loop(Mod, NewState);
|
||||||
{noreply, NewState} ->
|
{noreply, NewState} ->
|
||||||
gen_server:loop(Mod, NewState);
|
gen_server:loop(Mod, NewState);
|
||||||
|
{noreply, NewState, Timeout} ->
|
||||||
|
erlang:send_after(Timeout, self(), {timeout}),
|
||||||
|
gen_server:loop(Mod, NewState);
|
||||||
{stop, Reason, Reply, NewState} ->
|
{stop, Reason, Reply, NewState} ->
|
||||||
From ! {Ref, Reply},
|
From ! {Ref, Reply},
|
||||||
exit(Reason)
|
exit(Reason)
|
||||||
@@ -1274,11 +1281,17 @@
|
|||||||
{'$gen_cast', Msg} ->
|
{'$gen_cast', Msg} ->
|
||||||
case Mod:handle_cast(Msg, State) of
|
case Mod:handle_cast(Msg, State) of
|
||||||
{noreply, NewState} -> gen_server:loop(Mod, NewState);
|
{noreply, NewState} -> gen_server:loop(Mod, NewState);
|
||||||
|
{noreply, NewState, Timeout} ->
|
||||||
|
erlang:send_after(Timeout, self(), {timeout}),
|
||||||
|
gen_server:loop(Mod, NewState);
|
||||||
{stop, Reason, NewState} -> exit(Reason)
|
{stop, Reason, NewState} -> exit(Reason)
|
||||||
end;
|
end;
|
||||||
Other ->
|
Other ->
|
||||||
case Mod:handle_info(Other, State) of
|
case Mod:handle_info(Other, State) of
|
||||||
{noreply, NewState} -> gen_server:loop(Mod, NewState);
|
{noreply, NewState} -> gen_server:loop(Mod, NewState);
|
||||||
|
{noreply, NewState, Timeout} ->
|
||||||
|
erlang:send_after(Timeout, self(), {timeout}),
|
||||||
|
gen_server:loop(Mod, NewState);
|
||||||
{stop, Reason, NewState} -> exit(Reason)
|
{stop, Reason, NewState} -> exit(Reason)
|
||||||
end
|
end
|
||||||
end.")
|
end.")
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"language": "erlang",
|
"language": "erlang",
|
||||||
"total_pass": 769,
|
"total_pass": 771,
|
||||||
"total": 769,
|
"total": 771,
|
||||||
"suites": [
|
"suites": [
|
||||||
{"name":"tokenize","pass":62,"total":62,"status":"ok"},
|
{"name":"tokenize","pass":62,"total":62,"status":"ok"},
|
||||||
{"name":"parse","pass":52,"total":52,"status":"ok"},
|
{"name":"parse","pass":52,"total":52,"status":"ok"},
|
||||||
@@ -14,6 +14,6 @@
|
|||||||
{"name":"fib","pass":8,"total":8,"status":"ok"},
|
{"name":"fib","pass":8,"total":8,"status":"ok"},
|
||||||
{"name":"ffi","pass":37,"total":37,"status":"ok"},
|
{"name":"ffi","pass":37,"total":37,"status":"ok"},
|
||||||
{"name":"vm","pass":78,"total":78,"status":"ok"},
|
{"name":"vm","pass":78,"total":78,"status":"ok"},
|
||||||
{"name":"send_after","pass":8,"total":8,"status":"ok"}
|
{"name":"send_after","pass":10,"total":10,"status":"ok"}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Erlang-on-SX Scoreboard
|
# Erlang-on-SX Scoreboard
|
||||||
|
|
||||||
**Total: 769 / 769 tests passing**
|
**Total: 771 / 771 tests passing**
|
||||||
|
|
||||||
| | Suite | Pass | Total |
|
| | Suite | Pass | Total |
|
||||||
|---|---|---|---|
|
|---|---|---|---|
|
||||||
@@ -15,7 +15,7 @@
|
|||||||
| ✅ | fib | 8 | 8 |
|
| ✅ | fib | 8 | 8 |
|
||||||
| ✅ | ffi | 37 | 37 |
|
| ✅ | ffi | 37 | 37 |
|
||||||
| ✅ | vm | 78 | 78 |
|
| ✅ | vm | 78 | 78 |
|
||||||
| ✅ | send_after | 8 | 8 |
|
| ✅ | send_after | 10 | 10 |
|
||||||
|
|
||||||
|
|
||||||
Generated by `lib/erlang/conformance.sh`.
|
Generated by `lib/erlang/conformance.sh`.
|
||||||
|
|||||||
@@ -118,3 +118,46 @@
|
|||||||
erlang:cancel_timer(Ref)")
|
erlang:cancel_timer(Ref)")
|
||||||
:name)
|
:name)
|
||||||
"false")
|
"false")
|
||||||
|
|
||||||
|
;; ── T5 — send_after to a registered atom name ──────────────────────
|
||||||
|
;; A second process registers itself as `srv`; the timer addresses it
|
||||||
|
;; by name, and the delayed message lands in that process's mailbox.
|
||||||
|
;; The server forwards what it got back to the parent for inspection.
|
||||||
|
(er-sa-test
|
||||||
|
"T5 timer delivers to registered name"
|
||||||
|
(get
|
||||||
|
(sa-ev
|
||||||
|
"Me = self(),
|
||||||
|
Pid = spawn(fun () -> receive M -> Me ! {got, M} end end),
|
||||||
|
register(srv, Pid),
|
||||||
|
erlang:send_after(20, srv, ping),
|
||||||
|
receive {got, X} -> X end")
|
||||||
|
:name)
|
||||||
|
"ping")
|
||||||
|
|
||||||
|
;; ── T6 — gen_server {noreply, State, Timeout} hookup ───────────────
|
||||||
|
;; A gen_server that, on the `arm` cast, returns {noreply, S, 100}.
|
||||||
|
;; The library schedules {timeout} to itself via send_after; when no
|
||||||
|
;; other message arrives first, handle_info({timeout}, S) fires. The
|
||||||
|
;; handler signals the parent so we can confirm the timeout landed.
|
||||||
|
(do
|
||||||
|
(er-load-gen-server!)
|
||||||
|
(erlang-load-module
|
||||||
|
"-module(sa_tmo).
|
||||||
|
init(Me) -> {ok, Me}.
|
||||||
|
handle_call(_R, _F, S) -> {reply, ok, S}.
|
||||||
|
handle_cast(arm, Me) -> {noreply, Me, 100}.
|
||||||
|
handle_info({timeout}, Me) -> Me ! fired, {noreply, Me};
|
||||||
|
handle_info(_M, S) -> {noreply, S}.")
|
||||||
|
nil)
|
||||||
|
|
||||||
|
(er-sa-test
|
||||||
|
"T6 gen_server timeout fires handle_info"
|
||||||
|
(get
|
||||||
|
(sa-ev
|
||||||
|
"Me = self(),
|
||||||
|
P = gen_server:start_link(sa_tmo, Me),
|
||||||
|
gen_server:cast(P, arm),
|
||||||
|
receive fired -> ok after 5000 -> timeout end")
|
||||||
|
:name)
|
||||||
|
"ok")
|
||||||
|
|||||||
Reference in New Issue
Block a user