TODO comentários com prazos?

51

Antecedentes

Estou trabalhando em uma equipe que está procurando implantar implantações sem tempo de inatividade. Estamos planejando usar uma estratégia de implantação azul / verde para conseguir isso. Uma das coisas que estou percebendo ao fazer a pesquisa é o quão complicado se torna fazer alterações no banco de dados. Uma operação simples, como renomear uma coluna, pode exigir 3 ciclos completos de lançamento até que esteja concluído!

Parece-me que ter a implementação completa de uma alteração em vários ciclos de lançamento introduz um grande potencial de erro humano. No artigo vinculado, ele mostra que as alterações de código são necessárias para duas versões e uma migração de banco de dados é necessária para três versões.

O que estou procurando

Atualmente, se quisermos lembrar de fazer algo, podemos criar um ticket em nosso sistema de gerenciamento de problemas, que cria confusão e também pode ser movido para um sprint posterior ou para o backlog por parte do gerenciamento; ou podemos criar um comentário TODO, que provavelmente será esquecido completamente.

O que estou procurando é uma maneira que um comentário TODO possa ter um prazo final contra ele, e nosso sistema de Integração Contínua (atual indeciso que usaremos) rejeitaria a compilação se este prazo expirasse.

Por exemplo, se renomearmos uma coluna, poderemos criar a migração inicial para ela e dois comentários TODO para garantir que as duas migrações restantes sejam criadas:

// TODO by v55: Create migration to move constraints to new column, remove references to old column in app
// TODO by v56: Create migration to drop old column

Isso parece bastante simples de implementar, mas estou imaginando se algo assim já existe, porque não quero reinventar a roda.

Pensamentos adicionais

Eu sinto que posso estar sofrendo de problema XY aqui, dado que implantações contínuas e implantações de azul / verde são consideradas uma prática recomendada, parece estranho que eu não consiga encontrar uma solução para tornar as atualizações de banco de dados menos dolorosas. Se você acha que estou olhando para a coisa errada por completo, por favor, deixe-me saber em um comentário! Dito isso, o exemplo de banco de dados que dei é apenas um exemplo, e acho que os comentários TODO com datas de entrega também seriam úteis em outras situações, por isso mesmo que eu esteja abordando essa situação específica, eu realmente gostaria de respostas pergunta real também. Obrigado!

EDIT: Acabei de pensar em outra situação em que isso poderia ser útil. Se você usar as alternâncias de recurso para ativar partes de seu aplicativo quando elas estiverem prontas, é necessário ter cuidado ao limpá-las; caso contrário, você poderá ter Alternar dívida . Comentários com prazos podem ser uma boa maneira de lembrar isso.

    
por Joshua Walsh 30.05.2017 / 02:12
fonte

7 respostas

52

Esta pergunta é realmente duas perguntas em uma.

Todo comentário

De todas as maneiras de rastrear itens de ação, esse é o pior. TODO comentários são bons durante o trabalho ativo ou como uma forma de sugestão para um mantenedor, "aqui está algo que poderia ser melhorado no futuro". Mas se você confiar nos comentários TODO para realizar o trabalho, estará fadado ao fracasso.

O que fazer sobre isso

TODO os comentários são basicamente dívida técnica, então eles devem ser tratados como qualquer outra dívida técnica. Enfrente-os imediatamente, se tiver tempo, ou coloque-os no backlog para que eles possam ser rastreados e priorizados.

De um modo geral, e isso é totalmente opinativo e aberto ao debate, TODO comentários podem ser considerados um cheiro de código. Se um comentário TODO faz com que seja verificado o controle de versão, você tem que se perguntar, você está indo realmente para segui-lo agora? Se não, tudo bem. Apenas seja honesto consigo mesmo e coloque-o no backlog.

O modo como você gerencia esse backlog se resume a processos de negócios, políticas da empresa e talvez alguma autonomia pessoal. Mas você ainda precisa de um backlog rastreado e priorizado para garantir que isso aconteça.

Alterações no banco de dados

Sim, as alterações do banco de dados são complicadas com uma política de tempo de inatividade zero. Alguns truques para ajudar a torná-lo menos doloroso:

Processo pós-implementação

Crie um processo de pós-implantação que seja executado como parte do mesmo release. No entanto, você quer que ele funcione. No último sistema em que trabalhei, projetei uma implantação de quatro fases:

  1. scripts do banco de dados do preapp
  2. aplicativos da web
  3. scripts de banco de dados postapp
  4. scripts do banco de dados da janela de manutenção

A idéia era que, sempre que possível, colocássemos o máximo possível de mudanças no banco de dados no pré-pico.

O postapp foi reservado para os casos incomuns em que precisávamos fazer alterações de esquema incompatíveis. Nesses casos, o preapp faria uma mudança suficiente para tornar o novo código do aplicativo compatível (talvez criando uma exibição temporária para compatibilidade) e o postapp iria limpar esses artefatos temporários.

A fase da janela de manutenção foi reservada para alterações que realmente exigiam tempo de inatividade ou onde o risco ou custo de uma implantação ativa não valeria a pena. Por exemplo, scripts que alteram grandes quantidades de dados podem precisar bloquear uma tabela inteira.

Implante com frequência

Se você implantar novos lançamentos com frequência suficiente, poderá chegar a um ponto em que carregar uma alteração em 2 ou 3 versões é trivial. Ciclos de lançamento longos amplificam o custo das alterações do banco de dados.

    
por 30.05.2017 / 03:32
fonte
24

Não use TODOs. Você já tem uma lista de tarefas no seu projeto. É chamado de rastreador de problemas.

Eu acho que o verdadeiro problema está nesta frase:

we can create a ticket in our issue management system, which creates clutter and also might get moved to a later sprint or the backlog by management.

Se o rastreador de problemas criar muita confusão, encontre maneiras de corrigir isso. Talvez um tipo / tag de problema especial que envolva menos cerimônia. Talvez sub-questões. Talvez menos cerimónia completamente. Nós não podemos dizer realmente. Mas se o rastreador de problemas cria tanto trabalho, que as pessoas formulam uma pergunta elaborada em um fórum público, em vez de apenas adicionar esse problema, algo está seriamente errado.

Se a sua administração atrasa indevidamente a última parte de uma tarefa, você tem duas opções:

  1. fale com sua gerência porque esta é uma má ideia.

  2. lidamos com isso como uma única tarefa. Essa pode ser a solução padrão ouro. Em um mundo perfeito, você deve ser capaz de fazer as três mudanças necessárias em cada etapa. Aplique um ao ramo principal, deixe-o construir e implantar. Enquanto isso, aplique o segundo ao branch master, deixe-o construir e implantar e assim por diante, para que tudo aconteça no mesmo sprint, e se isso não acontecer, não é feito. Talvez até algo automático faça sentido onde você logicamente faz uma implantação, mas na verdade é dividido em 3.

por 30.05.2017 / 07:47
fonte
9

What I'm looking for is a way that a TODO comment can have a deadline against it, and our Continuous Integration system (current undecided which we'll use) would reject the build if this deadline was expired.

O que você está pedindo é factível se você estiver disposto a fazer o trabalho e seguir adiante.

// TODO by v55: Create migration to move constraints to new column, remove references to old column in app // TODO by v56: Create migration to drop old column

grep para //TODO by v55 quando chegar a hora de implantar o v55. Implementar compilar executa um script que faz isso como um teste de integração.

Você pode vincular 55 ao acompanhamento de sua versão ou apenas solicitá-lo.

É interessante se você quiser checar // TODO por v54 ao fazer 55. Ao invés disso, procure o código base 55 vezes apenas procure por // TODO by. Em seguida, filtre esse resultado de 1 a 55. Agora, 56 não acionará uma falha.

Você pode pensar "oh, não precisaremos disso. Vamos consertar isso todas as vezes, desde que tenhamos o cheque". Não, você não vai.

    
por 30.05.2017 / 02:43
fonte
4

Tivemos um problema muito semelhante em nossa equipe. Para resolver isso, nós escrevemos uma verificação de análise estática que lida com esses TODO's verificando o problema do JIRA ou Git Issue que eles referenciam. Nossa construção falha quando o problema especificado passa da coluna "Em desenvolvimento".

Portanto, podemos confortavelmente ter o TODO sem nos preocuparmos com o fato de ele ser esquecido.

Eu criei uma implementação de código aberto disso, em Java. Sim, um aviso é que eu escrevi isso, mas como eu disse, é totalmente aberto e licenciado.

A ferramenta é chamada Westie e um exemplo do verificador de problemas do Jira está no README.md. Veja também o GitIssueAnalyser.

Para evitar a autopromoção se você tiver mais alguma dúvida, envie-me uma mensagem. Se você decidir usá-lo e tiver alguma sugestão, apresente quaisquer problemas no github.

    
por 30.05.2017 / 19:43
fonte
4

Não faça. Faça agora.

TLDR: Grave (e teste) seus scripts de banco de dados agora, não mais tarde; apenas codifique-os para que sua execução seja dependente da versão do banco de dados.

Exemplo

Por exemplo, vamos imaginar que você queira alterar o nome de uma coluna de SSN para TaxID , um requisito comum quando for internacional.

Para que isso aconteça, talvez você tenha temporariamente as colunas TaxID e SSN . E, apesar de suportar ambas as versões, você terá um gatilho para atualizar um do outro. Mas você não quer manter esse gatilho indefinidamente, então, quando a compatibilidade com versões anteriores não for mais necessária, você deseja que o gatilho seja removido (e a coluna SSN caiu). Vamos codificar tudo isso sem precisar de itens ToDo.

Em nosso exemplo, estaremos implementando o build 102 (que tem a nova coluna), mantendo a compatibilidade com o build 101 (o que não funciona).

Aqui estão os passos.

1. Configurar tabela de versões

  1. Adicione uma única tabela chamada Configuration com duas colunas, Name e Value .

  2. Adicione uma linha com Name de "TargetVersion" e defina o Value para a versão da nova compilação a ser implantada.

  3. Adicione uma linha com um Name de "CompatibleWith" e defina o Value para o número de versão mínimo com o qual a implantação deve ser compatível.

Inspecione e atualize essas linhas antes de cada implantação.

2. Modifique os scripts de implantação

  1. Adicione um script que crie uma nova coluna de TaxID , lado a lado com SSN , e a preencha na coluna SSN . Coloque esse código em uma instrução If que verifica TargetVersion; se a versão de destino for muito baixa (ou seja, o TaxID ainda não é necessário), ignore.

    SELECT @TargetVersion = TargetVersion FROM Configuration
    IF @TargetVersion < '102' THEN RETURN
    ALTER TABLE Customer ADD COLUMN taxID VarChar(12) NOT NULL
    UPDATE Customer SET TaxID = SSN
    
  2. Adicione um script que crie um acionador que preencha TaxID ao inserir ou atualizar SSN e vice-versa. Coloque esse código em uma instrução If que verifique a versão de destino e a versão compatível; pule se TargetVersion for muito baixo (o TaxID não é necessário) ou se a versão CompatibleWith for muito alta (o campo SSN não é necessário).

    SELECT @TargetVersion  = TargetVersion,
           @CompatibleWith = CompatibleWith 
    FROM Configuration
    IF @TargetVersion  < '102' THEN RETURN
    IF @CompatibleWith > '101' THEN RETURN
    CREATE TRIGGER SSNAndTaxIDTrigger ON Customer etc.
    
  3. Adicione um script para remover a coluna SSN . Coloque em uma instrução If que remove a coluna somente se a versão CompatibleWith for alta o suficiente ( SSN não é mais necessário).

    SELECT @CompatibleWith = CompatibleWith FROM Configuration
    IF @CompatibleWith <= '101' THEN RETURN
    IF OBJECT_ID('SSNAndTaxIDTrigger') IS NOT NULL DROP TRIGGER SSNAndTaxIDTrigger
    IF EXISTS (SELECT * FROM syscolumns c JOIN sysobject o ON o.id = c.is WHERE o.Name = 'Custeomr' AND c.Name = 'SSN') BEGIN
        ALTER TABLE Customer DROP COLUMN SSN
    END
    

3. Testando

Não deixe de testar sua implantação com qualquer combinação de números de versão em azul / verde que você queira poder oferecer em produção. Você pode testar assim que o código estiver pronto, manipulando a tabela Configuration em seu ambiente de QA.

4. No seu manual de implantação

Adicione um passo para um engenheiro atualizar as linhas CompatibleWith version e TargetVersion. Se você estiver implantando no Blue, defina TargetVersion para o número de versão do Blue e a versão CompatibleWith para o número de versão do Green; reverta-os se estiver implantando o Green.

Armadilhas

Tudo bem que seus scripts de implantação façam referência e confiem nesses números de versão mantidos nessa tabela de banco de dados. NÃO código de tempo de execução.

Se você começar a escrever seu código de tempo de execução para inspecionar os números de versão, estará introduzindo um novo nível de complexidade em seu aplicativo que poderia potencialmente se tornar um grande problema de manutenção. Cada caminho de execução do tempo de execução deve ser testado; Se você levar essas condições adiante, a equipe de controle de qualidade terá que criar uma matriz de dor para validá-las com cada uma delas. lançamento. Meu conselho é manter condições como essas apenas em scripts de implantação.

O resultado de tudo isso

No final, você deve ser capaz de escrever todo o código na frente (e testá-lo também) sem medo de que ele seja executado muito cedo. Além disso, o código irá limpar o gatilho de compatibilidade com versões anteriores quando chegar a hora sem precisar se preocupar com isso ainda mais.

Desta forma, você pode escrever e testar todo o código na frente, quando você está pensando sobre isso, e você não precisa lidar com esses comentários bagunçados ToDo.

    
por 30.05.2017 / 20:59
fonte
1

Você está recebendo muitas críticas à sua ideia TODO, mas eu pessoalmente não vejo nenhum problema com isso. No final, a melhor (e mais fácil) maneira de garantir que a migração entre em produção é falhar em um teste de unidade, se não o fizer. Ele literalmente levará menos de um minuto para eliminar uma função de migração vazia que gera uma exceção se a versão for 55 ou mais (ou quaisquer que sejam os requisitos).

Então, se você tentar lançá-lo, terminará com um teste com falha e alguém precisará transformar essa exceção em um código de migração real.

    
por 02.06.2017 / 20:43
fonte
-2

Ninguém parece estar se concentrando na raiz de sua reclamação, que é o fato de que as alterações no banco de dados podem levar muitos ciclos de lançamento. Ele quer continuar com seu cronograma de implementação azul / verde e a solução já deve estar lá, mas a menos que eu esteja perdendo algo, sua descrição parece indicar que há apenas um banco de dados que é compartilhado por ambos os sistemas. Não é um verdadeiro sistema azul / verde, se for esse o caso. Uma vez que parece que o banco de dados é o polo longo da barraca, ele deve ser duplicado também, de modo que não importa quanto tempo ou quantos ciclos de lançamento sejam necessários para implementar as alterações do banco de dados no sistema off-line. totalmente testado. No sistema intermediário offline, os scripts podem manter o banco de dados offline totalmente atualizado diariamente.

    
por 30.05.2017 / 20:30
fonte