mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-08-04 14:57:42 +00:00
Some checks are pending
Docker Dev Branch Images Build / build (Dockerfile, lc-dev, node) (push) Waiting to run
Docker Dev Branch Images Build / build (Dockerfile.multi, lc-dev-api, api-build) (push) Waiting to run
GitNexus Index / index (push) Waiting to run
GitNexus Index / post-index (push) Blocked by required conditions
* 📉 perf: Bound Early Event Buffering for Detached Generations
A generation streaming with no attached subscriber re-entered buffering
mode on every disconnect and retained each emitted event in
earlyEventBuffer for its remaining duration. A single 26-minute detached
run (~58,800 tool-argument deltas) grew the heap past 2 GiB with GC cost
climbing alongside it, while client reconnects always resume from
durable state and discard that local buffer anyway.
- Close the early buffer after the first attachment drains it in Redis
mode; the durable chunk log and pub/sub own recovery from then on,
matching how cross-replica subscribers already attach.
- Enforce hard bounds (5,000 events / 8 MB estimated) in both modes; on
overflow the buffer is discarded and closed, with recovery falling back
to the durable chunk log (Redis) or resume snapshot (in-memory).
- Add a generation_stream_early_buffer_overflows_total counter and
earlyBufferedEvents/Bytes gauges on getRuntimeStats() for visibility.
- Add incident-shaped regression tests and update specs that pinned the
old post-disconnect re-buffering contract.
* fix: redirect post-overflow first attachments to resume recovery
A buffer discarded by the overflow guard left the initial non-resume
SSE attachment with nothing to replay, silently omitting pre-attach
output until the final event. Track the overflow on the runtime and
close such attachments with the existing reconnect signal instead: the
client already re-attaches with resume=true on transport failure and
its sync frame reconstructs the discarded output from durable/snapshot
state. Adds no per-event work; the check is one boolean per attachment.
* fix: enforce buffer bounds when restoring canceled resume captures
Captured emissions restored by a resume canceled before activation
bypassed the early-buffer hard cap, so one oversized restoration could
persist past the limits with no later emission to trip the guard.
Restoration now applies the same overflow-and-close behavior through a
shared helper, and the restore-cap spec fails before this change
(5 events / ~10MB retained) and passes after.
* chore: add Redis management scripts and update package.json for Redis commands
60 lines
No EOL
1.2 KiB
Bash
60 lines
No EOL
1.2 KiB
Bash
#!/usr/bin/env bash
|
|
|
|
set -euo pipefail
|
|
|
|
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
CLUSTER_DIR="$ROOT_DIR/redis-config"
|
|
|
|
require_redis() {
|
|
if command -v redis-server >/dev/null && command -v redis-cli >/dev/null; then
|
|
return
|
|
fi
|
|
|
|
echo "Redis is required. Install it with: sudo apt-get install redis-server redis-tools"
|
|
exit 1
|
|
}
|
|
|
|
redis_is_running() {
|
|
redis-cli -p "$1" ping >/dev/null 2>&1
|
|
}
|
|
|
|
stop_single() {
|
|
if redis_is_running 6379; then
|
|
redis-cli -p 6379 shutdown nosave >/dev/null 2>&1 || true
|
|
fi
|
|
}
|
|
|
|
start_single() {
|
|
mkdir -p "$CLUSTER_DIR/data/6379"
|
|
|
|
if redis_is_running 6379; then
|
|
echo "Redis single node is already running on port 6379."
|
|
return
|
|
fi
|
|
|
|
redis-server --port 6379 --dir "$CLUSTER_DIR/data/6379" --save '' --appendonly no --daemonize yes
|
|
redis-cli -p 6379 ping >/dev/null
|
|
echo "Redis single node is ready on port 6379."
|
|
}
|
|
|
|
case "${1:-}" in
|
|
single)
|
|
require_redis
|
|
"$CLUSTER_DIR/stop-cluster.sh" >/dev/null 2>&1 || true
|
|
start_single
|
|
;;
|
|
cluster)
|
|
require_redis
|
|
stop_single
|
|
exec "$CLUSTER_DIR/start-cluster.sh"
|
|
;;
|
|
stop)
|
|
require_redis
|
|
stop_single
|
|
exec "$CLUSTER_DIR/stop-cluster.sh"
|
|
;;
|
|
*)
|
|
echo "Usage: $0 {single|cluster|stop}"
|
|
exit 1
|
|
;;
|
|
esac |