Come approccio i plugin poliglotta alle applicazioni python asincrone?

2

Ho cercato modi per consentire agli utenti della mia app di scrivere plug-in per questo. Tuttavia, per dare loro più opzioni, ho deciso di implementare un sistema di plugin poliglotta.

Dal punto di vista dell'ingegneria ci sono molti modi per farlo.

  • Transpiling: non ci sono molte librerie che possono farlo in modo affidabile.
  • Associazioni: i tipi possono essere un problema.
  • Uso delle API: sembra il percorso più semplice, ma i plugin diventano complessi.

Un metodo a cui pensavo era di usare i kernel di Jupyter. Invio di messaggi (tramite IPC) tra loop di eventi già eseguiti nei rispettivi interpreti. Voglio solo supportare linguaggi interpretati / dinamici (almeno 5), quindi sarà più facile caricarli in fase di esecuzione.

Ci sono metodi comuni che mi sono persi e come faccio a costruire un'applicazione come questa? Cosa devo fare per evitare le trappole più comuni?

Tutto questo deve funzionare pur continuando a supportare una sorta di ciclo degli eventi. Tuttavia, non ho bisogno di threading dal momento che python non ha un buon supporto comunque.

    
posta daegontaven 17.02.2018 - 09:12
fonte

1 risposta

2

I loop di eventi in più lingue non sono del tutto impossibili, ma se segui questa strada ti trovi in un mondo di dolore. Solo questo esclude alcune soluzioni come i binding di lingua generati automaticamente.

L'unico modo semplice per collegare due linguaggi di programmazione è tramite IPC. Lascia che l'applicazione avvii i plug-in come sottoprocessi e comunichi tramite pipe. In alternativa, implementa la tua applicazione come server a cui i processi separati possono connettersi. Vantaggio aggiunto delle soluzioni basate su IPC: la maggior parte dei loop di eventi facilitano l'attivazione di handle I / O leggibili.

Oltre queste pipe, si scambiano messaggi di qualsiasi formato. Questo potrebbe essere un semplice protocollo "un documento JSON per linea", messaggi Protobuf o HTTP completo. Questa è la parte in cui è possibile scegliere un design facile da implementare per tutti i partecipanti, sia per quanto riguarda la tecnologia di serializzazione dei messaggi sia per il protocollo implementato da questi messaggi.

Il modo in cui il protocollo del plugin deve essere strutturato dipende da cosa dovrebbero fare queste applicazioni. Per esempio. un plugin può essere un filtro che massaggia alcuni dati. Quindi, l'applicazione principale ha un codice come questo:

sendMessageToPlugin(data)
result = await readMessageFromPlugin()

Quindi questa è effettivamente una comunicazione sincrona con il plugin, ma non blocca la tua applicazione. Il plug-in deve ancora rispondere ai messaggi in ordine, ma potrebbe non essere un problema per molti carichi di lavoro.

Un altro caso semplice è quando il plug-in è semplicemente un utente consumer. Quindi basta inviare messaggi al plugin senza dover ricevere alcuna risposta. Ma questo apre alcune domande difficili: cosa succede se ci sono più eventi di quelli che il plugin può attualmente consumare? Come possono essere bufferizzati? Dovrebbero essere tamponati? Cosa succede quando il plug-in si arresta in modo anomalo?

In questi casi più complicati, potrebbe essere ragionevole utilizzare una coda di messaggi esistente che funge da intermediario tra i plug-in e l'applicazione.

È generalmente ragionevole offrire un'API piccola, semplice e ben definita ai plugin. Questo rende impossibile per il plugin richiedere dati arbitrari. Invece, si definiscono i messaggi che contengono i dati necessari. Se hai bisogno di una datamodel condivisa, l'uso di un database esterno può essere sensato perché può fare aggiornamenti atomici e garantisce la coerenza della tua datamodel. I tuoi messaggi contengono quindi le chiavi del database, non i dati completi.

Nota che più il tuo design si evolve in una certa direzione, più diventa facile applicare le migliori pratiche dagli approcci SOA o Microservice. Tutti questi problemi affrontano lo stesso problema: cooperazione indipendente dalla lingua tra più processi.

Vorrei anche sottolineare che queste sfide ingegneristiche, pur non essendo irrisolvibili, richiedono ancora molto impegno. A meno che tu non abbia un bisogno concreto che giustifichi il costo di sviluppo di questo sistema di plugin, potrebbe essere meglio rimanere nella lingua ospite. L'integrazione di una libreria è molto più semplice rispetto all'utilizzo di IPC.

    
risposta data 17.02.2018 - 19:30
fonte

Leggi altre domande sui tag