apiVersion: apps/v1 kind: Deployment metadata: name: hrrr-point-rs namespace: prop # Phase 3 Stream C: per-QSO HRRR fetches move off the BEAM pods. # Elixir writes to hrrr_fetch_tasks (one row per valid_time with a # points JSONB array); this deployment drains via FOR UPDATE SKIP # LOCKED, fetches each HRRR cycle once, and upserts hrrr_profiles. spec: # Two replicas for parallelism on QSO-submit spikes. FOR UPDATE SKIP # LOCKED on hrrr_fetch_tasks lets both claim without coordination. replicas: 2 strategy: type: RollingUpdate rollingUpdate: maxSurge: 0 maxUnavailable: 1 selector: matchLabels: app: hrrr-point-rs template: metadata: labels: app: hrrr-point-rs tier: hrrr-points spec: affinity: # Avoid co-locating with prop-grid-rs pods — they compete for # the same wgrib2 subprocess slots and NFS fsyncs. Grid chain # is latency-sensitive (users refreshing /map); per-QSO point # work is throughput-sensitive but latency-tolerant. podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 80 podAffinityTerm: labelSelector: matchLabels: app: prop-grid-rs topologyKey: kubernetes.io/hostname imagePullSecrets: - name: forgejo-registry securityContext: runAsUser: 65534 runAsNonRoot: true fsGroup: 65534 seccompProfile: type: RuntimeDefault containers: - name: hrrr-point-rs # Shares the prop-grid-rs image so one CI pipeline produces # both binaries. k8s `command:` overrides the default # ENTRYPOINT to launch the per-QSO point worker. image: git.mcintire.me/graham/prop-grid-rs:main-1776811522-e688d8c # {"$imagepolicy": "flux-system:prop-grid-rs"} imagePullPolicy: IfNotPresent command: ["/usr/bin/tini", "--", "/usr/local/bin/hrrr-point-worker"] env: - name: HRRR_BASE_URL value: "http://skippy.w5isp.com:8080" - name: HRRR_FALLBACK_BASE_URL value: "https://noaa-hrrr-bdp-pds.s3.amazonaws.com" - name: RUST_LOG value: "info" - name: PROP_GRID_RS_PG_CONNS value: "4" # Shared NFS idx cache — same directory as prop-grid-rs so a # chain-step idx fetch warms both workers. - name: HRRR_IDX_CACHE_DIR value: "/data/hrrr_idx" - name: OTEL_EXPORTER_OTLP_ENDPOINT value: "http://otel-collector.observability.svc.cluster.local:4317" envFrom: - secretRef: name: prop-secrets resources: requests: cpu: 100m memory: 256Mi limits: # Per-batch peak is a single CONUS surface + pressure # decode (~40 MB blob, ~200 MB wgrib2 working set plus # the full 92k-cell merged CellValues map kept in memory # until all requested points are drained). 1 Gi OOMKilled # repeatedly — four restarts in ten minutes — so bumped # to 2 Gi. The scheduler-on-worker2 placement has plenty # of headroom. cpu: "2" memory: 2Gi securityContext: allowPrivilegeEscalation: false runAsNonRoot: true runAsUser: 65534 capabilities: drop: - ALL seccompProfile: type: RuntimeDefault volumeMounts: - name: data mountPath: /data volumes: - name: data nfs: server: 10.0.15.103 path: /data