Qual è il modo migliore per progettare l'elaborazione del tipo di lavoro in batch

3

Sto lavorando su una parte di un sistema ERP in cui ho bisogno di elaborare i dati in modo simile a una serie di lavori batch e sto cercando di decidere la migliore architettura del programma da utilizzare. Sto chiedendo qui perché so di non conoscere molti dei metodi di programmazione più avanzati e sono preoccupato di progettare il mio software in modo arcaico senza accorgermene.

Il mio sistema ha bisogno di elaborare batch di dati e di essere in grado di pianificare i processi di elaborazione a intervalli regolari e anche di essere eseguiti su richiesta. Alcune delle elaborazioni si basano anche su servizi Web esterni.

Al momento la mia architettura è che ho una sola soluzione di Visual Studio C # (con diversi progetti al suo interno). La soluzione produce un programma che dispone di un'interfaccia per l'esecuzione di lavori su richiesta anche per la configurazione di una pianificazione per l'esecuzione automatica dei lavori. Il singolo programma contiene anche tutto il codice di elaborazione batch.

All'interno del programma, ogni "lavoro batch" viene chiamato chiamando un metodo sulla mia classe di controller principale, ad esempio public async Task BillOrders() , che quindi chiama il metodo appropriato da una classe di servizio di alto livello, che chiama i servizi di livello inferiore , e così via. Le classi stesse sono tutte abbastanza separate in termini di principio di responsabilità singola. Il controller principale chiama ogni metodo di lavoro batch in modo asincrono e gestisce il monitoraggio, la segnalazione di errori, la limitazione e così via.

Tutto funziona, ma sono preoccupato che questo non sia il modo in cui dovrei farlo.  Nello specifico, le mie preoccupazioni sono:

  1. Dato che ho diverse funzioni separate per il tipo di processo batch tutte nello stesso programma, sono preoccupato che un arresto anomalo o un bug nel programma possa causare il blocco di tutti i processi batch. Sembra anche brutto avere un solo programma che faccia un sacco di cose diverse.

  2. Anche se ogni processo batch è correlato a un'area del mio ERP, sono preoccupato che avere un singolo codebase con funzioni diverse finirà per creare qualcosa di monolitico e difficile per diversi sviluppatori di lavorare su diversi aspetti di simultaneamente.

Uno dei motivi principali per cui l'ho fatto come un singolo programma (e la soluzione di Visual Studio) è il contesto di Entity Framework e le classi di servizio sono condivise tra ogni lavoro batch. Se divido il programma in diversi programmi più piccoli, ogni programma avrà un sacco di classi e il contesto EF che sono lo stesso codice. E qualsiasi correzione o estensione di un servizio in un programma dovrebbe essere copiata agli altri. Inoltre, il mio contesto EF ha diverse dozzine di tabelle che vengono eseguite con l'API Fluent.

Ho preso in considerazione l'idea di creare una serie di microservizi, ma ci sono così tante preoccupazioni trasversali che ogni microservizio avrebbe bisogno di molte delle stesse classi di servizio e di EF che ho descritto sopra, vanificando così l'obiettivo dell'utilizzo dei microservizi.

Esiste un'architettura comunemente accettata per questo genere di cose? È quello che sto facendo OK, o sto programmando come se fosse 15 anni fa?

    
posta Ben Rubin 21.09.2018 - 22:51
fonte

2 risposte

2

Since I have several separate batch-process-type functions all in the same program, I'm worried that a crash or bug in the program could cause all the batch processes to stop working.

Stai eseguendo più lavori contemporaneamente nello stesso processo? In tal caso, esiste il rischio che un errore possa interrompere altri lavori. Ciò accadrà solo per errori che danneggiano l'intero processo. Questo è abbastanza raro. Gli esempi sono condizioni di memoria insufficienti, stack overflow o persone che terminano il processo. Altrimenti, puoi avvolgere il codice di elaborazione in try-catch per isolarli l'uno dall'altro. Questo è ciò che fanno le applicazioni web e normalmente funziona molto bene.

È anche possibile eseguire ogni lavoro come processo OS separato. Quindi, i lavori sono totalmente isolati. Puoi riutilizzare lo stesso file EXE per questo. Crea un argomento di riga di comando intero o stringa che indichi all'EXE quali dei numerosi lavori possibili che deve avviare.

Riutilizzare lo stesso file EXE ti salva dalla necessità di creare molti progetti C # e avere il sovraccarico di gestione del codice che verrebbe fornito con quei progetti.

It also seems bad to have one single program that does a bunch of different things.

Qual è la tua preoccupazione? Forse sei preoccupato che ciò possa andare contro il principio della responsabilità unica. Questo principio riguarda lo stesso codice che fa più cose. Come ho capito, i tuoi lavori sono abbastanza isolati l'uno dall'altro. Considera anche che le tipiche applicazioni web fanno 100 o 1000 di cose diverse e non è un problema. L'SRP è solo un principio, non una regola difficile. Fai ciò che funziona per te.

Even though each batch process is related to one area of my ERP, I'm worried that having a single codebase with different functions in it will end up creating something monolithic and difficult for several developers to work on different aspects of simultaneously.

Se sei preoccupato che la codebase possa diventare ingombrante allora direi che suddividere il codice in più progetti non ti porterà nulla. È sempre lo stesso codice, le stesse dipendenze e l'architettura in un posto diverso.

Risolvere l'entanglement non è mai possibile semplicemente mettendo il codice in un posto diverso (progetti o servizi aggiuntivi). Devi apportare modifiche architettoniche.

Quindi, se si crea un EXE / microservizio per ogni lavoro o se si fa ogni lavoro semplicemente la propria classe C # non è una grande differenza architettonica. Aggiunge solo un sacco di complessità di sviluppo.

Poiché i tuoi lavori sono abbastanza isolati l'uno dall'altro non mi preoccupo di inserirli tutti nello stesso progetto.

Sembra anche che tu voglia condividere alcune infrastrutture come i modelli di Entity Framework. Questa è anche una buona ragione per tenere insieme le cose.

    
risposta data 22.09.2018 - 11:32
fonte
1

Il tuo dominio è così diverso dal mio e i commenti sottostanti alla tua domanda da parte di esperti in questo dominio stanno andando oltre la mia testa, ma con "elaborazione in batch" e le tue due domande specifiche relative ai tuoi problemi di progettazione molto immediati, penso immediatamente del modello di comando e IPC (comunicazione interprocesso) come le mie tecniche di goto per risolvere questi problemi.

Even though each batch process is related to one area of my ERP, I'm worried that having a single codebase with different functions in it will end up creating something monolithic and difficult for several developers to work on different aspects of simultaneously.

Una soluzione per questo è sostituire l'interfaccia centrale "controller principale" con oggetti di comando concreti decentralizzati che implementano tutti la stessa interfaccia Command astratta. Puoi eseguirli in modo asincrono da un posto centrale se è necessario. Puoi anche combinarlo con una factory per istanziare i comandi con una stringa che indica il nome che potrebbe essere utile per il secondo punto seguente. In questo modo puoi continuare ad aggiungere nuovi comandi al tuo sistema in modo non intrusivo senza che alcune interfacce centrali diventino un monolite.

Since I have several separate batch-process-type functions all in the same program, I'm worried that a crash or bug in the program could cause all the batch processes to stop working. It also seems bad to have one single program that does a bunch of different things.

La soluzione per questo se vuoi qualcosa di veramente robusto è generare un processo separato per eseguire questi comandi (o generarlo in anticipo e comunicare con uno esistente per dirgli cose nuove da fare con IPC). Non è necessario programmare binari separati per ogni singola attività / lavoro (comando) che potrebbe essere eseguita come indicato da usr . Puoi avere un comando binario eseguibile generalizzato o persino riutilizzare lo stesso che hai già adesso con gli argomenti del comando forniti per dirgli quale comando eseguire, e qualche forma di IPC (ci sono molte opzioni qui da named pipe per mappare i file a mailslots e altri su Windows: ho generalizzato il mapping dei file e il metodo di memoria condivisa come quello più generalizzato per i miei scopi, sebbene richieda semafori) per condividere lo stato pertinente tra due o più processi. Se lo fai in questo modo, se alcuni processi secondari si bloccano, non porterà l'applicazione host a eseguire questi processi batch con essa in fiamme.

Credo che questo sia il modo in cui molti dei nostri browser funzionano per evitare arresti anomali in caso di arresto anomalo di Flash o JavaScript o WebGL o qualcosa del genere. Probabilmente generano queste cose in processi separati e puoi vedere con Chrome almeno che ha il proprio task manager per questo (shift + esc) e che tende a lanciare molte istanze di Chrome.exe indipendentemente dal numero di istanze di Chrome che hai aperto te stesso.

    
risposta data 11.12.2018 - 13:49
fonte

Leggi altre domande sui tag