Bentornato SQL Server

E’da un po’ di tempo che ho in mente di scrivere questo post. Come al solito, sono in ritardo :)
Vediamo di rimediare…

Chi mi conosce sa che, fin da tempi non sospetti, sono stato un “acceso” sostenitore di mongodb.
Al tempo mi aveva attirato per la sua semplicità di utilizzo, dall’installazione all’interazione stessa: un veloce download e l’esecuzione dell’engine è a distanza di un click.

Prima che orde di DBA inferociti mi rincorrano alla prossima conferenza, ci tengo a sottolineare che comprendo perfettamente la necessità di un’installazione e configurazione accurata di qualsiasi strumento, database in primis. Ciò non nega il fatto che, in fase di sviluppo, un processo di setup molto lungo/complesso o un’interazione non ottimale introducono una frizione che impatta sulla produttività stessa del team.

Tornando a noi…negli ultimi anni MS, con SQL server, ha fatto un lavoro incredibile, migliorando di versione in versione l’engine, e introducendo una serie di feature che hanno fatto scalare a SQL Server la mia personale classifica, portandolo nuovamente nelle primissime posizioni.

SQL Server e docker

Con l’introduzione e il supporto a docker, in un colpo solo, MS ha risolto tutte le mie frustrazioni per un’installazione silent di SQL, in modo automatico tramite per esempio vagrant. Chiunque ci abbia mai provato, sa di cosa sto parlando…potrebbe essere il topic per un nuovo post.
Con la possibilità di eseguire l’engine di SQL all’interno di un container docker, la frizione per un nuovo dev che deve fare setup dell’infrastruttura prima di poter fare F5 è a distanza di uno script.

SQL Server e il supporto a json

Altra “frustrazione frustrante” per noi dev è la famosissima impedence mismatch tra modello relazionale e modello object-oriented, che ci ha portato, nel corso degli anni a provarle un po’ tutte, passando da StoredProcedure agli ORM più o meno light e a…chi più ne ha più ne metta.
Il modello documentale, tipico di MongoDB e altri db no-sql, risolvono up-front questa difficoltà: niente tabelle e relazioni, ma documenti.
Da un paio di versioni, però, anche SQL Server ha il supporto nativo a json, con la possibilità di indicizzare attributi del documento a diverso livello di profondità garantendo al contempo un modello diverso da quello relazionale (quello documentale, appunto) e ottime performance.

SQL Server e il modello a grafo

Un nuovo modello si è aggiunto a quelli supportati: il modello a grafo. L’engine è lo stesso ma l’approccio è sostanzialmente differente: anche in questo caso vige la regola per cui diversi scenari hanno necessità differenti e soluzioni/tool diversi.
Il fatto di avere un’unica tecnologia che li supporti tutti è un grande vantaggio, perchè permette di limitare le componenti infrastrutturali del sistema e quindi abbassare il costo della manutenzione e del monitoring.
Nulla vieta ovviamente di valutare ulteriori tool qualora lo scenario da approcciare sia così specifico da non potere essere risolto con una tecnologia “cross”. A questo punto il costo di un nuovo componente è assolutamente compensato dalla specificità dello scenario e dai benefici introdotti da un tool specifico.

SQL Server e Azure

Ho lasciato volutamente per ultimo questo punto, ma ciò non significa che abbia meno importanza dei precedenti. Anzi…assume un ruolo cardine nelle mie scelte quando l’applicazione che sto progettando e su cui sto lavorando deve “funzionare nel cloud”.
In questo scenario avere SQL Server, in modalità PaaS è “tanta roba”: significa potersi dimenticare di configurazione e monitoraggio perchè forniti direttamente dalla piattaforma. Significa poter sfruttare tutte le metriche raccolte dalla piattaforma stessa su tutti i servizi SQL Database attivati da tutti gli utenti, per ottimizzare o suggerire ottimizzazioni sulla nostra istanza. Significa avere un livello del servizio difficilmente ottenibile in uno scenario on-premise.

Tante altre sono le caratteristiche interessanti di SQL Server (infatti non abbiamo parlato di In-Memory OLTP o Columnstore indexes)…diciamo che il pretesto del post era di riportare nella giusta prospettiva il mio modo di vedere e approcciare l’utilizzo di SQL Server.
Che posso dire: “Welcome back SQL Server”…certi amori non finiscono, fanno dei giri immensi ma poi ritornano :D

Reactjs Redux pattern

React and Redux

ReactJs e’ diventato in breve tempo una delle più diffuse librerie per sviluppare applicazioni web. Ho usato il termine libreria per marcare la differenza che React ha con framework piu’ esaustivi quali ad esempio AngularJS. Proprio per il fatto che ReactJs e’ una libreria, il suo scope e’ legato esclusivamente alla generazione delle View di un ipotetico framework MV*. Questo ha un duplice vantaggio: ci permettere di scegliere quale altra libreria affiancare a ReactJs per l’implementazione delle nostre applicazioni (chiamata alle api, servizi, utilities, ecc…) e lascia liberta’ di disegnare l’architettura più adatta all’applicazione che si sta sviluppando. Quindi non siamo vincolati ad usare architetture complesse per semplici applicazioni, ma possiamo usare React e poco altro per piccole applicazioni e usare Flux e Redux per applicazioni più complesse. Redux e’ oggi lo standard di fatto anche se talvolta può essere troppo complesso, prolisso o “pesante” per applicazioni di medie dimensioni. Redux resta comunque una ottima implementazione basata su pochi chiari principi che rendono l’applicazione semplice, testabile e manutenibile. In questo breve articolo mi piacerebbe mostrarvi un’implementazione di redux che usiamo in CodicePlastico che e’ completamente aderente ai principi di Redux ma che rimane più semplice e meno prolissa.

I principi di redux sono:

  • Esiste un unico stato: i componenti di react non usano this.state ma lo stato viene memorizzato esternamente al componente e gli viene passato dall’esterno sotto forma di proprietà.
  • Lo stato e’ read-only: l’unico modo di cambiare lo stato e’ quello di inviare un’azione e far si che chi riceva l’azione crei il nuovo stato
  • La trasformazione dello stato e’ fatto da funzioni pure

Come potete vedere i principi sono molto semplici e Redux di fatto non fa altro che fornire alcuni moduli che semplificano la loro applicazione.

Un po’ di codice

Partiamo da un esempio implementato con l’uso dello stato internamente al componente per poi rifattorizzarlo verso un’architettura in puro stile redux. Il componente e’ questo:

class MyCounter extends React.Component {
  constructor() {
	  super()
    this.state = { counter: 0 }
  }
  plusOne() {
    this.setState({counter: this.state.counter + 1})         
  }
  render() {
    return (
     <div>
      <div>Click count: {this.state.counter}</div>
      <button onClick={this.plusOne.bind(this)}>Add 1</button>
    </div>)
  }
}

Questo componente mostra un bottone che se cliccato incrementa il valore del contatore visualizzato sopra il bottone stesso. L’implementazione e’ quella classica con l’uso dello stato per memorizzare il valore del contatore. Pur non essendoci nulla di male in questa implementazione (specialmente per il caso in questione) in casi più complessi la gestione dello stato non si limita ad una sola chiamata a setState ma a diverse chiamate in tempi diversi e con logiche (e molti if).

Il primo principio di redux sottintende che lo stato sia tenuto fuori dal componente e che venga passato al componente MyCounter attraverso l’uso delle props. Possiamo quindi introdurre un componente esterno che “wrappa” il nostro counter:

class WithState extends React.Component { 
  constructor() {
	  super()
    this.state = { counter: 0 }
  }
  plusOne() {
    this.setState({counter: this.state.counter + 1})         
  }
  render() {
    return (
      <MyCounter value={this.state.counter} onPlusOne={this.plusOne.bind(this)} />
     )
  }
}

class MyCounter extends React.Component {
  render() {
    return (
     <div>
      <div>Click count: {this.props.value}</div>
      <button onClick={this.props.onPlusOne}>Add 1</button>
    </div>)
  }
}

In questo modo il componente MyCounter non fa più uso dello stato e potrebbe essere scritto sotto forma di funzione semplificando ulteriormente la sua implementazione:

function MyCounter({value, onPlusOne}) {
   return (
     <div>
      <div>Click count: {value}</div>
      <button onClick={onPlusOne}>Add 1</button>
    </div>)
}

Ma abbiamo un problema. Il componente WithState non e’ riutilizzabile per altri componenti avendo al suo interno conoscenza di alcune cose:

  • Il componente che sta “wrappando”
  • La forma dello stato
  • La funzione che modifica lo stato (plusOne)

Vediamo come risolvere questi tre problemi. Partiamo dal terzo punto: dobbiamo rimuovere la logica di modifica dello stato dal componente WithState Nei principi di redux si dice che per modificare lo stato bisogna scatenare un’azione che verra’ gestita da funzioni chiamate reducer. L’idea di inviare azioni proviene dall’architettura unidirezionale di Flux che ha gettato le basi anche per redux. L’idea e’ quella di introdurre un dispatcher che si occupa di inoltrare le richieste di azioni a tutti coloro che sono interessati. Una semplicissima (e semplificata) implementazione di un dispatcher può essere questa:

const dispatcher = {
  subscribers: [],
  register(subscriber) {
    this.subscribers.push(subscriber)
  },
  dispatch(action) {
    this.subscribers.forEach(s => s(action))
  }
}

Il suo ruolo e’ quello di ricevere una richiesta di dispatch da parte di un componente e inoltrare la richiesta a tutte le funzioni interessate all’azione. Il reducer prenderà’ l’azione (e lo stato corrente) e ritornerà il nuovo stato. Una prima idea potrebbe essere quella di lasciare al componente WithState l’applicazione del reducer:

function counterReducer(state, action) {
  return {counter: state.counter + action.value}  
}

class WithState extends React.Component { 
  constructor() {
	  super()
    this.state = { counter: 0 }
  }
  componentWillMount() {
    dispatcher.register(action => {
      const nextState = counterReducer(this.state, action)
      this.setState(nextState)
    })
  }
  render() {
    return (
      <MyCounter value={this.state.counter}  />
     )
  }
}

function MyCounter({value, onPlusOne}) {
   return (
     <div>
      <div>Click count: {value}</div>
      <button onClick={() => dispatcher.dispatch({value: 1})}>Add 1</button>
    </div>)
}

In questo modo abbiamo portato all’esterno la logica di modifica dello stato. Ora non ci resta che generalizzare portando fuori la definizione dello stato iniziale, il componente wrappato e il riferimento alla funzione reducer (che ora e’ cablata in WithState). Per estrapolare quelle informazioni possiamo scrivere una funzione che prende i 3 parametri (nome del componente, stato iniziale, la funzione che modifica lo stato) e ritorna il nuovo componente WithState opportunamente configurato.

function counterReducer(state, action) {
  return {counter: state.counter + action.value}
}

function createWithState(WrappedComponent, reducer, INITIAL_STATE) {
  return class WithState extends React.Component { 
    constructor() {
	    super()
      this.state = INITIAL_STATE
    }
    componentWillMount() {
      dispatcher.register(action => {
        const nextState = reducer(this.state, action)
        this.setState(nextState)
      })
    }
    render() {
      return (
        <WrappedComponent {...this.state}  />
      )
    }
  }
}

function MyCounter({counter}) {
   return (
     <div>
      <div>Click count: {counter}</div>
      <button onClick={() => dispatcher.dispatch({value: 1})}>Add 1</button>
    </div>)
}
     
const MyComponent = createWithState(MyCounter, counterReducer, {counter: 0})

Con questo ultimo giro di refactoring il componente WithState e’ completamente all’oscuro del componente MyCounter ed e’ in grado di fare da wrapper a qualsiasi altro componente. Ciao’ che varia e’ il componente wrappato, il reducer che si occupa di creare il nuovo stato, e la forma dello stato. Questi sono i tre parametri della funzione createWithState.

Questa implementazione e’ molto semplificata ma con un pizzico di sofisticazione in più si riesce a scrivere un modulo pronto ad essere utilizzato in produzione e a supportare la casistica di applicazioni molto complesse. La nostra implementazione la trovate qui: t-redux e se date un’occhiata al codice ritroverete tutti i concetti spiegati in questo articolo.

Redux e’ leggermente più complesso ha il concetto di store, di selectors e poco altro ma la sua implementazione, almeno nei concetti e principi e molto simile a quanto presentato in questo post. Una cosa che mi piace sempre ricordare e’ che e’ molto piu’ importante imparare i principi e i pattern utilizzati invece che imparare ad usare una libreria, questo perché i principi restano e le librerie passano (soprattutto nel mondo javascript). Ad esempio Redux implementa molti principi utilizzati in architetture basate su eventsourcing, CQRS e programmazione funzionale, inventate anni fa….come al solito non si inventa quasi mai nulla, si adattano e riusano vecchi concetti.

CodicePlastico e il nostro processo di hiring

Ho letto con molto interesse il post degli amici di Gummy con un po’ di suggerimenti su cosa non fare per aumentare le proprie possibilità di essere presi in considerazione durante il loro processo di recruiting.

Ci sono diversi passaggi che condivido in pieno e che si sposano perfettamente anche alla realtà che vivo tutti i giorni, quella di CodicePlastico:

…siamo un team piccolo, ogni persona che aggiungiamo cambia la nostra struttura in modo sostanziale…

…scegliere le persone è veramente difficile. È un processo faticoso e la possibilità di sbagliare è altissima…

Con questi presupposti, il processo di hiring assume un ruolo fondamentale e in CodicePlastico, di iterazione in iterazione, stiamo cercando di renderlo sempre più affidabile, attingendo anche da esperienze personali, come per esempio quello che ho potuto “toccare con mano” collaborando con i ragazzi di Particular per circa un anno.

Il nostro processo di hiring è generalmente suddiviso in diversi step:

Un primo colloquio conoscitivo, per le dovute presentazioni. In questo modo il candidato può raccontarci un po’ di lui, spiegarci le sue eseperienze, sottolineare cosa gli piace fare e cosa no. E’un modo, anche per noi, per presentare il nostro team, per spiegare come lavoriamo e in quali scenari, quali tecnologie utilizziamo e quali ci piacerebbe utilizzare.
Come scriveva Mauro in un suo post, obbiettivo di questo “incontro” è quello di trovare i no secchi.
Quindi “caro candidato” se ti presenti con mezz’ora di ritardo al colloquio, se chiacchierando mi dici che sei un buon grafico/designer perchè conosci abbastanza bene jQuery, oppure se fai scena muta e non sei capace di gestire una conversazione (non tecnica)…bhe, allora non dare colpa alla crisi.

Al termine del primo incontro, se c’è interesse reciproco a continuare (si, reciproco…ad alcune persone non sempre possiamo andare a genio) scegliamo un kata su cui il candidato potrà lavorare da casa, senza fretta, con la tecnologia che preferisce, con gli strumenti che preferisce. Senza pressione.
Terminato l’esercizio, basta pushare quanto prodotto sul proprio account github e mandarci una mail per dare il via al prossimo step.
Quindi “caro candidato” se quando ti diciamo di pushare su github ci guardi come se ti avessimo detto una parolaccia, se ti lamenti del fatto che ti facciamo lavorare fuori dall’orario lavorativo, se dopo cinque mesi stiamo ancora aspettando la mail con il link al tuo lavoro…bhe, allora non dare colpa alla crisi.

Terzo step: se hai concluso il kata (e soprattutto ci hai mandato la mail per dircelo) c’è sempre un terzo step. Hai lavorato? E’ giusto confrontarci per capire il tuo approccio alla soluzione, farti le nostre domande e osservazioni.
Questo passaggio è per noi fondamentale perchè permette di iniziare a conoscere la persona che abbiamo di fronte: il nostro è un lavoro di team, è impensabile poter inserire in modo proficuo una persona che non accetti, per esempio, osservazioni/domande sul proprio operato.
Al termine di questa prima review, passiamo ad un esercizio pratico, un nuovo kata, da fare insieme. Questo ci permette di capire un po’ di più sul reale livello tecnico del candidato, la sua “dimestichezza con la tastiera” e soprattutto il “livello di connettività” tra il cervello e le mani, considerando nella valutazione anche la variante “pressione”.
Al termine di questo step c’è la prima, vera scrematura. Obbiettivo di questo incontro è trovare i probabili sì

Ultimo incontro: bhe se sei arrivato qui, diciamo che abbiamo alte possibilità di essere compatibili, almeno dal nostro punto di vista.
L’ultimo incontro è più una chiacchierata, non solo tecnica. Potrebbe capitare di pensare insieme ad una soluzione, anche architetturale, ad uno dei problemi su cui stiamo lavorando, oppure parlare di metodologia, oppure di panzerotti.
Sicuramente in questo incontro si parla di soldi e di tutto quello che ci serve per formalizzare una “lettera d’intenti”.

Questo è il nostro processo. Può essere migliorato? Sicuramente sì…ci sono già nuove idee in cantiere. Per esempio coinvolgere anche il resto del team nella valutazione, cosa che adesso avviene solo raramente (se io o emanuele non siamo presenti). Magari fare il kata in pair con uno “di noi”, oppure…

Tutto il processo richiede un po’ di tempo. Nè troppo, nè poco. Ma è un investimento. E’una cosa di cui non possiamo fare a meno, per abbassare, almeno un po’, le possibilità di errore.

Ah dimenticavo…se sei interessato, noi siamo sempre alla ricerca di nuovi super eroi :)

Global Azure Bootcamp 2017 e non solo...

La scorsa settimana ho avuto il piacere e l’onore di partecipare al Global Azure Bootcamp a Pordenone organizzato dagli amici di Innova. Un evento sul cloud, un evento su Azure. Un evento ricco di spunti interessanti e anche la consueta occasione per rivedere vecchi amici e incontrarne di nuovi.

Nel corso della mattinata ho avuto l’occasione di parlare di docker e di come sfruttare i servizi messi a disposizione da Azure per poter ottimizzare “l’esperienza del dev” nel corso di tutto il ciclo di sviluppo di un’applicazione.
Abbiamo quindi parlato di Azure Container Registry per la persistenza e la gestione delle immagini docker prodotte. Abbiamo visto Azure Container Service come piattaforma per il deploy e la gestione di un cluster docker, con Docker Swarm. Abbiamo “chiuso il cerchio” definendo una pipeline di CI/CD con Visual Studio Team Services: dalla modifica del codice, al deploy in un click.

Questa volta non ero il solo (pazzo?) a parlare di docker :) Maksim Sinik ha tenuto un bellissimo talk su kubernetes e sulla sua intgrazione con Azure Container Service.

La sensazione è che in Italia si parli, e soprattutto si utilizzi, ancora poco docker. Attenzione, non è sicuramente la panacea a tutti i mali: se una codebase è un colabrodo, con docker la situazione non migliora, anzi…
Ma non si può pensare di vivere in “questo mondo” e non essere a conoscenza di questo potente strumento (my 2 cents)

Ed ora? Non ci si ferma mai…la prossima settimana, con gli amici di UgiDotNet saremo a Milano con un evento interamente dedicato al cloud.
L’agenda non è per nulla male e copre diversi aspetti dell’ecosistema “cloud”: dai dati alla parte compute, dai container alle strategie di migrazione…insomma tutti gli ingredienti per trasformare una semplice giornata in una giornata interessante e proficua.

Insomma…vi aspetto!!!

Docker & Azure

Venerdì 10 febbraio sarò a Roma dagli amici di DomusDotNet e GetLatestVersion per una ricca giornata di contenuti sul tema DevOps.

Nel mio piccolo terrò una sessione su Docker e Azure. L’abstract è abbastanza esplicativo (almeno credo):

Hai visto un paio di tutorial introduttivi su docker? Sai come avviare un container o come creare una nuova immagine partendo da una gia’ presente sul docker hub? Ma vuoi saperne di piu’…questa e’ la sessione che fa per te: analizzeremo casi reali di utilizzo congiunto di docker e Azure, quali per esempio l’integrazione nella pipeline di Continuous Integration, come creare un hub privato o come supportare scenari di scale-out.

L’idea non è quella di un tutorial passo-passo e introduttivo sul mondo dei container e di Docker nello specifico. Vuole portare la mia esperienza in uno scenario mediamente complesso su cui stiamo lavorando in CodicePlastico e su come, Docker e Azure, possono semplificare la vita del team, sia nella fase di sviluppo, sia nella fase di operation e di gestione dei deploy.

Non è la prima volta che tengo questo talk, ma non è mai successo che due sessioni consecutive avessero lo stesso contenuto: l’ecosistema di Docker e il supporto che Azure ne dà sono in continua evoluzione. Ad ogni “giro” una nuova versione di Docker o un nuovo servizio di Azure a mantenere vivo (spero) l’interesse di chi partecipa e la necessità da parte mia di aggiornare slide e demo :D

Se non ti sei iscritto, forse sei ancora in tempo: https://www.eventbrite.it/e/biglietti-devopswork-2017-30931208076

Vi aspetto!!