Progettazione di gestori di azioni che richiedono un certo ordine

1

Ho un'applicazione REST in cui è possibile eseguire "azioni" per eseguire qualsiasi operazione nel sistema. Ad esempio: user.save, user.get, ecc ...

Ho anche "gestori" di pre e post esecuzione. Ad esempio, un gestore di post-esecuzione viene utilizzato per aggiungere tag agli utenti; è un modulo AddOn che gestisce i tag degli utenti (e di altre entità). Ho anche un altro modulo (chiamato Rules) che può, ad esempio, convalidare le informazioni dell'utente e fare qualcosa in base a quello (ad esempio, inviare un messaggio di posta elettronica).

Il problema che sto affrontando ora è che in generale l'ordine di esecuzione di quei moduli non è importante, ma a volte lo è. Prendi i seguenti casi:

Esempio 1:

  1. Azione: Salva utente
  2. Gestore: tagga l'utente come "VIP"
  3. Gestore: invia un'email se l'utente è contrassegnato come "VIP"

= > L'email viene inviata.

Esempio 2:

  1. Azione: Salva utente
  2. Gestore: invia un'email se l'utente è contrassegnato come "VIP"
  3. Gestore: tagga l'utente come "VIP"

= > L'email non verrà inviata.

Tutte le operazioni (azioni e gestori) vengono eseguite all'interno di una singola transazione.

Quale sarebbe una buona soluzione per assicurarti che il gestore "Invia email" venga eseguito dopo l'utente "Tag user"?

Alcune idee:  - Avere gestori di post-azione e gestori post- (post-azione). Ma quanti post-post-post dovrei aggiungere?  - Aggiungi un peso o indice di priorità a ciascun gestore. Ma quando finisci con diversi gestori, le priorità tendono ad essere confuse poiché ogni modulo non conosce gli altri moduli e gestori.

Che cosa consiglieresti? Grazie.

Nel caso qualcuno lo trovi importante: è C # 4.5, ASP.NET, IIS.

    
posta Diego Jancic 27.02.2015 - 19:04
fonte

3 risposte

1

Ci sono ovviamente delle dipendenze tra i gestori.

Un modo possibile per farlo è assegnare priorità ai moduli: la cosa buona è che è facile da implementare, ma (come ha notato Frank Hileman) questa soluzione non è scalabile. Essenzialmente si nascondono le dipendenze tra i moduli dal sistema e si risolvono queste dipendenze manualmente ordinando i moduli - è necessario mantenere queste dipendenze in testa o in modo non formale (commenti, documentazione). Questo va bene finché non ci sono molti moduli e dipendenze.

Una soluzione più scalabile sarebbe quella di esprimere direttamente le dipendenze nel codice e quindi avere un motore che le risolva automaticamente e ordina l'esecuzione dei gestori. Ad esempio, ogni gestore può avere due proprietà:

  • prerequisiti (ad esempio TAG): cosa è necessario fare per eseguire questo gestore (le operazioni di tag devono essere completate)
  • operationsOn (di nuovo TAGS) - cosa sta facendo questo gestore (modifica i tag)

La regola è che il gestore può essere eseguito solo dopo che tutti i suoi prerequisiti sono già stati completati. "Finito" significa che non ci sono altri gestori con i prerequisiti forniti nel suo campo "operationsOn" che non è stato ancora eseguito.

Esempio, hai due gestori:

Gestore che codifica l'utente come VIP:

  • prerequisiti: nessuno
  • operationsOn: TAG

Gestore che invia l'email:

  • prerequisiti: TAG
  • operationsOn: USER_EMAIL

Prima esegui i gestori senza dipendenze (tagging VIP uno). Quindi si tenta di trovare gestori per cui sono state completate tutte le dipendenze. Guardi l'handler che invia l'email, ha dipendenza TAGS. Verifica che tutti i gestori che operano su TAGS siano stati completati in modo da poter eseguire il gestore inviando l'e-mail.

Ciò creerà efficacemente un albero di gestori che esprime le dipendenze. Come con qualsiasi albero, devi fare attenzione a non introdurre dipendenze circolari - un gestore dipende dal risultato di un gestore diverso che dipende ancora dal risultato del primo gestore.

Ovviamente questo ha un costo abbastanza iniziale di progettazione di questo sistema, quindi è più utile per sistemi complessi (e generalizzati) con molti gestori e dipendenze.

    
risposta data 03.05.2015 - 13:18
fonte
1

Vorrei consolidare le azioni e i gestori in astrazioni di livello superiore che operano utilizzando un ordine fisso di operazioni. La soluzione basata su priorità non verrà ridimensionata.

    
risposta data 03.03.2015 - 21:20
fonte
0

L'approccio generale per garantire che un elenco di handler venga eseguito nell'ordine corretto è not rendere ogni gestore come pronto per l'esecuzione , ma per fare solo il < strong> primo gestore come pronto e passa l'elenco rimanente di gestori al primo gestore, in modo che il primo gestore possa eseguire il successivo nell'elenco come primo finiture. Ciascun gestore eseguirà quindi uno spegnimento ed eseguirà il successivo, finché l'elenco non sarà vuoto.
(Questo non è specifico per ASP.NET, è solo un approccio generale nel software.)

Un'altra possibilità è che devi avere qualcuno esaminare il codice sorgente e l'implementazione, per vedere se stai utilizzando IHttpModule e IHttpHandler nel modo corretto (inteso). Se il tuo codice non ha ottenuto l'effetto desiderato perché non lo stai utilizzando in base al design del framework, sarà inutile porre tali domande ai programmatori.
(Questo non dovrebbe essere eseguito su Programmers.SE o CodeReview.SE; dovresti cercare qualcuno dal tuo reparto software.)

    
risposta data 03.05.2015 - 04:20
fonte

Leggi altre domande sui tag