Sperimentazione progressiva con flag di funzionalità

Man mano che i team di DevOps passano a una metodologia Agile incentrata sul recapito continuo delle funzionalità, la necessità di controllare come diventano disponibili agli utenti diventa sempre più importante. I flag di funzionalità sono una soluzione ideale per limitare l'accesso degli utenti alle nuove funzionalità, sia per scopi di marketing che per i test nell'ambiente di produzione.

Disaccoppiamento della distribuzione e dell'esposizione

Con i flag di funzionalità, un team può scegliere se un determinato set di funzionalità è visibile nell'esperienza utente e/o richiamato all'interno della funzionalità. Le nuove funzionalità possono essere compilate e distribuite come parte del normale processo di sviluppo senza che tali funzionalità siano disponibili per l'accesso generale. La distribuzione delle funzionalità è convenientemente disaccoppiata dall'esposizione.

I flag forniscono il controllo di runtime a un singolo utente

I flag forniscono anche un controllo granulare fino all'utente singolo. Quando è il momento di abilitare una funzionalità, sia per un utente, un piccolo gruppo o tutti, il team può semplicemente modificare il flag di funzionalità per accenderlo senza dover ridistribuire.

L'ambito di un flag di funzionalità varia in base alla natura della funzionalità e al gruppo di destinatari. In alcuni casi, un flag di funzionalità abiliterà automaticamente la funzionalità per tutti. In altri casi, una funzionalità verrà abilitata in base all'utente. Teams può anche usare flag di funzionalità per consentire agli utenti di acconsentire esplicitamente all'abilitazione di una funzionalità, se lo desiderano. Non esiste un limite al modo in cui vengono implementati i flag di funzionalità.

Supporto di feedback e sperimentazione iniziali

I flag di funzionalità sono un ottimo modo per supportare la sperimentazione anticipata. Alcune caratteristiche possono avere bordi grezzi all'inizio, che possono essere interessanti solo per i primi degli adottanti. Il tentativo di spingere queste funzionalità non abbastanza pronte a un pubblico più ampio potrebbe produrre insoddisfazione. Ma il vantaggio di raccogliere feedback dagli utenti disposti a gestire una funzionalità in corso è prezioso.

Interruttore rapido disattivato

A volte è utile essere in grado di disattivare qualcosa. Si supponga, ad esempio, che una nuova funzionalità non funzioni come previsto e che si verifichino effetti collaterali che causano problemi altrove. È possibile usare i flag di funzionalità per disattivare rapidamente la nuova funzionalità per eseguire il rollback al comportamento attendibile senza dover ridistribuire. Anche se i flag di funzionalità sono spesso considerati in termini di funzionalità dell'interfaccia utente, possono anche essere usati facilmente per le modifiche apportate all'architettura o all'infrastruttura.

Fasi standard

Microsoft usa un processo di implementazione standard per attivare i flag di funzionalità. Esistono due concetti distinti: gli anelli sono per le distribuzioni e le fasi sono per i flag di funzionalità. Altre informazioni sugli anelli e le fasi.

Le fasi riguardano la divulgazione o l'esposizione. Ad esempio, la prima fase potrebbe essere relativa all'account di un team e agli account personali dei membri. La maggior parte degli utenti non visualizzerebbe nulla di nuovo perché l'unico flag di posizione è attivato per questa prima fase. In questo modo un team può usare e sperimentare completamente con esso. Dopo la disconnessione del team, selezionare i clienti che potranno acconsentire esplicitamente tramite la seconda fase dei flag di funzionalità.

Consenso esplicito

È consigliabile consentire agli utenti di acconsentire esplicitamente ai flag di funzionalità quando possibile. Ad esempio, il team può esporre un pannello di anteprima associato alle preferenze o alle impostazioni dell'utente.

Screenshot of opt-in preview pane.

Usare i flag con i dati di telemetria

I flag di funzionalità consentono di esporre in modo incrementale gli aggiornamenti. Tuttavia, i team devono monitorare continuamente le metriche corrette per misurare l'idoneità per un'esposizione più ampia. Queste metriche devono includere il comportamento di utilizzo, nonché l'impatto degli aggiornamenti sull'integrità del sistema. È importante evitare la trappola di presupporre che tutto sia ok solo perché nulla di male sembra accadere.

Esempio di flag di funzionalità

Si consideri l'esempio seguente. Il team ha aggiunto un paio di pulsanti qui per Cherry-pick e Revert nell'interfaccia utente della richiesta pull. Questi sono stati distribuiti usando i flag di funzionalità.

Screenshot of pull request UI example.

Definire i flag di funzionalità

La prima funzionalità esposta è il pulsante Ripristina . La soluzione usa un file XML per definire tutti i flag di funzionalità. In questo caso è presente un file per servizio, che crea un incentivo per rimuovere i vecchi flag per impedire che la sezione venga effettivamente lunga. Il team eliminerà i vecchi flag perché esiste una motivazione naturale per controllare le dimensioni del file.

<?xml version="1.0" encoding="utf-8"?>
<!--
  In this group we should register Azure DevOps specific features and sets their states.
-->
<ServicingStepGroup name="AzureDevOpsFeatureAvailability" … >
  <Steps>
    <!-- Feature Availability -->
    <ServicingStep name="Register features" stepPerformer="FeatureAvailability" … >
      <StepData>
        <!--specifying owner to allow implicit removal of features -->
        <Features owner="AzureDevOps">
           <!-- Begin TFVC/Git -->
           <Feature name="SourceControl.Revert" description="Source control revert features" />

Un framework server comune incoraggia il riutilizzo e le economie di scalabilità in tutto il team. Idealmente, il progetto avrà l'infrastruttura sul posto in modo che uno sviluppatore possa semplicemente definire un flag in un archivio centrale e disporre del resto dell'infrastruttura gestita per loro.

Controllare i flag di funzionalità in fase di esecuzione

Il flag di funzionalità usato qui è denominato SourceControl.Revert. Ecco il TypeScript effettivo di quella pagina che illustra la chiamata a un controllo di disponibilità delle funzionalità.

private addRevertButton(): void {
 if (FeatureAvailability.isFeatureEnabled(Flags.SourceControlRevert)) {
     this._calloutButtons.unshift(
         <button onClick={ () => Dialogs.revertPullRequest(
             this.props.repositoryContext,
             this.props.pullRequest.pullRequestContract(),
             this.props.pullRequest.branchStatusContract().sourceBranchStatus,
             this.props.pullRequest.branchStatusContract().targetBranchStatus)
         }
         >
             {VCResources.PullRequest_Revert_Button}
         </button>
        );
     }
}

Nell'esempio precedente viene illustrato l'utilizzo in TypeScript, ma è possibile accedervi facilmente usando C#. Il codice verifica se la funzionalità è abilitata e, in tal caso, esegue il rendering di un pulsante per fornire la funzionalità. Se il flag non è abilitato, il pulsante viene ignorato.

Controllare un flag di funzionalità

Una buona piattaforma di flag di funzionalità fornirà diversi modi per gestire se è impostato un determinato flag. In genere, esistono scenari di utilizzo per il flag da controllare tramite PowerShell e l'interfaccia Web. Per PowerShell, tutto ciò che deve essere effettivamente esposto è un modo per ottenere e impostare lo stato di un flag di funzionalità, insieme ai parametri facoltativi per elementi come identificatori di account utente specifici, se applicabile.

Flag di funzionalità di controllo tramite l'interfaccia utente Web

L'esempio seguente usa l'interfaccia utente Web esposta per questo prodotto dal team. Prendere nota del flag di funzionalità per SourceControl.Revert. Qui sono elencati due account personali: hallux e buckh-westeur. Lo stato è impostato per hallux, che si verifica nel Centro settentrionale e cancellato per l'altro account in Europa occidentale.

Screenshot of controlling feature flags through web UI.

La natura del flag di funzionalità determina la modalità di esposizione delle funzionalità. In alcuni casi, l'esposizione seguirà un anello e un modello di fase. In altri utenti, gli utenti possono acconsentire esplicitamente tramite l'interfaccia utente di configurazione o anche inviando un messaggio di posta elettronica al team per l'accesso.

Considerazioni per i flag di funzionalità

La maggior parte dei flag di funzionalità può essere ritirata dopo che una funzionalità è stata implementata a tutti. A questo punto, il team può eliminare tutti i riferimenti al flag nel codice e nella configurazione. È consigliabile includere una revisione del flag di funzionalità, ad esempio all'inizio di ogni sprint.

Allo stesso tempo, potrebbe essere presente un set di flag di funzionalità che vengono mantenuti per vari motivi. Ad esempio, il team potrebbe voler mantenere un flag di funzionalità che dirama un elemento infrastrutturale per un periodo di tempo dopo il passaggio completo del servizio di produzione. Tenere tuttavia presente che questo potenziale percorso di codice potrebbe essere riattivato in futuro durante una cancellazione esplicita del flag di funzionalità, quindi deve essere testato e mantenuto fino a quando l'opzione non viene rimossa.

Flag di funzionalità e strategia di diramazione

I flag di funzionalità consentono ai team di sviluppo di includere funzionalità incomplete in main senza influire su altri utenti. Purché il percorso di codice sia isolato dietro un flag di funzionalità, è in genere sicuro compilare e pubblicare il codice senza effetti collaterali che influiscono sull'utilizzo normale. Tuttavia, se ci sono casi in cui una funzionalità richiede dipendenze, ad esempio quando si espone un endpoint REST, i team devono considerare il modo in cui tali dipendenze possono creare operazioni di sicurezza o manutenzione anche senza che la funzionalità venga esposta.

Flag di funzionalità per attenuare il rischio

A volte nuove funzionalità hanno il potenziale di introdurre cambiamenti distruttivi o distruttivi. Ad esempio, il prodotto può essere in fase di trasformazione da uno schema di database wide a uno lungo. In questo scenario, lo sviluppatore deve creare un ramo di funzionalità per un periodo di tempo ridotto. Apportano quindi le modifiche destabilizzanti nel ramo e mantengono la funzionalità dietro un flag. Una pratica comune è che i team possano unire le modifiche fino a main quando non causano danni. Questo non sarebbe fattibile senza la possibilità di mantenere nascosta la funzionalità non completa dietro un flag di funzionalità.

I flag di funzionalità consentono di lavorare in modo principale

Se si seguono le procedure di buon senso descritte nella fase di sviluppo , lavorare in main è un buon modo per rafforzare un ciclo DevOps. In combinazione con i flag di funzionalità, gli sviluppatori possono unire rapidamente le funzionalità upstream ed eseguirne il push attraverso il gauntlet di test. Il codice di qualità può essere pubblicato rapidamente per i test nell'ambiente di produzione. Dopo alcuni sprint, gli sviluppatori riconosceranno i vantaggi dei flag di funzionalità e li useranno in modo proattivo.

Come decidere se usare un flag di funzionalità

I team delle funzionalità possiedono la decisione relativa alla necessità di un flag di funzionalità o meno per una determinata modifica. Non ogni modifica richiede una modifica, quindi è una richiesta di giudizio per uno sviluppatore quando scelgono di apportare una determinata modifica. Nel caso della funzionalità Ripristina descritta in precedenza, era importante usare un flag di funzionalità per controllare l'esposizione. Consentire ai team di prendere decisioni chiave sull'area di funzionalità fa parte dell'abilitazione dell'autonomia in un'organizzazione DevOps efficace.

Compilazione e acquisto

Sebbene sia possibile creare un'infrastruttura di flag di funzionalità personalizzata, è consigliabile adottare una piattaforma come LaunchDarkly o Split . È preferibile investire nella creazione di funzionalità invece di ricompilare le funzionalità del flag di funzionalità.

Passaggi successivi

Altre informazioni sull'uso dei flag di funzionalità in un'app ASP.NET Core.