Parallel Actions
1434
Views
23
Comments
New
Backend

Why hasn't OutSystems given a thought about having Parallel Actions? If OutSystems can give me the ability to call two or more server actions or two or more client actions and collate their response would be really great.

You can use BPT Processes to start multiple events.

I like the idea, BPT is way to expensive for what Jaffar proposes. It is just like Async/Await in C# would be nice to have multithreading without the need to use BPT.

Thanks Daniel, precisely the point I wanted to make here. Two were in my mind when it comes to what more I expect from OutSystems, Parallel Actions was the first one.

I am not sure the BPT approach allows you to wait on the outcome of the parallel calls, so would only work when you do not need to report a result, or the success or otherwise of the calls.

Hi Daniel,

I am not aware of how a web request can wait on completion of a BPT activity.

And even if you could, the BPT activity may not begin for some time, possibly minutes, which would cause the web request to timeout.  So BPT is not the appropriate technology for handling parallel requests when the web request requires a result; a search for example.

Kind regards,

Stuart

Hi Stuart,

You write about web request and BPT, but for me that was not the discussion.

I was referring to BPT parallel processing as compared to what you can do in c# or JavaScript using asyc/await. 

Server or client parallel processing of actions have nothing to do with web requests it is about multi threading.

Regards,

Daniel


Hi Daniel,

Yes, that is true, parallel processing is not necessarily called in the context of a web request.

However, the same issue still stands when atttempting to wait for the result, as per Jaffar's original request "or two or more client actions and collate their response".

Although I may not know all of the capabilities of the platform.  Do you know of a way where an action can call two or more client actions (UPDATE: in parallel) then wait for them to finish processing?

Kind regards,

Stuart

Hi Stuart,

The reactive framework is already async in design.

What is lacking for the developer is to use it in an easy way in client actions.

Time outs will always be applicable, the idea of doing stuff in parallel is to do more in the same time. JavaScript is single threated, so probably no so much performance benefits here for client actions, unless one uses service workers to offload processing to another thread.

On the server however there is a clear benefit as the .net framework allows for multi threading.

Regards,

Daniel



Thanks Stuart / Daniel, what was in my mind when I started writing this Idea is like something attached. I wsa a BizTalk consultant earlier and have used an action called Parallel Convoy. What I would expect is to have them run in parallel in Client Action or a Server Action and return the control to the same client or server action. May be I'm expecting out of the blue but something like this would ease my work. How? Assuming I'm validating a user by his Passport ID and Verify his Address with the same ID. Now, instead of doing them in sequence one after the other I can do them in parallel and get them done at the same time. By this I expect a forking to be done on the thread to create sub processes.

Thanks Jaffar, good explanation.

Unfortunately, I think Daniel is correct, there is no platform supported way to do it.

I respect Daniels view, but I am not sure I agree that there is no benefit in parallel processing on the client side outside of service workers.  The benefit is in making parallel asynchronous calls to the server, javascript may be single threaded but AJAX is asynchonous.

After some experimentation, there does seem a way to do it, which involves configuring hidden buttons, and writing javascript to click on them.  If you call a DataAction, it can then call another action when the server action completes.

The first example in the below image shows just calling actions regularly from another client action.

The second example shows triggering button clicks which then call the actions.

Unfortunately the forum is not allowing upload of the OML, but you can see the test here https://shkiandra.outsystemscloud.com/TestAsync/Home?_ts=637120410940621716


(function(){
function clickOnButton(btnId) {
    var event = new MouseEvent('click');
    var el = document.getElementById(btnId);
    if (el) {
        console.log('Clicking on ' + btnId)
        el.click ? el.click() : el.dispatchEvent(event);
    }
}

clickOnButton($parameters.Id1);
clickOnButton($parameters.Id2);
clickOnButton($parameters.Id3);
   
})();

In my test I did not hide the buttons, but they just need the "hidden" class applied.

I have tested it on a few browsers, but I'm not sure about the compatibility of it.  The click() function appears to work, but the dispatchEvent doesn't, although maybe setting a few of the parameters would change that.

Hope this helps!

Kind regards,

Stuart

Oh, and the MouseEvent constructor could require a polyfill which you can get from here https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/MouseEvent


(function (window) {
  try {
    new MouseEvent('test');
    return false; // No need to polyfill
  } catch (e) {
// Need to polyfill - fall through
  }

    // Polyfills DOM4 MouseEvent
var MouseEventPolyfill = function (eventType, params) {
params = params || { bubbles: false, cancelable: false };
var mouseEvent = document.createEvent('MouseEvent');
mouseEvent.initMouseEvent(eventType, 
params.bubbles,
params.cancelable,
window,
0,
params.screenX || 0,
params.screenY || 0,
params.clientX || 0,
params.clientY || 0,
params.ctrlKey || false,
params.altKey || false,
params.shiftKey || false,
params.metaKey || false,
params.button || 0,
params.relatedTarget || null
);

return mouseEvent;
}

MouseEventPolyfill.prototype = Event.prototype;

window.MouseEvent = MouseEventPolyfill;
})(window);

Thanks Stuart for the time and effort on explaining this. I understand this couldn't add much value on client side. It can easily be achieved with JS, will this add value on the server side? Do you see light on having this on server side to ease our parallel action requirement on achieving fork or threading on server side. We are now achieving this using Processes (BPM / BPT) on OutSystems but have a strong feel that one like this could be adding more strength to the tool if available.

Changed the category to
Backend
Merged this idea with 'Parallel gateway widget' (created on 30 Nov 2020 17:49:08 by Tiago Ribeiro)

As a developer,

I want a "Parallel gateway" widget,

So that I can execute client and server actions async to improve performance.


Image a scenario where I have a server action that invokes 3 other actions (action1, action2 and action3) and aggregates the results. 

Even if the results are not dependent I am "forced" to do it like this:

If each action is slow (e.g a legacy REST endpoint) this approach causes a huge performance hit.

I propose a "Parallel gateway" widget that would branch out (much like the "switch" widget) and execute all the branches in parallel instead of sequentially.

The assign, and the rest of the flow, should have access to all the outputs of the 3 actions (as they where all executed).

Even though the example is in the server context, the same widget could be available client side and would work like a Promise.All( [action1, action2....] ).



Kudos, like this idea very much! 

This looks a lot like BPT, only in real-time?

A good one Tiago. Very well explained. My vote goes for it.

It really looks like a BPT. The idea is good and I think there could be modes in this "Parallel", being to follow the flow even if I have not finished all the processing (in all actions in parallel) or continue as soon as I complete the whole process in parallel (when all actions are completed).


+1

You can think of it somewhat like a BPT but with some important differences. 

With this widget, we would not leave the execution context - therefore not needing later logic to check if the process as already finished - and only proceed when ALL or ANY (configurable) of the tasks are completed (proceeding immediately and leaving the process in the background would be indeed like a BPT). 

Would also not have any of the performance penalties of starting a BPT (we could try to achieve this with a light process but we would need a trigger event).

Another advantage is that it would also work client side e.g doing multiple create / updates in local storage concurrently.


Thank you!

Changed the category to
Backend

This is a very good idea!!!

Good Idea,

@OutSystem implement it using pThreads in actions and barrier wait in the assign statement or maybe better task / await functionality in .NET (reuse of threads in tasks so that the creating thread time is avoided).

I like this ideia very much, this could improve a lot some performance when executing non sequencial tasks during a user tasks mainly on update actions.