Ir para o conteúdo

Blogue ·

Uma barra de progresso que se recusa a adivinhar

A maioria das estimativas de tempo é inventada. Eis a regra que decide se o painel tem direito a mostrar uma, e o que escreve no ecrã quando não tem.

Por Provibr

Alguém carrega em instalar. É preciso clonar uma máquina, arrancá-la, configurá-la e verificá-la e, algures a meio disso, o cliente quer saber uma coisa: quanto tempo é que isto vai demorar.

A resposta fácil é uma contagem decrescente. Escolhe-se um número plausível, subtrai-se um segundo a cada segundo, e o ecrã fica com ar de quem sabe alguma coisa. Não sabe. Uma contagem decrescente é uma promessa sobre um momento, e ninguém na casa conhece esse momento.

Por isso escrevemos a regra, demos-lhe um número de versão e fizemos o painel dizer em voz alta quando não se qualifica.

A regra, em resumo

Uma estimativa de tempo só aparece quando duas condições são ambas verdadeiras. Têm de existir pelo menos vinte execuções bem sucedidas do mesmo tipo de trabalho nos últimos trinta dias, e a dispersão tem de ser estreita: o percentil noventa não pode ser mais de duas vezes e meia a mediana. Se uma delas falhar, o ecrã mostra a etapa, o tempo decorrido e uma frase a dizer que não há estimativa.

Esses três números vivem numa única constante com um campo de versão ao lado, e mais nada no código tem o direito de ter opinião sobre eles.

SituaçãoO que o ecrã mostra
Menos de vinte execuções comparáveis em trinta dias«No reliable time estimate yet», com quantas execuções foram registadas e quantas são necessárias
Vinte ou mais em trinta dias, mas a dispersão é demasiado larga«No reliable time estimate», e que as execuções ficaram demasiado afastadas umas das outras
Ambas as condições cumpridas«Comparable tasks took X to Y minutes, based on N runs in the last 30 days»

Leia a terceira linha com atenção. É um intervalo e nomeia a sua própria prova. Não é uma barra a rastejar para a meta, e nunca se transforma em «faltam 3 minutos».

Porquê um intervalo e não uma contagem decrescente

Uma contagem decrescente junta dois erros. Esconde a incerteza e volta a afirmar-se a cada segundo, pelo que o engano ganha um ritmo. Toda a gente já viu uma caixa de cópia prometer quatro minutos, depois catorze, depois dois, e aprendeu em cerca de trinta segundos que o número não quer dizer nada. Depois de um leitor aprender isso, todos os outros números do ecrã passam a valer um pouco menos. Um intervalo, dito uma vez e com a contagem de amostras ao lado, não consegue fazer isso.

A condição da dispersão é a parte que faz o trabalho a sério. Vinte amostras com uma mediana de quatro minutos e um percentil noventa de quarenta minutos não são uma coorte com uma previsão lá dentro; são duas populações diferentes com um só rótulo, e fazer a média delas produz um valor com casa decimal e sem significado. Duas vezes e meia é um número escolhido, não derivado, e o campo de versão existe para que alterá-lo mais tarde seja uma decisão visível.

A coorte é a conta do próprio cliente, e isso é deliberado

A forma óbvia de chegar depressa a vinte amostras é medir em toda a plataforma. Não o fazemos. A coorte é o tipo de trabalho dentro de uma única organização.

Há duas razões, e a segunda é a que decidiu.

A primeira é a comparabilidade. O histórico próprio é a população mais parecida que existe: o mesmo hipervisor, a mesma rede, as mesmas imagens, o mesmo armazenamento.

A segunda é que a contagem de amostras está no ecrã. Uma frase que diz quantas execuções comparáveis a plataforma viu em trinta dias é uma afirmação sobre o nosso próprio volume, impressa no painel de um cliente, e seria entregue em troca de uma estimativa ligeiramente melhor. Limitar a consulta a uma organização faz com que o número no seu ecrã seja um facto sobre si.

A consequência prática é que uma conta recente não vê estimativa nenhuma durante algum tempo, e esse é o comportamento correto e não uma lacuna a preencher. Mostrar nada é melhor do que mostrar um número que não quer dizer nada.

Não existe tabela de amostras

A duração de uma tarefa bem sucedida é a diferença entre dois carimbos temporais que já estão guardados na própria tarefa. Não há uma tabela separada de medições.

Isso parece uma poupança óbvia, e vale a pena dizer porque foi uma decisão. Uma segunda tabela guardaria a mesma verdade duas vezes, e as duas divergiriam da primeira vez que uma limpeza de retenção tocasse numa e não na outra. A única coisa que acrescentaria mesmo são amostras que sobrevivem às tarefas de onde vieram, e isso só importa quando o período de retenção for mais curto do que a janela de medição. Hoje a retenção é de noventa dias e a janela é de trinta, portanto a questão não se põe.

Uma nota de rodapé que já mordeu este código: a consulta do percentil devolve um double e a contagem devolve um bigint, que o driver entrega como texto. Ambos precisam de conversão, e esquecer exatamente um dos dois falha em silêncio em vez de falhar alto.

Etapas, porque uma percentagem tem de vir de algum lado

Cada tipo de tarefa transporta uma lista de etapas por ordem. Uma instalação passa por em fila, a preparar, a arrancar, a instalar, a terminar. Uma transferência a partir de um URL passa por em fila, enviada ao agente, a transferir, a verificar, a aplicar. A percentagem é derivada da posição nessa lista, a não ser que o trabalho subjacente comunique uma percentagem real própria, caso em que é essa que ganha.

Essa sobreposição importa mais do que parece. Uma instalação comunica o seu próprio valor de progresso, que é mostrado na página do próprio servidor; se a gaveta calculasse um segundo número a partir das posições das etapas, um ecrã transportaria duas percentagens diferentes sobre o mesmo trabalho. Isso é uma segunda cópia da verdade, uma camada acima.

A tradução das fases de instalação para etapas está exatamente num sítio, escrita como um registo exaustivo em vez de uma instrução de seleção. Catorze fases repartidas por duas escadas de instalação diferentes são mapeadas em cinco etapas que um cliente reconheceria. Uma fase nova é um erro de compilação, não uma etapa que cai em silêncio para a primeira.

Desatualizado não é falhado

Há dois limiares para a frescura do último relatório de progresso: dois minutos e dez minutos. Passado o primeiro, o ecrã diz que não há atualização desde determinada hora. Passado o segundo, diz que nada foi comunicado desde então.

Nenhum deles altera o estado. O trabalho pode estar a correr na perfeição. O que parou foi o relato, e um leitor merece que lho digam em vez de ficar a olhar para uma barra que não se mexe e a tirar as suas próprias conclusões. Confundir silêncio com falha é o mesmo erro que fechar um incidente porque as medições deixaram de chegar, e vale a pena manter as duas palavras separadas em todos os sítios onde aparecem.

A gaveta não é dona de nada

A gaveta de tarefas em segundo plano no cabeçalho assenta em cima de tudo isto, e a sua regra de desenho é curta: não guarda estado próprio nenhum sobre o trabalho. O único estado local naquele componente é se o painel está aberto. Não há ciclo de leitura, não há intervalo, não há um segundo socket. O estado inicial chega da mesma consulta que a página de detalhe usa, e as atualizações em direto chegam pelo armazenamento partilhado de tempo real.

Um teste lê a árvore sintática do componente e falha se alguma variável local chegar a guardar um estado, uma etapa ou uma percentagem. Isso é uma garantia mais forte do que uma revisão de código, pela mesma razão que um comentário não é um teste.

Um pormenor ali dentro é fácil de trocar ao contrário: os grupos na gaveta são calculados depois de a atualização em direto ser aplicada, não antes. Calcule-os primeiro e uma tarefa que acabou de falhar fica sentada no grupo das que estão a correr até ao carregamento completo seguinte da página, a mostrar em silêncio um indicador a girar ao lado de uma coisa que já está a vermelho.

Três defeitos que só a verificação encontrou

Os três compilaram, passaram a verificação de tipos e passaram nos testes unitários.

O recibo nunca chegou a ser escrito em lado nenhum. O código referia uma função que não existia, pelo que uma instalação bem sucedida produzia uma tarefa com uma secção de resultado que ficava vazia para sempre.

Uma fase de instalação não reconhecida apagava a etapa registada. O mapeamento devolve corretamente nada para uma fase que não conhece, mas quem o chamava escrevia esse nada na linha, pelo que um agente mais antigo a comunicar uma fase renomeada teria apagado a etapa de uma tarefa que corria bem. A correção é um único recuo para a etapa que já lá estava, e a salvaguarda foi provada a vermelho antes de merecer confiança.

Uma tarefa terminada continuava a girar. A etapa de uma tarefa concluída continua a ser a última que alcançou, o que está certo, porque de outra forma não se veria onde acabou. O erro era perguntar «esta etapa é a atual» comparando nomes, quando a pergunta verdadeira é se a tarefa ainda está ativa. Uma tarefa falhada também não recebe um visto verde na etapa em que morreu: essa etapa foi abandonada e não concluída, pelo que tem um estado próprio em vez de ser arrumada em concluída ou não iniciada, que afirmariam ambas uma coisa falsa.

O que registaríamos

  1. Colocar a regra da estimativa numa única constante com versão. A pergunta «a estimativa que mostraram em março era defensável» só tem resposta se se souber que regra estava em vigor.
  2. Fazer da ausência de estimativa uma frase, e não um espaço vazio. Um vazio onde devia estar um número lê-se como um defeito; «No reliable time estimate yet. 6 of 20 comparable runs recorded.» lê-se como um sistema que sabe aquilo que não sabe.
  3. Limitar a coorte ao cliente, e aceitar que as contas novas não vejam nada durante algum tempo. A alternativa imprime o volume da própria casa no ecrã deles.
  4. Nunca deixar uma gaveta, um distintivo ou um widget guardar a sua própria cópia de um estado. Dois números sobre um trabalho num só ecrã é pior do que número nenhum.
  5. Separar silêncio de falha no vocabulário, no modelo de dados e no ecrã, e mantê-los separados em todo o lado.

Os limites honestos: esta camada corre hoje para quatro tipos de trabalho, e a lista é deliberadamente curta porque um tipo que ninguém consegue iniciar é uma categoria que aparece vazia. O fluxo de cancelamento consegue registar um pedido, mas ainda não existe camada de execução que confirme algum, e a gaveta não tem ponto de entrada abaixo dos 768 pixels de largura de ecrã.

O mesmo argumento, aplicado àquilo a que uma barra de progresso costuma estar presa, está em porque um 200 do Proxmox não é um resultado, e a razão pela qual deixámos de confiar nos nossos próprios prazos está em um prazo não é um botão de paragem.

Do trabalho de plataforma no Provibr.

Comece com um host e um agente

Crie uma conta, instale o agente com um único comando e ligue o seu primeiro host Proxmox. O período experimental dura 14 dias e não pede quaisquer dados de pagamento.