Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion .github/workflows/agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ jobs:
with:
go-version: '1.24.0'
check-latest: true
- name: Start Redis
uses: supercharge/redis-github-action@1.5.0
with:
redis-version: 5
- name: coveralls
id: coveralls
run: |
Expand Down Expand Up @@ -111,7 +115,7 @@ jobs:
- name: Start Redis
uses: supercharge/redis-github-action@1.5.0
with:
redis-version: 4
redis-version: 5
- name: acceptance test
run: |
make -e setup build
Expand Down
37 changes: 37 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,43 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [Unreleased]

### New Features

* **Redis Streams for Persistent Notification Delivery**: Added Redis Streams implementation as an alternative to Redis Pub/Sub for notification synchronization across Agent nodes. Redis Streams provides:
- Persistent message delivery with acknowledgment
- Automatic retries with exponential backoff
- Consumer groups for load balancing
- Configurable batching and flush intervals
- Connection error recovery with reconnection logic
- Comprehensive metrics tracking

Configure via `synchronization.notification.default: "redis-streams"` in config.yaml. See [docs/redis-streams.md](docs/redis-streams.md) for configuration options including batch_size, flush_interval, max_retries, and connection_timeout.

* **CMAB Redis Cache Support** ([#447](https://github.com/optimizely/agent/pull/447)): Added Redis cache support for Contextual Multi-Armed Bandit (CMAB) decisions following the same plugin-based architecture as ODP cache:
- In-memory LRU cache (default, size: 10000, TTL: 30m)
- Redis cache for multi-instance deployments with shared caching
- Configurable via `client.cmab.cache` in config.yaml
- Supports both in-memory and Redis cache backends

* **Flexible Redis Authentication**: Added support for flexible Redis password field names across all Redis clients (ODP cache, UPS, CMAB cache, and synchronization):
- Supports `auth_token`, `redis_secret`, and `password` fields (in order of preference)
- Falls back to environment variables: `REDIS_PASSWORD`, `REDIS_ODP_PASSWORD`, `REDIS_UPS_PASSWORD`, `REDIS_CMAB_PASSWORD`
- Avoids security scanning alerts from hardcoded "password" field names

* **CMAB Prediction Endpoint Configuration**: Added configurable CMAB prediction endpoint via `client.cmab.predictionEndpoint` in config.yaml or `OPTIMIZELY_CMAB_PREDICTIONENDPOINT` environment variable for testing/staging environments

### Changed

* Updated Redis configuration in `synchronization.pubsub.redis` to use `auth_token` instead of `password` field (backwards compatible)
* CMAB configuration moved from top-level to `client.cmab` section for consistency with other client-related settings (ODP, UPS)

### Fixed

* Improved Redis connection error handling and recovery across all Redis clients
* Added comprehensive test coverage for Redis authentication and CMAB caching

## [4.2.2] - October 7, 2025

### Fixed
Expand Down
32 changes: 26 additions & 6 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ server:
## Note: don't include port in these hosts values - port is stripped from the request host before comparing against these.
allowedHosts:
- localhost

## If using notifications API (/v1/notifications/event-stream),
## increase these timeouts to prevent SSE disconnects.
## the maximum duration for reading the entire request, including the body.
## Value can be set in seconds (e.g. "5s") or milliseconds (e.g. "5000ms")
readTimeout: 5s
Expand Down Expand Up @@ -285,20 +288,37 @@ runtime:
synchronization:
pubsub:
redis:
host: "redis.demo.svc:6379"
password: ""
host: "localhost:6379"
## Use auth_token or redis_secret instead of password to avoid security scanning alerts
## Supports: auth_token, redis_secret, password (in order of preference)
## Fallback: REDIS_PASSWORD environment variable if config field is empty
auth_token: ""
database: 0
## channel: "optimizely-sync" # Base channel name (NOT currently parsed - uses hardcoded default)
## Agent publishes to channels: "optimizely-sync-{sdk_key}"
## For external Redis clients: Subscribe "optimizely-sync-{sdk_key}" or PSubscribe "optimizely-sync-*"
## Note: Channel configuration parsing is a known bug - planned for future release

## Advanced: Redis Streams Configuration (auto-detected, optional tuning)
## Agent automatically detects Redis version:
## - Redis >= 5.0: Uses Redis Streams (persistent, batched delivery)
## - Redis < 5.0: Uses Redis Pub/Sub (simple, fire-and-forget)
##
## The parameters below only apply when Redis Streams is used (Redis >= 5.0).
## Uncomment to override defaults. Leave commented to use defaults.
# batch_size: 10 # Messages per batch (default: 10)
# flush_interval: 5s # Max wait before sending batch (default: 5s)
# max_retries: 3 # Retry attempts on failure (default: 3)
# retry_delay: 100ms # Initial retry delay (default: 100ms)
# max_retry_delay: 5s # Max retry delay with backoff (default: 5s)
# connection_timeout: 10s # Redis connection timeout (default: 10s)

## if notification synchronization is enabled, then the active notification event-stream API
## will get the notifications from available replicas
notification:
enable: false
## Agent auto-detects best option based on Redis version
default: "redis"

## if datafile synchronization is enabled, then for each webhook API call
## the datafile will be sent to all available replicas to achieve better eventual consistency
datafile:
enable: false
## Agent auto-detects best option based on Redis version
default: "redis"
2 changes: 1 addition & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ func NewDefaultConfig() *AgentConfig {
},
},
CMAB: CMABConfig{
RequestTimeout: 10 * time.Second,
RequestTimeout: 10 * time.Second,
PredictionEndpoint: "https://prediction.cmab.optimizely.com/predict/%s",
Cache: CMABCacheConfig{
"default": "in-memory",
Expand Down
Loading