--- # K8s Job для створення NATS JetStream streams apiVersion: batch/v1 kind: Job metadata: name: nats-create-streams namespace: nats spec: template: spec: containers: - name: create-streams image: python:3.11-slim command: - /bin/sh - -c - | pip install -q nats-py python3 << 'PYEOF' import asyncio from nats.js import api from nats.aio.client import Client as NATS async def main(): nc = NATS() await nc.connect("nats://nats-client.nats:4222") js = nc.jetstream() streams = [ {"name": "MM_ONLINE", "subjects": ["mm.embed.online", "mm.retrieve.online", "mm.summarize.online"], "max_age": 1800000000000, "max_deliver": 3}, {"name": "MM_OFFLINE", "subjects": ["mm.embed.offline", "mm.index.offline", "mm.backfill.offline"], "max_age": 604800000000000, "max_deliver": 10}, {"name": "MM_WRITE", "subjects": ["mm.qdrant.upsert", "mm.pg.write", "mm.neo4j.write"], "max_age": 604800000000000, "max_deliver": 10}, {"name": "MM_EVENTS", "subjects": ["mm.event.audit", "mm.event.status"], "max_age": 2592000000000000} ] for s in streams: try: await js.add_stream( name=s["name"], subjects=s["subjects"], retention=api.RetentionPolicy.LIMITS, max_age=s["max_age"], storage=api.StorageType.FILE, replicas=1, discard=api.DiscardPolicy.OLD, max_deliver=s.get("max_deliver", 10) ) print(f"✅ {s['name']}") except Exception as e: if "already in use" in str(e).lower(): print(f"⚠️ {s['name']} вже існує") else: print(f"❌ {s['name']}: {e}") print("\n📋 Створені streams:") for stream_name in await js.stream_names(): info = await js.stream_info(stream_name) print(f" - {stream_name}: {len(info.config.subjects)} subjects") await nc.close() asyncio.run(main()) PYEOF restartPolicy: Never backoffLimit: 3