Come utilizzare gli interruttori flag funzione?


15

Quali sono i diversi modi di utilizzare gli interruttori flag delle funzionalità nelle applicazioni?

Se dovessi spiegare a uno sviluppatore le cose esatte che dovrebbero essere fatte al fine di passare dal nulla a un'applicazione completa con flag di funzionalità, quali sarebbero questi passaggi?

Risposte:


16

I flag delle caratteristiche sono un dispositivo di ingegneria che può essere utilizzato per evitare rami di lunga durata e conflitti nello sviluppo del prodotto. Ecco come può essere utilizzato il contesto di un linguaggio orientato agli oggetti per aiutare gli sviluppatori a collaborare su una specifica funzionalità del prodotto mentre si gestisce una nuova versione. Questa soluzione può essere utilizzata anche in contesti non orientati agli oggetti, purché esista una nozione di "interfaccia". ( cfr . sistema di moduli OCaml.)

A scopo illustrativo, assumiamo uno strumento che presenta report sui dati memorizzati in un database. Il codice implementa una classe DatabaseClient utilizzata per eseguire le richieste. Man mano che il set di dati cresce, diventa chiaro che alcuni layout di dati alternativi migliorerebbero le prestazioni dell'applicazione. Pertanto Alice svilupperà una nuova versione di DatabaseClient in grado di recuperare i dati dalle strutture con layout migliorato, mentre Bob manterrà lo storico DatabaseClient .

Con i seguenti passaggi, Alice e Bob possono collaborare su rami di breve durata minimizzando i loro conflitti.

  1. Alice rinomina DatabaseClient in DatabaseClient_v1 e crea una classe delegata denominata DatabaseClient che utilizza un oggetto DatabaseClient_v1 e implementa un'interfaccia denominata DatabaseClientInterface. (Se possibile, questo DatabaseClientInterface dovrebbe essere un artefatto di codice ma i linguaggi tipizzati da anatra non sempre lo supportano.)

  2. Bob esamina le modifiche apportate da Alice in 1 ed è consapevole che il suo lavoro di manutenzione dovrebbe avvenire su DatabaseClient_v1 .

  3. Alice introduce un nuovo flag di configurazione nell'applicazione che regola il comportamento del delegato DatabaseClient e implementa un segnaposto DatabaseClient_v2 , una classe che implementa DatabaseClientInterface i cui metodi generano un'eccezione "Non implementata".

Successivamente, Alice e Bob possono collaborare senza sincronizzazione esplicita, poiché il codice scritto nelle rispettive iterazioni è soggetto a DatabaseClientInterface . Ciò riduce al minimo il rischio di un conflitto derivante dal loro lavoro simultaneo.

Le iterazioni di Alice possono essere molto brevi, come l'implementazione di un test, l'implementazione di un metodo o anche parzialmente, poiché in produzione il codice non è selezionato per l'uso e non deve essere completamente funzionale. La suite di test automatizzata deve essere configurata in modo che DatabaseClientInterface utilizzi sempre DatabaseClient_v1 mentre Alice può facilmente passare a DatabaseClient_v2 quando si esegue la suite di test localmente o in un'impostazione CI personalizzata. Una volta che tutto è pronto, un singolo commit può eseguire la modifica, aggiornando il valore di configurazione che governa il delegato DatabaseClient .


7

I passaggi sono abbastanza "facili", per passare a un'app di flag di funzionalità sono necessarie sostanzialmente due cose:

  1. Un repository di flag (file / data base / variabile env)
  2. Dichiarazioni condizionali per modificare il comportamento in base alla bandiera.

La base del flag delle funzionalità è di accenderli / spegnerli, ma rapidamente vorrai rilasciare una nuova funzionalità in modo accelerato, ad esempio: 1 server su 5 che ospita l'app ha la funzione "on" per iniziare, quindi si attiva la funzione su un altro server, fino a quando tutti i server lo hanno "acceso".

Ciò significa che devi fare attenzione a che la tua funzionalità sia compatibile con l'app senza di essa (ad esempio colonna aggiuntiva nel DB).

I frame esistono in varie lingue per evitare di reinventare la ruota, quella ora non mantenuta di Etsy ha un readme interessante per spiegare come funziona.


2

Il mondo del software incorporato utilizza spesso flag di build-time, nel codice dell'app stesso ( #define/ #ifdefistruzioni, ad esempio) e / o nei file di configurazione degli strumenti di costruzione ( makefilead esempio,).

I flag di costruzione possono essere utilizzati, in modo simile, non solo per le funzionalità, ma anche per tutti i tipi di refactoring del codice, migrazioni, supporto per il debug, ecc.). Consentono di eseguire modifiche parziali o non verificate nel ramo di integrazione senza interrompere la build o causare regressioni nelle funzionalità / progetti già funzionanti nel ramo. Eccellente per gestire le correzioni dei punti insieme a cambiamenti di avanzamento grandi / rischiosi / lenti (che altrimenti richiederebbero un ramo di lunga durata) in una modalità di integrazione continua.

Ma oltre a verificare il codice di filiale già esistente per le regressioni, è anche possibile eseguire verifiche di avanzamento / stabilità del nuovo codice. Per questo è necessario attivare / disattivare i flag di build-time.

Un modo per attivare / disattivare i flag sarebbe quello di utilizzare, in una pipeline di verifica separata del sistema CI dello stesso ramo (se ha il supporto per tale funzionalità), un file patch che attiva / disattiva il flag - da applicare a un'area di lavoro separata prima del costruire. Un diverso set di artefatti verrebbe creato in questo spazio di lavoro e quindi verificato.

In alternativa, è possibile estrarre un ramo di funzionalità di lunga durata dal ramo di integrazione principale, ma l'unica modifica in questo ramo di funzionalità sarebbe la bandiera attivata / disattivata. Grazie a questa piccola modifica, il ramo delle funzionalità può essere sincronizzato automaticamente in modo estremamente rapido, praticamente oscurando molto da vicino il ramo di integrazione principale. Un'esecuzione CI separata su questo ramo non avrebbe più bisogno di un file patch preliminare. Sarebbe banale portare con sé tale ramo di funzionalità anche per un lungo periodo di tempo.

Potrebbe anche essere possibile creare, nel ramo di integrazione principale, nuovi artefatti di costruzione che sarebbero in realtà solo cloni degli artefatti di costruzione esistenti ma con le bandiere attivate. In questo modo né il file di patch preliminare né il ramo funzionalità sarebbero necessari per verificare il nuovo codice, proprio nel ramo principale.


1
Benvenuti nel mondo 1K-DevOps ... Usa i privilegi che ne derivano saggiamente ...
Pierre.Vriens
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.