github.com/rakyll/sessionlife


License
Apache-2.0
Install
go get github.com/rakyll/sessionlife

Documentation

sessionlife

A Go package for session lifecycle management on top of Valkey streams.

sessionlife provides a global Manager that tracks lifecycle events across sessions—such as resuming for a unit of work ("resume") or suspending when idle ("suspend"). It allows querying pending events and acknowledging completed work with Valkey streams.

Installation

go get github.com/rakyll/sessionlife

Quick Start

package main

import (
	"context"
	"fmt"
	"log"

	"github.com/rakyll/sessionlife"
	"github.com/valkey-io/valkey-go"
)

func main() {
	ctx := context.Background()

	client, err := valkey.NewClient(valkey.ClientOption{
		InitAddress: []string{"127.0.0.1:6379"},
	})
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	// 1. Create a global Manager
	m, err := sessionlife.NewManager(client)
	if err != nil {
		log.Fatal(err)
	}

	// 2. Queue lifecycle events across multiple sessions
	ev1, err := m.QueueResume(ctx, "session-A", "work-101")
	ev2, err := m.QueueResume(ctx, "session-B", "work-201")
	ev3, err := m.QueueSuspend(ctx, "session-A")

	// 3. Inspect currently pending events
	pending, err := m.Pending(ctx)
	for _, e := range pending {
		fmt.Printf("Pending: session=%s action=%s work=%s id=%s\n", e.SessionID, e.Action, e.WorkID, e.EntryID)
	}

	// 4. Acknowledge completed work
	if err := m.Ack(ctx, ev1.EntryID); err != nil {
		log.Fatal(err)
	}
	if err := m.Ack(ctx, ev2.EntryID); err != nil {
		log.Fatal(err)
	}

	// 5. Acknowledge suspend when processed
	_ = m.Ack(ctx, ev3.EntryID)
}

API Overview

Event

type Event struct {
	SessionID  string    `json:"session_id"`
	WorkID     string    `json:"work_id,omitempty"`
	Action     string    `json:"action"`
	EntryID    string    `json:"entry_id"`
	EnqueuedAt time.Time `json:"enqueued_at"`
}

Manager

Method Description
NewManager(client, opts...) Creates a new global session manager.
m.Queue(ctx, sessionID, action, workID...) Appends a lifecycle event ("resume", "suspend", etc.) to the session stream.
m.QueueResume(ctx, sessionID, workID) Convenience helper for Queue(ctx, sessionID, "resume", workID).
m.QueueSuspend(ctx, sessionID) Convenience helper for Queue(ctx, sessionID, "suspend").
m.Ack(ctx, entryID) Acknowledges and removes the event with the given stream entry ID. Idempotent.
m.Pending(ctx) Returns all currently unacknowledged events in chronological order.
m.Stream() Returns the Valkey stream key name used by the manager.

Options

  • WithPrefix(prefix string): Custom key prefix (default: "sessionlife").
  • WithStreamKey(key string): Explicit stream key name (default: "<prefix>:stream").

Keys Used

Everything lives under the configured prefix or stream key:

  • <prefix>:stream — Valkey stream containing pending lifecycle events (entries are deleted on Ack).

Tests

Tests run against an in-process miniredis by default:

go test -race ./...

To run against a real Valkey server:

VALKEY_ADDR=127.0.0.1:6379 go test -race ./...