Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 48s
Session is an Erlang process holding {subject, client, status}. lookup/
touch/expire/revoke are messages; expiry is the process's own
`receive ... after Ttl` timeout (RFC-agnostic; no global sweep), which
notifies the owner and tombstones. Tombstoned sessions answer lookups
with an explicit {error, expired|revoked}, never a silent dead mailbox.
Adds the conformance harness + scoreboard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
21 lines
2.8 KiB
Plaintext
21 lines
2.8 KiB
Plaintext
;; identity/session.sx — a session is an Erlang process.
|
|
;;
|
|
;; create = spawn a session process holding {subject, client, status}
|
|
;; lookup = a message; the live process answers {ok, ...} or {error, S}
|
|
;; expire = explicit message OR an idle timeout the process arms itself
|
|
;; revoke = explicit message; the grant tombstones immediately
|
|
;;
|
|
;; Expiry is the process's own `receive ... after Ttl` timeout, never a
|
|
;; global sweep. On timeout the process notifies its Owner and becomes a
|
|
;; tombstone that still answers lookups — with {error, expired}, never a
|
|
;; silent dead mailbox. A revoked or expired session is an explicit
|
|
;; negative state, not the absence of a positive one.
|
|
|
|
(define
|
|
identity-session-source
|
|
"-module(identity_session).\n\n start(SessionId, Subject, Client, Owner, Ttl) ->\n spawn(fun () -> active(SessionId, Subject, Client, Owner, Ttl) end).\n\n lookup(Pid) ->\n Pid ! {lookup, self()},\n receive {session_reply, R} -> R end.\n\n touch(Pid) ->\n Pid ! {touch, self()},\n receive {session_reply, R} -> R end.\n\n expire(Pid) ->\n Pid ! {expire, self()},\n receive {session_reply, R} -> R end.\n\n revoke(Pid) ->\n Pid ! {revoke, self()},\n receive {session_reply, R} -> R end.\n\n stop(Pid) ->\n Pid ! {stop, self()},\n receive {session_reply, R} -> R end.\n\n active(SessionId, Subject, Client, Owner, Ttl) ->\n receive\n {lookup, From} ->\n From ! {session_reply, {ok, {SessionId, Subject, Client, active}}},\n active(SessionId, Subject, Client, Owner, Ttl);\n {touch, From} ->\n From ! {session_reply, ok},\n active(SessionId, Subject, Client, Owner, Ttl);\n {expire, From} ->\n From ! {session_reply, ok},\n tombstone(SessionId, Subject, Client, expired);\n {revoke, From} ->\n From ! {session_reply, ok},\n tombstone(SessionId, Subject, Client, revoked);\n {stop, From} ->\n From ! {session_reply, ok}\n after Ttl ->\n Owner ! {session_expired, SessionId},\n tombstone(SessionId, Subject, Client, expired)\n end.\n\n tombstone(SessionId, Subject, Client, Status) ->\n receive\n {lookup, From} ->\n From ! {session_reply, {error, Status}},\n tombstone(SessionId, Subject, Client, Status);\n {touch, From} ->\n From ! {session_reply, {error, Status}},\n tombstone(SessionId, Subject, Client, Status);\n {expire, From} ->\n From ! {session_reply, ok},\n tombstone(SessionId, Subject, Client, Status);\n {revoke, From} ->\n From ! {session_reply, ok},\n tombstone(SessionId, Subject, Client, revoked);\n {stop, From} ->\n From ! {session_reply, ok}\n end.")
|
|
|
|
(define
|
|
identity-load-session!
|
|
(fn () (erlang-load-module identity-session-source)))
|