Repository navigation
Emit session_end when a console session exits normally - #5
Merged
Merged
Conversation
grantcox
marked this pull request as ready for review
August 27, 2026 03:55
grantcox
enabled auto-merge
August 27, 2026 03:58
console1984 reaches finish_session only through Supervisor#stop, which only exit_irb calls, which CommandExecutor only calls after a forbidden command has executed. A session ended with a plain `exit` was therefore never closed: no session_end record, and command_count and duration_seconds existed for effectively no real session. Upstream does not notice because its own Database logger treats finish_session as in-memory cleanup -- the session row and its commands are already persisted, so nothing is lost if it never runs. We hung a record emission off the same hook, which does need it to fire. start_session now arms the close with at_exit. The two paths are safe together: whichever runs first clears @session_id and emit drops any later event without one. The existing spec called finish_session directly, so the unit behaviour was correct while the integration never happened. The new specs drive the registered handler instead, and one pins the duck-type name that console1984 calls on exit so a rename fails here rather than silently taking out both paths. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
grantcox
force-pushed
the
stagility/session-end-at-exit
branch
from
August 27, 2026 07:44
81fb292 to
71a3226
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug
session_endis effectively never emitted. In console1984 0.2.4 the only path tofinish_sessionis:There is no
at_exit, noENDblock, no trap, and nothing hooks IRB's normal exit. So a session ended withexit— which is every ordinary session — is never closed, andcommand_count/duration_secondsare populated for effectively no real session.Upstream doesn't hit this because
Console1984::SessionsLogger::Database#finish_sessionjust nils out two ivars. If it never runs, nothing is lost: the session row and its commands are already in the database. We hung a record emission off the same hook, which does depend on it firing.Found while writing the manual acceptance plan for v1.0.0 — the plan asserted a
session_endfor a normal console session and it wasn't there.The fix
start_sessionarms the close withat_exit. Registering insidestart_sessionrather than in the Railtie keeps it self-limiting: it only arms for a real interactive session, and never forrake/rails runner/ web / worker.The two paths are safe together. Whichever runs first clears
@session_id, andemit's existing nil-session guard drops any later event without one — so the forbidden-command path still emits exactly onesession_end, and theat_exitis then a no-op.Why the specs didn't catch it
spec/console_audit/sessions_logger_spec.rbcalledlogger.finish_sessiondirectly. The unit behaviour was correct; the integration never happened. The new specs drive the registered handler instead, and one pins the duck-type name console1984 calls on exit, so an upstream rename fails here rather than silently taking out both paths.Confirmed the three behavioural specs fail without the
lib/change.Limits
heroku ps:stop, or the dyno being reaped) still produces nosession_end. Nothing in-process can fix that; thesession_startandcommandrecords are already durable, which is the property that matters.at_exithandlers run LIFO. This one is registered at console start, well after Rails' boot-time handlers, so it runs before them and the queue backend should still be connected. If an enqueue does fail there it's fail-open and warns, which is the pre-existing behaviour for every other record.Replaces #3, which was merged into
add-ciafteradd-cihad already merged tomain, so the commit never landed. Same single commit (81fb292), retargeted atmain.