Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

feat(routing): share session affinity across gateway replicas

Open
#136 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
5/5
Estimated time
Over a week
Newbie friendliness
25/100
Issue type
Feature
Clarity
Mostly clear
Activity status
Active
Tech stack
redis, rust

Research direction

Start by reading Praxis's request-selection and current in-memory affinity paths, then inspect Grid's routing overlay and Helm/Forge-backed qualification setup. Define the shared-store binding and failure semantics before implementation; done means deterministic tests cover replica sharing, eligibility changes, expiry, outage and recovery, plus Grid qualification evidence that does not expose session values.

Written by the indexing model from the issue text.

Description

enhancement triage/accepted

Problem

Praxis can keep a session on the same provider by reading a configured request header or cookie and storing a provider binding in memory. The binding expires after a configurable TTL, and Praxis replaces it when the selected provider is no longer eligible.

Because this state is local to one Praxis process, affinity is lost when later requests reach another gateway replica or when the original replica restarts. Horizontally scaling a consumer gateway can therefore move one conversation between providers, reducing conversation continuity and KV-cache locality.

Desired behavior

Add an optional shared affinity store backed by Valkey or Redis-compatible storage so every replica of a logical consumer gateway resolves the same session to the same stable provider candidate.

The binding should remain advisory rather than overriding routing safety: health, authorization, admission, provider removal, and hard policy constraints must still be able to invalidate it. A provider in existing_only should remain eligible for a session already bound to it but must not receive a new session.

Architecture considerations

  • Use the provider candidate's stable identity, not a pod address or list position.
  • Namespace bindings by the logical gateway or routing scope so unrelated gateways and tenants cannot collide.
  • Store only an opaque hash of the session identifier; do not put raw cookies, conversation IDs, credentials, or request content in keys, logs, or metrics.
  • Apply a configurable idle TTL and refresh it only according to a documented access policy.
  • Make concurrent first-request binding deterministic or atomic so replicas do not establish conflicting bindings.
  • Define atomic compare-and-replace behavior when a bound provider becomes ineligible.
  • Preserve current in-memory affinity as the default for backward compatibility.
  • Define explicit behavior when Valkey is unavailable. Do not silently claim shared affinity while using divergent replica-local bindings.
  • Keep shared affinity out of Grid's CRDT/SWIM state; this is request-path data-plane state, not converged Grid control-plane state.

Grid integration

Grid should continue publishing stable candidate identities and admission states in the routing overlay. Praxis owns lookup and mutation of the affinity binding during request selection. Grid's responsibility is to provide a qualification topology and prove that drain, failure, restoration, and overlay changes interact correctly with shared bindings.

Acceptance criteria

  • Two Praxis replicas configured with the same shared store route one session to the same stable provider when requests alternate between replicas.
  • Different session identifiers can be distributed normally across eligible providers.
  • Restarting either gateway replica does not lose the shared binding.
  • A provider in existing_only continues serving sessions already bound to it but receives no new sessions.
  • An unhealthy, removed, unauthorized, or none provider causes a bounded rebind to an eligible provider.
  • Concurrent first requests for one session cannot leave conflicting bindings.
  • Binding expiry and refresh behavior are covered with deterministic tests.
  • Valkey/Redis outage and recovery behavior is explicit, observable, and tested.
  • Raw session identifiers and credentials do not appear in storage keys, metrics, logs, or qualification evidence.
  • Existing deployments without a shared-store configuration retain the current in-memory behavior.
  • A Helm/Forge-backed Grid qualification exercises two gateway replicas, at least two providers, restart persistence, drain, provider failure, expiry, and store outage/recovery.
  • Evidence records the serving overlay revision and opaque binding/provider identities without exposing the session value.

Out of scope

  • Replicating session bindings through SWIM or Grid CRDTs.
  • Persisting model conversation content or KV-cache data.
  • Allowing affinity to bypass health, authorization, or hard routing policy.
Dominant language
Rust
Stars
10
Forks
24
Avg merge
1d 9h
Merged PRs (30d)
79

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from praxis-proxy/grid

All issues in praxis-proxy/grid

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.