Pular para o conteúdo

Produção

Subir, recarregar ao salvar, observar, estender com plugins e o que colocar na frente.

A linha de comando#

bash
dataforge vitrine new meupainel   # cria o projeto
dataforge vitrine dev             # sobe recarregando ao salvar
dataforge vitrine run             # sobe, sem recarregar
dataforge vitrine doctor          # diz por que ela não sobe

dataforge vitrine dev --porta=8600 --host=0.0.0.0

Sem argumento, ele procura main.df, app.df, painel.df e src/main.df, nessa ordem, e depois a entrada do forge.toml. A porta e o host da linha de comando vencem o que está escrito no arquivo — é o que permite trocar a porta sem editar o programa.

O doctor responde as perguntas de quem está vendo uma tela em branco, da causa mais provável para a menos: o módulo carrega, o Kiln está lá, existe um arquivo que sobe, ele compila, ele adota a Vitrine, ele chama V.subir, a porta está livre.

Para distribuir o projeto, dataforge pack.

Subir#

dataforge
V.rodar(painel, porta := 8501)                 // uma página
V.subir(porta := 8501, recarregar := yes)      // com hot reload
porta := V.servir(0)                            // em segundo plano
V.parar_servidor()

V.servir(0) deixa o sistema escolher a porta e devolve qual foi — é o que torna um teste de integração independente de porta ocupada.

Hot reload#

Com recarregar := yes, salvar um .df do projeto reinicia o processo. Reiniciar, e não recarregar o módulo: o estado de um módulo recarregado pela metade produz erros que não existem no código, e depurar isso custa mais do que o segundo do reinício.

Configuração#

dataforge
V.app("Painel",
      icone := "📊",
      descricao := "Vendas da Forja Ltda.",
      tema := "escuro",
      producao := yes,
      validade_sessao := 1800,
      limite_upload := 4194304)

V.configurar("atualizar_a_cada", 30)
ChaveFaz
titulo · icone · descricaoaba do navegador e metadados
tema"claro", "escuro" ou um vault de cores
modo_tema"automatico" segue o sistema de quem abre
producaoesconde o detalhe do erro e o diagnóstico
validade_sessaosegundos até a sessão ociosa sair da memória
limite_uploadbytes por arquivo enviado
atualizar_a_cadasegundos entre recargas automáticas
css · javascripto seu, injetado na página
manifestoserve um manifesto PWA em /__vitrine__/manifesto.json
httpsmarca o cookie de sessão como Secure

Tema#

dataforge
V.configurar("tema", {
    "primaria": "#0F62FE",
    "raio": "4px",
    "largura": "1400px"
})

Um tema é um vault de variáveis CSS. Mudar a cor primária muda o botão, o link, o foco, a borda do campo e a primeira série do gráfico ao mesmo tempo — e não em nove lugares. Um tema parcial completa o que falta a partir do claro e do escuro, para que quem trocou a primária não perca o modo escuro por isso.

Observabilidade#

dataforge
V.registrar("consulta lenta", "aviso", {"ms": 1840})
V.logs(50, "erro")
V.metricas()      // execuções, erros, média em ms, sessões, cache
V.saude()         // o que um balanceador pergunta

Duas rotas vêm prontas: GET /__vitrine__/saude e GET /__vitrine__/metricas. O log em memória tem teto de 2 000 linhas — sem teto, ele é um vazamento que só aparece depois de semanas no ar.

Middleware#

dataforge
action so_de_dia(ctx):
    given Time.hora() bigger 22:
        V.aviso("O painel está fechado à noite.")
        yield no                  // 'no' interrompe a página
    yield yes

V.antes(so_de_dia)

V.antes roda antes de toda página e pode interromper; V.depois recebe o contexto já montado. Para middleware de HTTP — CORS, limite de taxa, compressão —, use o do Kiln sobre V.montar().

Trabalho fora do pedido#

dataforge
V.tarefa(enviar_email, destinatario)    // roda numa thread, não espera
V.agendar(recalcular_totais, 3600)      // de hora em hora

V.tarefa é para o que a página não vai mostrar agora. Para um resultado que a página precisa, Arcane.Async, que tem await. O primeiro disparo de V.agendar é depois do primeiro intervalo — agendar algo "a cada hora" não deveria fazê-lo agora e de novo em uma hora.

Plugins#

dataforge
action tema_da_empresa(app):
    app.configurar("tema", {"primaria": "#7B1FA2"})
    app.configurar("css", ".v-titulo { letter-spacing: -.03em }")

V.plugin("tema-empresa", tema_da_empresa)

Um plugin é uma ação que recebe a aplicação e acrescenta algo. Registrar duas vezes o mesmo nome é erro, e não substituição silenciosa: quase sempre é um adopt duplicado, e descobrir isso por um comportamento que sumiu é caro.

O que colocar na frente#

Mais de um processo: a sessão num lugar comum#

Por padrão a sessão vive na memória do processo. Com dois processos atrás de um balanceador, o segundo pedido da mesma pessoa cai numa memória que nunca a viu: o contador volta a 1 e o login "cai". Dê às sessões um lugar que todos os processos veem:

dataforge
V.app("Painel", sessoes_em := V.sessoes_em_banco("/dados/sessoes.db"))
// ou: V.sessoes_em_arquivos("/dados/sessoes")

A página continua falando com um dicionário: a sessão é aberta no começo do pedido e gravada uma vez, no fim, só com o que mudou — inclusive itens.append(x), que não passa por definir. A gravação é por chave: duas abas mexendo em chaves diferentes não apagam uma à outra; na mesma chave, vence a última.

ArmazémQuem vê
o padrãoeste processo
V.sessoes_em_banco(caminho)todo processo que abre o mesmo SQLite — aceita também a conexão do Arcane.Database
V.sessoes_em_arquivos(pasta)todo processo que vê a mesma pasta
um blueprint com carregar, gravar e apagaro que ele decidir: Redis, Postgres…

Atualização automática#

dataforge
action acompanhar():
    V.atualizar_a_cada(15)
    V.metrica("Fila", tamanho_da_fila())

A página se recarrega sozinha nesse intervalo — e não quando a aba está escondida, porque cobrar do servidor por uma página que ninguém está vendo é desperdício puro.

É o "tempo real" do framework, e ele é por pergunta e não por empurrão. O Kiln tem WebSocket e SSE (/docs/kiln/tempo-real) — a Vitrine é que não os usa: o modelo dela é reexecutar o programa inteiro, e empurrar um pedaço de tela exigiria saber qual pedaço mudou, que é exatamente o que este framework existe para não precisar saber.

Para um painel que muda a cada segundos, perguntar é suficiente e não quebra atrás de proxy nenhum. Para um fluxo de eventos contínuo — cotação, log ao vivo, progresso de um trabalho longo — é o Kiln direto que serve.