I am trying to understand how I can make the code for this easy to understand and debug too. The reason I'm asking is that it feels like the kind of scenario which has probably been tackled before plenty of times. And if that is the case I would like to use that as a solid starting point which will allow this to be extended and scale in the future of its lifetime.

Ihave a web application, which needs to performs lots of different actions against an existing external system. The trigger is an action performed in the portal. The order of the steps at design time, and they need to run in order. The actions needed are generally formed of a few steps.


Portal action (Job)A -->  (Task A -> Task B -> Task C)
Portal action (Job)B -->  (Task A -> Task D -> Task E)
Portal action (Job)C -->  (Task B -> Task D -> Task E)
Portal action (Job)D -->  (Task C -> Task E)
etc, etc.

The steps need to run in order.

While there are technology choices (possibly queuing) within this, the main thing I'm trying to decide on is a code structure.

I have considered a couple of patterns.

  • Chain of Responsibility - From what I understand, it seemed like more of a filter for permissions/validation, rather than a method to chain together steps.
  • Event Sourcing - To get the benefit, it looked better suited to none sequential execution or possibly multiple subscribers to the same event.

I'm still struggling to accept that I am searching for a pattern that doesn't exist. I'm looking advice on that front, what is the suitable pattern to give me a good solid starting point?

  • Have you considered defining them as Job life-cycles and using State Transition machines? – Chris Reynolds Oct 31 '18 at 21:37
  • Do the jobs and their order need to be dynamic, i.e. stored at runtime in a list? It seems to me you could execute the steps in order simply by writing them out in code, which is the easiest and most readable way. – John Wu Aug 28 '19 at 18:38

You gave no reason why this couldn't be a simple "sequence". I.e. statements separated by semicolon (example code in Java):

public void jobA() {

It doesn't get much clearer than that. If you are worried about long running tasks or thread management, you can make all those tasks non-blocking. Most languages have some form of support for it, for example Java has CompletableFuture<>:

public CompletableFuture<JobAResult> jobA() {
   return taskA()

If you have other constraints, you should mention them. For example if you need to run the tasks on potentially different hosts, or scale tasks separately, etc. Otherwise don't over-engineer the thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.