Class: Alplus::Session

Inherits:
Object
  • Object
show all
Defined in:
lib/alplus/session.rb

Overview

Request-scoped session-health tracker for AL+ Observe's crash-free sessions metric (issue #12). One request = one session, Sentry "request-mode" style: Alplus::RackMiddleware opens it, this class accumulates its outcome as the request runs, and the middleware closes it once @app.call returns (or raises).

State lives on Thread.current, exactly like Scope and for the same reason: a thread-pool server (Puma, Passenger) reuses OS threads across requests, so this must be reset per request rather than shared.

Three outcomes, in ascending severity, matching ARCHITECTURE.md's decision #2 (Sentry-aligned):

* `:healthy` -- the request completed with no captured error.
* `:errored` -- the request captured a handled error (any
`Alplus.capture_exception`/`capture_message` at level
`"error"`/`"fatal"`).
* `:crashed` -- the request raised an exception that propagated,
unhandled, up through `RackMiddleware`. Only this state counts
against crash-free sessions.

Severity only ever increases within one request: mark_errored is a no-op once mark_crashed has run (RackMiddleware's rescue calls Alplus.capture_exception for the crash itself, which would otherwise downgrade the outcome back to :errored).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeSession

Returns a new instance of Session.



59
60
61
62
63
# File 'lib/alplus/session.rb', line 59

def initialize
  @id = Id.generate_session_id
  @status = :healthy
  @started_at = Time.now.utc
end

Instance Attribute Details

#idObject (readonly)

Returns the value of attribute id.



57
58
59
# File 'lib/alplus/session.rb', line 57

def id
  @id
end

#started_atObject (readonly)

Returns the value of attribute started_at.



57
58
59
# File 'lib/alplus/session.rb', line 57

def started_at
  @started_at
end

#statusObject (readonly)

Returns the value of attribute status.



57
58
59
# File 'lib/alplus/session.rb', line 57

def status
  @status
end

Class Method Details

.currentObject

The current thread/fiber's session, or nil if none was started (e.g. outside RackMiddleware, such as a background job).



39
40
41
# File 'lib/alplus/session.rb', line 39

def current
  Thread.current[THREAD_KEY]
end

.with_clean_sessionObject

Replaces the current thread's session with a fresh one and yields; restores whatever session (if any) was active before, even if the block raises. RackMiddleware wraps each request in this so a session from request A never leaks into request B on a reused thread-pool thread.



48
49
50
51
52
53
54
# File 'lib/alplus/session.rb', line 48

def with_clean_session
  previous = Thread.current[THREAD_KEY]
  Thread.current[THREAD_KEY] = new
  yield
ensure
  Thread.current[THREAD_KEY] = previous
end

Instance Method Details

#mark_crashedObject

Marks the session :crashed. Terminal: never downgraded within one request.



71
72
73
# File 'lib/alplus/session.rb', line 71

def mark_crashed
  bump(:crashed)
end

#mark_erroredObject

Marks the session :errored, unless it is already :crashed.



66
67
68
# File 'lib/alplus/session.rb', line 66

def mark_errored
  bump(:errored)
end