Lingue concomitanti e dipendenze non concorrenti [chiuso]

0

Abbiamo avuto un bug causato da lavoratori ruby (4 processi, 1 thread ciascuno) che eseguivano i record di batch utilizzando un mongodb legacy come archivio. La condizione della gara era attorno al fatto che il gruppo fosse pieno o meno; con uno o tre record di nascosto in un batch. Questo è stato risolto bloccando correttamente (anche se ha rallentato un po 'le cose).

Per alcuni dei nostri servizi ho discusso il passaggio a una lingua con concurrence in-house ma come si progetta su dipendenze di terze parti che non sono concorrenti o si avvicinano alla concorrenza in modo diverso (ad esempio, il blocco).

Puoi creare una bella app concorrente e poi rovinare tutto condividendo lo stato altrove? Questo problema sarebbe stato evitato se avessimo usato Erlang / Elixir e Riak?

    
posta kreek 11.02.2016 - 19:06
fonte

1 risposta

1

Questa è una domanda molto ampia e devi essere consapevole che nessun linguaggio risolve automaticamente i problemi di concorrenza. È possibile scrivere applicazioni concomitanti basate su paradigmi di concorrenza esposti dal sistema operativo o eseguire problemi di concorrenza in un lingue orientate agli attori come Erlang. Ciò che ti offre Erlang sono astrazioni e strumenti migliori che rendono più facile ragionare sui problemi di concorrenza.

Prendi una cache semplice come esempio. Esistono centinaia di possibili implementazioni di tale cache in varie lingue. Ma è interessante osservare l'implementazione proposta in capitolo 6 dell'eccellente libro Erlang e OTP in azione . Propongono un'architettura in cui ogni chiave è memorizzata in un processo Erlang separato:

Your simple cache will store key/value pairs, where the keys are unique and each key maps to a single value. The core idea behind the design of this cache is that you'll use a separate process to store each value you insert and map each key to its corresponding process. You may consider it strange, even unbelievable, that you would use a process for each value like this; but for something like a cache, it makes sense, because every value may have its own life cycle. Erlang's support for large numbers of lightweight processes makes this approach possible.

Progettare e implementare correttamente le applicazioni concorrenti in Erlang può richiedere un po 'di cambiamento di mente, ma una volta imparato che è facile interfacciare Erlang con il mondo esterno.

Erlang non è solo un linguaggio, ma ancora più importante, una VM (in qualche modo simile a Java VM). Si chiama BEAM ed esegue moduli compilati di Erlang. Ecco perché i processi leggeri di Erlang sono possibili: sono astrazioni fornite da BEAM su thread e processi del sistema operativo.

Ma i processi non sono l'unica astrazione disponibile. BEAM espone TCP e UDP socket di rete, anche SCTP possono essere facilmente programmati. Permette di interrogare DNS , interfacce di rete o interfaccia a processi esterni tramite porte . Espone inoltre un'API completa per operare sui file . Questo è un elenco completo di moduli disponibili in OTP , senza menzionare quelli disponibili in applicazioni esterne.

Vedi l'implementazione di yexec: sh_cmd / 1 come esempio. Esegue un comando esterno e raccoglie il risultato della sua esecuzione (output standard e codice di errore) usando le porte di Erlang. Può essere eseguito in parallelo, come in yolf_p: call / 4 o < a href="https://github.com/yoonka/builderl/blob/master/src/bld_lib.erl#L535"> bld_lib: call / 2 , che genera un nuovo processo di Erlang per ogni elemento nel elenco. Questo può essere usato per avviare più comandi git clone simultaneamente, come bld_deps: do_start / 1 fa.

Lo stesso principio vale quando si utilizzano socket di rete o descrittori di file. Non è insolito per le applicazioni di Erlang tenere aperte dozzine di migliaia di socket o descrittori di file allo stesso tempo. Vedi Riak come esempio.

Se l'interfaccia attraverso le porte non è sufficiente, Erlang supporta l'esecuzione di applicazioni C esterne direttamente nei principali processi BEAM VM attraverso il cosiddetto NIF librerie . Questo documento delinea le opzioni per l'interoperabilità con le applicazioni scritte in altre lingue. Yajler è un esempio di un modulo NIF che consente ai processi di Erlang di analizzare JSON utilizzando il < a href="https://lloyd.github.io/yajl/"> yajl libreria scritta in C.

Riassumendo, è certamente possibile scrivere le parti concorrenti in Erlang e gestire le applicazioni esterne attraverso il livello di astrazione fornito da OTP e BEAM. Se è possibile nella tua applicazione molto dipende dall'architettura di tale applicazione e dalla quantità di stato condiviso che puoi portare e reimplementare in Erlang.

    
risposta data 12.02.2016 - 12:51
fonte