I've written some code that essentially is responsible for orchestrating a number of API's in sequence through a library method I provide to my clients called "orchestrate" (yes I know so original). What sits behind this orchestrate method is nothing more than a loop that executes API's in the order they are received, which in turn are delegated to a number of classes that contain some business logic for building a request, calling an API, performing some validation on the response and finally returning the api result. So, if a client sent in a list of apis:
{a1, a2, a3, a4, a5}
it would execute each api in sequence in a completely blocking way.
I'm attempting to beef this up to where I'm able to call multiple API's in parallel depending on how I receive the instructions from a client. Think of it as the client sending me a list of lists like: { {a1, a2}, {a3}, {a4, a5} }
This means I'd like to execute a1 and a2 in parallel (which means build their request, call the apis, validate the response). Then wait until i'm sure both of them are done. Then execute a3, and wait until i'm sure it's done. Finally I want to execute a4 and a5 and follow the usual pattern.
Now, I'm tempted to use futures for the simple abstraction they provide to execute methods a wait for the response using the .get()
method. But what I noticed that the executorService needs underneath is future's invocation of a call()
method. This is fine, but makes me think that the call()
method that is implemented per class may need access to "local" data in order to do its job (after all, I can't pass the call() method any particular parameters). I really want to avoid holding any local mutable state because that brings its own side-effects.
Is there a way for me to NOT hold local state and still use futures to handle my multithreading use-case? Or is my understanding of futures completely wrong and I'm missing something obvious? If not, are there any recommendations on a good path forward with some alternatives?