# Canary Request Job (account-weighted traffic shifting)

The canary request job gradually increases the share of users exposed to the canary version by
updating the router with a valid canary header, per account type. It's driven by `setAccountWeight`
steps in the canary strategy.

## How it works

Each `setAccountWeight` step in `rolloutStrategy.canary.steps` defines how much of an account type is
routed to the canary. At Helm-render time a helper (`_helpers.tpl`) turns each such step into an
`analysis` step that runs the canary-request-job `AnalysisTemplate` with the step's `weight`/`type`.
At run time the job calls the **canary manager** service, which updates the **router** with the right
canary header.

```yaml
rolloutStrategy:
  canary:
    steps:
      - setCanaryScale:
          weight: 100
      - setAccountWeight:
          weight: 20
          type: enterprise_trial
      - pause:
          duration: 10m
      - setAccountWeight:
          weight: 40
          type: enterprise_trial
      - pause:
          duration: 10m
      - setAccountWeight:
          weight: 100
          type: enterprise_trial
      - pause:
          duration: 10m
```

- `setCanaryScale: { weight: 100 }` brings the canary to full capacity before routing begins.
- `setAccountWeight` requires `weight` (allowed: `20`, `40`, `100`) and `type` (account type).
- **Advanced (optional) per step:**
  - `interval` — how often the job checks the canary-header change status (default **10s**).
  - `timeout` — how long to wait for the change (default **7200s** = 2h).
- `saas-deployer` injects the deployment `region` and `mt-service` name as args used by the helper.

A new job runs at each `setAccountWeight` step, then a `pause` lets you monitor before the next increment.

## Canary-request-job pod behavior

Pods spawned by the job have:

- **Log routing** — annotation `logging_index: devops-infra` routes the pod logs to the `devops-infra`
  index.
- **Context labels** — `rollout-name` (from `rolloutStrategy.deploymentName`) and `canary-region` (from
  `canaryRegion`), so pods are filterable: `kubectl get pods -l rollout-name=<name>`.
- **Pod naming** — the job metric is named after `canaryServiceName` (fallback `canary-job`), so pods
  read as `<analysis-run-uid>.<service>.<n>-<random>`. Underscores in the service are replaced with
  hyphens (`mt_event` → `mt-event`) to stay DNS-1123-valid. The leading UID is the Argo `AnalysisRun`
  UID (assigned by Argo — can't be changed from the chart); Argo also truncates the service segment to
  fit 63 chars (readability only, names stay unique).
- **Job tuning** (`rolloutAnalysisTemplates.canaryRequestJobTemplate`):
  - `backoffLimit` — retries before the Job is failed (default `0` = fail fast).
  - `ttlSecondsAfterFinished` (optional) — seconds Kubernetes keeps the finished Job/pod; unset → no
    timer (the pod persists until Argo evicts the owning AnalysisRun via its run-history limit).
  - Both render into the Job spec **only when present in values** (a value of `0` still renders).
  - `affinity` / `tolerations` — rendered verbatim into the canary-job pod spec (`job.spec.template.spec`)
    when set. They **default** to `k8s.jfrog.com/subscription_type in (paying, paying-arm64)` node
    affinity plus matching `subscription_type` tolerations, steering the canary-job onto paying-tier
    nodes. Set them to `{}` / `[]` to opt out and let the scheduler place the pod on any node.

## Canary Manager configuration keys

These configure the canary-request-job and are **injected automatically by `saas-deployer`** during
the Helm upgrade — **do not set them manually** in your values:

| Key | Meaning |
|-----|---------|
| `canaryServiceName` | The microservice being deployed. |
| `canaryRegion` | The deployment region. |
| `canaryManagerEndpoint` | Canary manager service URL. |
| `canaryManagerUsername` | Canary manager auth username. |
| `canaryManagerPassword` | Canary manager auth password. |
| `canaryRequestJobImage` | Container image for the canary request job. |
| `rolloutStrategy.canary.canaryByHeader.canaryByHeaderValue` | Canary header value (from the cell config). |
