Skip to content

Cron Central Filter Tenants By Server

technical-documenter edited this page Sep 3, 2026 · 1 revision

Cron central — filtro de tenants por servidor

Documentação técnica do filtro de tenants na agenda central (app:cron:run) do submódulo api-platform-common.

Contexto

A API multi-tenant mantém uma agenda central de jobs (CronJob) no banco master. Jobs com scope = tenant são expandidos para cada tenancy installed com app_host preenchido.

Em ambientes com vários hosts (produção, staging, white-labels em servidores distintos), o mesmo master pode listar tenants cujo banco não é alcançável a partir do host que está rodando o cron. Isso gerava falhas recorrentes (Access denied, Connection timed out) em comandos como tenant:integration:start, tenant:messenger:consume e import:start.

Comportamento

Comando

php bin/console app:cron:run [--server=<domínio>] [--dry-run]
Opção Efeito
--server=<domínio> Limita a expansão de jobs tenant aos tenancies cujo server_id corresponde ao do host informado
(sem --server) Usa APP_DOMAIN do ambiente como filtro implícito (via CronRunCommand::resolveServerFilter)
--dry-run Lista as execuções devidas sem executar os comandos

O filtro não altera jobs de scope = master (rodam uma vez, sem domínio).

Resolução do filtro

  1. CronRunCommand resolve o host (--server ou APP_DOMAIN).
  2. CronJobService::getDueJobExecutions($now, $serverHost) passa o host para getTargetTenants.
  3. getTargetTenants:
    • Se $serverHost vazio → mantém o comportamento anterior (todos os tenants installed com app_host).
    • Se preenchido → busca server_id em tenancies onde app_host = :server_host e server_id IS NOT NULL.
    • Se não achar server_id → retorna lista vazia (nenhum job tenant para esse host).
    • Se achar → adiciona WHERE server_id = :server_id na seleção de tenants.

Consultas usam parâmetros tipados (ParameterType::STRING / INTEGER).

Efeito operacional

  • O host de produção com --server=api.controleonline.com (ou APP_DOMAIN equivalente) não tenta conectar em tenants de outros servidores ou registros locais inválidos (localhost:8081, etc.).
  • Uma rodada sem filtro explícito ainda herda APP_DOMAIN e, portanto, também fica restrita ao servidor do processo.
  • Falhas de tenants inalcançáveis deixam de derrubar a rodada inteira por tentativa de conexão indevida.

Componentes

Artefato Papel
src/Command/CronRunCommand.php Entrypoint app:cron:run; resolve --server / APP_DOMAIN; lock de 900s
src/Service/CronJobService.php getDueJobExecutions, getTargetTenants (filtro por server_id)
src/Service/CronJobRunnerService.php Execução efetiva do comando configurado por job
tests/Service/CronJobServiceTest.php testDueTenantJobsAreFilteredByCurrentServer

Diagrama (fluxo resumido)

flowchart TD
  A[app:cron:run] --> B{resolveServerFilter}
  B -->|--server ou APP_DOMAIN| C[getDueJobExecutions]
  C --> D{job.scope}
  D -->|master| E[1 execução sem domain]
  D -->|tenant| F[getTargetTenants serverHost]
  F -->|serverHost vazio| G[todos installed com app_host]
  F -->|serverHost definido| H[resolve server_id do host]
  H -->|não encontrado| I[lista vazia]
  H -->|encontrado| J[tenants com mesmo server_id]
  E --> K[CronJobRunnerService]
  G --> K
  J --> K
Loading

Teste unitário de referência

CronJobServiceTest::testDueTenantJobsAreFilteredByCurrentServer monta um job tenant e um tenant com server_id = 7 associado ao host api.controleonline.com, e verifica que a execução devida carrega exatamente esse domínio/serverId.

O que este módulo faz / não faz

  • Faz: filtrar a expansão de jobs tenant pela identidade de servidor do host que agenda o cron.
  • Não faz: provisionar tenancies, alterar installation_status, nem expor endpoint HTTP novo. É superfície de console/operacional da API.
  • Visão de produto: infraestrutura da API (sem APP_TYPE de UI). Não há tela no Manager/CRM/POS relacionada a este filtro.

Links relacionados

Manutenção

  • Qualquer novo job scope=tenant na tabela central herda o filtro automaticamente.
  • Ao adicionar hosts/servidores, garantir que o registro em tenancies do próprio host da API tenha app_host e server_id coerentes, senão o filtro retorna lista vazia para aquele host.

Clone this wiki locally