Concurrent processing via scala singleton object

650 Views Asked by At

I'm trying to build a simple orchestration engine in a functional test like the following:

object Engine {
  def orchestrate(apiSequence : Seq[Any]) {
    val execUnitList = getExecutionUnits(apiSequence) // build a specific list
    schedule(execUnitList) // call multiple APIs
  }

In the methods called underneath (getExecutionUnits, and schedule), the pattern I've applied is one where I incrementally build a list (hence, not a val but a var), iterate over the list and call sepcific APIs and run some custom validation on each one.

I'm aware that an object in scala is sort of equivalent to a singleton (so there's only one instance of Engine, in my case). I'm wondering if this is an appropriate pattern if I'm expecting 100's of invocations of the orchestrate method concurrently. I'm not managing any other internal variables within the Engine object and I'm simply acting on the provided arguments in the method. Assuming that the schedule method can take up to 10 seconds, I'm worried about the behavior when it comes to concurrent access. If client1, client2 and client3 call this method at the same time, will 2 of the clients get queued up and be blocked my the current client being processed?

Is there a safer idiomatic way to handle the use-case? Do you recommend using actors to wrap up the "orchestrate" method to handle concurrent requests?

Edit: To clarify, it is absolutely essential the the 2 methods (getExecutionUnits and schedule) and called in sequence. Moreover, the schedule method in turn calls multiple APIs (anywhere between 1 to 10) and it is important that they too get executed in sequence. As of right now I have a simply for loop that tackles 1 Api at a time, waits for the response, then moves onto the next one if appropriate.

1

There are 1 best solutions below

2
On BEST ANSWER

I'm not managing any other internal variables within the Engine object and I'm simply acting on the provided arguments in the method.

If you are using any vars in Engine at all, this won't work. However, from your description it seems like you don't: you have a local var in getExecutionUnits method and (possibly) a local var in schedule which is initialized with the return value of getExecutionUnits. This case should be fine.

If client1, client2 and client3 call this method at the same time, will 2 of the clients get queued up and be blocked my the current client being processed?

No, if you don't add any synchronization (and if Engine itself has no state, you shouldn't).

Do you recommend using actors to wrap up the "orchestrate" method to handle concurrent requests?

If you wrap it in one actor, then the clients will be blocked waiting while the engine is handling one request.