O calendário de lançamentos My Comics Collection é atualizado todas as manhãs às 9h horário de Paris por meio de um cron-job externo que consulta a API pública Metron.cloud (licença CC-BY-SA 4.0). O sistema sincroniza as novas solicitações, atualiza as datas modificadas, baixa as capas em falta para um cache local em disco e notifica internamente os usuários Premium cuja pull list é impactada.
O calendário de lançamentos se apoia em uma arquitetura de 4 camadas técnicas. Camada 1: Metron.cloud, a fonte de dados original, um banco de dados comunitário colaborativo criado em 2018 que agrega as solicitações oficiais das editoras sob licença CC-BY-SA 4.0. Camada 2: um cron-job externo hospedado no cron-job.org (serviço gratuito com timeout de 30s) que chama todas as manhãs às 9h00 de Paris um endpoint dedicado da API My Comics Collection. Camada 3: a API do servidor, que busca os novos dados do Metron via a REST API deles, atualiza a tabela MySQL upcoming_releases e dispara o download assíncrono das capas em falta. Camada 4: o frontend da aplicação, que consulta essa tabela a cada visita do usuário para exibir o calendário atualizado.
A arquitetura do sistema: Metron → API → cache → usuário
Esse design de 4 camadas separa claramente as responsabilidades: o Metron cuida do dado de origem (que consumimos legalmente por meio da licença deles), o cron controla a frequência (decidimos quando sincronizar), o servidor cuida da persistência (cache MySQL + disco) e o frontend cuida da exibição. Se uma das camadas sofrer um incidente temporário, as demais continuam funcionando — o cache MySQL mantém os dados anteriores mesmo se o Metron estiver fora do ar, o que evita páginas em branco.
O cron-job diário: por que 9h horário de Paris
A escolha do horário 9h00 de Paris (UTC+1 ou UTC+2 no verão) atende a várias restrições operacionais. (1) Diferença com o horário dos EUA: 9h00 em Paris corresponde a 3h-4h no horário de Nova York, quando as editoras americanas já terminaram suas atualizações noturnas no banco de dados Metron. Nesse horário, o dado do Metron está atualizado e estável para as próximas 24h. (2) Baixa carga no servidor: 9h em Paris ainda está em horário de baixo movimento para a maioria dos usuários My Comics Collection, o que evita que o cron-job concorra com o pico de tráfego dos usuários. (3) Disponibilidade durante o dia: os usuários francófonos que abrem a aplicação no início do dia (8h-11h) veem um calendário recém-atualizado, o que maximiza a qualidade percebida.
Uma exceção: para os usuários na Ásia/Pacífico que acessam à meia-noite de Paris (de manhã no fuso deles), o calendário pode exibir dados do dia anterior antes da sincronização das 9h. É um trade-off consciente: otimizamos para a maioria francófona da UE em vez da minoria da APAC.
O timeout de 30s e a arquitetura assíncrona fire-and-forget
Uma restrição técnica do serviço cron-job.org gratuito é o timeout HTTP de 30 segundos. Se o servidor My Comics Collection demorar mais de 30s para responder, o cron-job.org considera que houve falha e envia uma notificação de erro. Só que a sincronização completa do Metron (busca das 400+ solicitações, atualização do MySQL, download das novas capas) leva tipicamente 2-5 minutos — bem além do timeout.
A solução arquitetural: o endpoint pull_list_sync_async usa um padrão fire-and-forget por meio da função PHP fastcgi_finish_request(). Concretamente, o servidor (1) recebe a chamada do cron, (2) valida o token X-Sync-Token, (3) responde HTTP 200 em menos de 100 ms, (4) encerra a conexão HTTP, e (5) continua o trabalho de sincronização em segundo plano. O cron-job.org recebe seu HTTP 200 dentro do timeout e fica satisfeito, enquanto o servidor termina a sincronização de verdade no seu próprio ritmo.
Esse padrão é elegante, mas tem uma restrição: se a sincronização falhar silenciosamente após o fire-and-forget (timeout do MySQL, espaço em disco esgotado para as capas, etc.), o cron-job.org não vai saber disso. Para mitigar, o servidor grava um log em _logs/pull_list_cron.log a cada etapa, o que permite diagnosticar depois se uma sincronização falhou.
O cache em disco das capas: por que e como
As capas de comics obtidas a partir do Metron são armazenadas em um cache local em disco no servidor (diretório cache/metron_covers/). Esse cache é crucial para a confiabilidade da exibição. Antes da implementação do cache (sprint v5.105, final de abril de 2026), as capas eram referenciadas diretamente pelo CDN do Metron — o que resultava em imagens quebradas em uma a cada duas vezes, por causa dos limites de hotlinking impostos pelo CDN.
Com o cache em disco, o fluxo é: (1) o cron de sincronização dispara o download das capas em falta por meio de um comando PHP curl; (2) cada capa é armazenada com o nome {slug}.jpg em 300×450 pixels; (3) um proxy HTTP do lado do servidor serve esses arquivos pela URL /api.php?action=cover_proxy&slug=X, o que contorna completamente o CDN do Metron assim que a capa está em cache. Resultado: taxa de exibição das capas > 99,5%.
Performance: quanto custa uma sincronização diária em recursos
Para os curiosos técnicos, aqui estão as ordens de grandeza de uma sincronização diária típica em junho de 2026: (1) requisições ao Metron: 1 chamada REST por editora (~10 editoras principais), ou seja, 10 requisições HTTP em menos de 5 segundos; (2) volume de dados: 400-600 KB de JSON processado; (3) requisições MySQL: ~1.200 INSERT IGNORE (uma por solicitação, idempotente) em menos de 2 segundos; (4) download de capas em falta: tipicamente 20-50 capas novas por dia, ou seja, 1-3 MB baixados em 30 segundos; (5) tempo total decorrido: 2-5 minutos por dia; (6) custo mensal: marginal (amplamente incluído na hospedagem OVH compartilhada existente, sem custo adicional).
Essa frugalidade faz parte da filosofia My Comics Collection: a funcionalidade Pull List é oferecida gratuitamente aos usuários sem prejudicar a economia geral da aplicação, porque seu custo marginal é insignificante. O Premium financia a manutenção e as evoluções, não a consulta gratuita.