session

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 13, 2026 License: AGPL-3.0 Imports: 21 Imported by: 0

Documentation

Overview

Package session manages the lifecycle of OpenJD sessions on the worker.

A Session is the ephemeral execution context within which one or more tasks from the same job step run. It provides:

  • An isolated working directory under <data_dir>/sessions/<session_id>/
  • Ordered environment entry (OnEnter actions run in declaration order)
  • Ordered environment exit (OnExit actions run in reverse order)
  • Safe concurrent task tracking via AddTask / RemoveTask

Session identity

Session IDs are worker-generated UUIDs. The ID is included in every protocol.TaskStatusMsg and protocol.LogChunkMsg published from within the session so the server can group task attempts by session for debugging (consistent with the session_id column on task_attempts; see docs/architecture.md, "SQLite schema overview").

Phase 1 scope

In Phase 1, sessions are not stored as database rows — they are worker-side runtime constructs. The server records the session ID only on task_attempts. A dedicated sessions table (for session-reuse scheduling) is deferred to Phase 2; see docs/architecture.md ("SQLite schema overview").

Usage

mgr := session.NewManager(cfg.Worker.DataDir, cfg.Worker.KeepFailedSessions, logger)

s, err := mgr.Create(ctx, assignMsg)
if err != nil { ... }
defer mgr.Cleanup(ctx, s, true) // true = "failed" path; use false on success

// Execute tasks within s.WorkDir, using s.ID as the SessionID in status messages.
s.AddTask(taskID)
// ... run task process ...
s.RemoveTask(taskID)

// On session end:
if err := s.ExitEnvironments(ctx, logger); err != nil { ... }
mgr.Cleanup(ctx, s, failed)

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Manager

type Manager struct {
	// contains filtered or unexported fields
}

Manager creates and cleans up sessions. A single Manager is constructed once at worker startup and shared by the executor for the process lifetime.

func NewManager

func NewManager(dataDir string, keepFailedSessions bool, logger *slog.Logger) *Manager

NewManager returns a Manager that stores session working directories under <dataDir>/sessions/. keepFailedSessions controls whether working directories for failed sessions are retained for post-mortem inspection.

func (*Manager) Cleanup

func (m *Manager) Cleanup(ctx context.Context, s *Session, failed bool)

Cleanup exits any remaining environments (if ExitEnvironments has not been called already) and removes the session's working directory.

If failed is true and keepFailedSessions is set, the working directory is retained and a message is logged so the operator can inspect it.

Cleanup logs all errors but does not return them so it can be called safely in deferred cleanup chains. Do not use the session after Cleanup returns.

func (*Manager) Create

func (m *Manager) Create(ctx context.Context, msg *protocol.AssignMsg) (*Session, error)

Create allocates a new Session for the given assignment: generates a UUID as the session ID, creates the working directory under <data_dir>/sessions/<session_id>/, and enters each environment in declaration order.

If any OnEnter action fails, already-entered environments are exited in reverse order and the working directory is removed before the error is returned. Create always returns either a ready-to-use session and nil error, or nil and a non-nil error — never both.

On success the returned Session is ready for task execution.

type Session

type Session struct {
	// ID is the worker-generated unique identifier for this session.
	// Callers MUST include this in every [protocol.TaskStatusMsg] (as
	// SessionID) and every [protocol.LogChunkMsg] published from within
	// the session so the server can group attempts by session.
	ID string

	// WorkDir is the absolute path to the session's isolated working directory,
	// created by [Manager.Create] and removed by [Manager.Cleanup].
	// Commands launched within the session run with this as their cwd so that
	// relative file references resolve correctly.
	WorkDir string

	// JobID is the ID of the job that owns this session.
	JobID string

	// CreatedAt is the wall-clock time the session was created.
	CreatedAt time.Time
	// contains filtered or unexported fields
}

Session is the ephemeral execution context for one or more tasks from the same job step. Obtain one via Manager.Create; end it by calling Session.ExitEnvironments followed by Manager.Cleanup.

Session is safe for concurrent use. Multiple tasks may execute within a single session simultaneously.

func (*Session) ActiveTaskCount

func (s *Session) ActiveTaskCount() int

ActiveTaskCount returns the number of tasks currently executing within this session. Safe for concurrent use.

func (*Session) ActiveTaskIDs

func (s *Session) ActiveTaskIDs() []string

ActiveTaskIDs returns a snapshot of the task IDs currently executing within this session. Safe for concurrent use.

func (*Session) AddTask

func (s *Session) AddTask(taskID string)

AddTask records taskID as executing within this session. Called by the executor when a task process is launched.

func (*Session) EnvOverrides

func (s *Session) EnvOverrides() map[string]string

EnvOverrides returns a snapshot of the environment variables accumulated from openjd_env / openjd_redacted_env directives, for callers (e.g. the executor's task-env construction) that must apply them on top of the task's static environment. Returns nil when no directives have set any variables.

func (*Session) EnvUnset

func (s *Session) EnvUnset() map[string]bool

EnvUnset returns a snapshot of the variables removed via openjd_unset_env, for callers that must strip them from a subsequent action's environment. Returns nil when no variables have been unset.

func (*Session) ExitEnvironments

func (s *Session) ExitEnvironments(ctx context.Context, logger *slog.Logger) error

ExitEnvironments runs each entered environment's OnExit action in reverse entry order, ensuring host state is restored predictably regardless of session outcome.

All teardown actions are attempted even if an earlier one fails. Errors from individual OnExit actions are logged as warnings, collected, and the first error encountered is returned.

ExitEnvironments is idempotent: after it is called the first time the entered-environments list is cleared, so subsequent calls are no-ops. Manager.Cleanup always calls ExitEnvironments, so callers that invoke it explicitly beforehand (e.g., on the cancellation path) do not need to skip the Cleanup call — the second invocation will be a safe no-op.

func (*Session) HasPathMappingRules

func (s *Session) HasPathMappingRules() bool

HasPathMappingRules reports whether the assignment carried any path-mapping rules. Exposed to format strings as Session.HasPathMappingRules.

func (*Session) PathMappingRulesFile

func (s *Session) PathMappingRulesFile() string

PathMappingRulesFile returns the absolute path to the OpenJD path-mapping file written into the session working directory, or "" when the assignment carried no path-mapping rules. Exposed to format strings as Session.PathMappingRulesFile.

func (*Session) RemoveTask

func (s *Session) RemoveTask(taskID string)

RemoveTask removes taskID from the active task list. Called by the executor when a task process exits. If taskID is not present the call is a no-op.

func (*Session) ScrubRedacted

func (s *Session) ScrubRedacted(line string) string

ScrubRedacted replaces any value registered via openjd_redacted_env in line with the redaction placeholder. It is the exported, concurrency-safe entry point the executor applies to every TASK stdout/stderr line: a step inherits redacted variables in its environment, so a command that echoes one (e.g. `echo $SECRET`) would otherwise publish the cleartext value to the log stream. Returns line unchanged when no redacted values are registered.

func (*Session) StaticEnv

func (s *Session) StaticEnv() map[string]string

StaticEnv returns a snapshot of the merged, fully-resolved static environment from all environments' Variables (see the staticEnv field). The executor uses it as the base environment for the task, on top of which the session's dynamic env (openjd_env directives) is applied. Returns nil when no environment sets any variable. The returned map is a clone; callers may mutate it freely.

func (*Session) WriteEmbeddedFiles

func (s *Session) WriteEmbeddedFiles(files []protocol.EmbeddedFile) error

WriteEmbeddedFiles materializes files into the session working directory. It is called by the executor before running the step OnRun action so that step-level embedded files are available to the task command.

Each file's Runnable flag is honored (execute permission set) and its EndOfLine value is applied before writing. Returns an error naming the first file that could not be written, which the caller should use to fail the task via the established pre-execution failure path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL