- Defined locations for crewai crew memory. This failed in k8s. - Redis connection for pub/sub in ExecutionProgressTracker adapted to conform to TLS-enabled connections
85 lines
2.9 KiB
Python
85 lines
2.9 KiB
Python
import ssl
|
|
from typing import Dict, Any
|
|
|
|
import redis
|
|
from flask import Flask
|
|
|
|
|
|
def _build_pubsub_redis_config(app: Flask) -> Dict[str, Any]:
|
|
"""Build Redis ConnectionPool config for the pubsub/EPT workload using app.config.
|
|
Does not modify cache or session pools.
|
|
"""
|
|
cfg = app.config
|
|
|
|
config: Dict[str, Any] = {
|
|
'host': cfg['REDIS_URL'],
|
|
'port': cfg['REDIS_PORT'],
|
|
'db': int(cfg.get('REDIS_SPECIALIST_EXEC_DB', '0')),
|
|
'max_connections': int(cfg.get('REDIS_PUBSUB_MAX_CONNECTIONS', 200)),
|
|
'retry_on_timeout': True,
|
|
'socket_keepalive': True,
|
|
'socket_keepalive_options': {},
|
|
'socket_timeout': float(cfg.get('REDIS_PUBSUB_SOCKET_TIMEOUT', 10.0)),
|
|
'socket_connect_timeout': float(cfg.get('REDIS_PUBSUB_CONNECT_TIMEOUT', 3.0)),
|
|
}
|
|
|
|
# Authentication if present
|
|
un = cfg.get('REDIS_USER')
|
|
pw = cfg.get('REDIS_PASS')
|
|
if un and pw:
|
|
config.update({'username': un, 'password': pw})
|
|
|
|
# TLS when configured
|
|
cert_path = cfg.get('REDIS_CA_CERT_PATH')
|
|
if cfg.get('REDIS_SCHEME') == 'rediss' and cert_path:
|
|
config.update({
|
|
'connection_class': redis.SSLConnection,
|
|
'ssl_cert_reqs': ssl.CERT_REQUIRED,
|
|
'ssl_check_hostname': cfg.get('REDIS_SSL_CHECK_HOSTNAME', True),
|
|
'ssl_ca_certs': cert_path,
|
|
})
|
|
|
|
return config
|
|
|
|
|
|
def create_pubsub_pool(app: Flask) -> redis.ConnectionPool:
|
|
"""Create and store the dedicated pubsub ConnectionPool in app.extensions."""
|
|
if not hasattr(app, 'extensions'):
|
|
app.extensions = {}
|
|
|
|
# Reuse existing if already created
|
|
pool = app.extensions.get('redis_pubsub_pool')
|
|
if pool is not None:
|
|
return pool
|
|
|
|
config = _build_pubsub_redis_config(app)
|
|
pool = redis.ConnectionPool(**config)
|
|
app.extensions['redis_pubsub_pool'] = pool
|
|
|
|
# Log a concise, non-sensitive summary
|
|
try:
|
|
summary = {
|
|
'scheme': app.config.get('REDIS_SCHEME'),
|
|
'host': app.config.get('REDIS_URL'),
|
|
'port': app.config.get('REDIS_PORT'),
|
|
'db': app.config.get('REDIS_SPECIALIST_EXEC_DB', '0'),
|
|
'ssl_check_hostname': app.config.get('REDIS_SSL_CHECK_HOSTNAME'),
|
|
'ca_present': bool(app.config.get('REDIS_CA_CERT_PATH')),
|
|
'max_connections': app.config.get('REDIS_PUBSUB_MAX_CONNECTIONS'),
|
|
'socket_timeout': app.config.get('REDIS_PUBSUB_SOCKET_TIMEOUT'),
|
|
'socket_connect_timeout': app.config.get('REDIS_PUBSUB_CONNECT_TIMEOUT'),
|
|
}
|
|
app.logger.info(f"Initialized Redis pubsub pool: {summary}")
|
|
except Exception:
|
|
pass
|
|
|
|
return pool
|
|
|
|
|
|
def get_pubsub_client(app: Flask) -> redis.Redis:
|
|
"""Get a Redis client bound to the dedicated pubsub pool."""
|
|
pool = app.extensions.get('redis_pubsub_pool')
|
|
if pool is None:
|
|
pool = create_pubsub_pool(app)
|
|
return redis.Redis(connection_pool=pool)
|