I have a need for user to press button on front end and it submit a long running process (job). This could take up to 7-8 minutes to run. How can I alert the user to the status of this job and when it is finished. Any best practices?
Announcement
Collapse
No announcement yet.
Long Running Process - how to monitor
Collapse
X
-
Best way to accomplish this would be through firing events. There are several necessary components needed:- Table that contains (at a minimum) a 64 character SID column
- Add an exit program for the Portal polling process (Portal Admin - Settings)
- This will read the above mentioned table and send back an array of "events" to fire
- Modify the Hook.js file to interrogate the response from the poll
- Use Valence.util.Helper.fireEvent for each element in the "events" array
- NAB App
- Add a startup script that uses Valence.util.Helper.addEventListener to listen for the event(s).
- This can then call setAppVar and/or fireEvent (to fire a local app event) to do whatever you need to alert the user
- Add a startup script that uses Valence.util.Helper.addEventListener to listen for the event(s).
So the process from start to finish:- User clicks something in NAB app that calls some program that starts a long running process
- Program returns back immediately so the user does not wait but submits a job to run the process
- The submitted job stamps a new record to a table when it is complete....at a minimum it stamps the SID (Valence session id) and an event name
- Polling process runs your new "exit" program which checks for any records that match the SID.
- If a record is found it creates an "events" array...maybe something like events: ["name": "orderCreated", "name": "printJobComplete"]
- Hook program changes check for the events array and call Valence.util.Helper.fireEvent for each element: Valence.util.Helper.fireEvent('orderCreated')
- The NAB startup script is listening for the "orderCreated" event and then does something to alert the user.
?Code:Valence.util.Helper.addEventListener('orderCreated',function(){ setAppVar('nabInfo':'The order has been created'); });
-
Sean, I'm just curious.....
what if I wanted to fire a global event? Right now, its tied to a specific user's session. Is there any way that if I started this long running process and another user somewhere opened up the same app on their computer, that they would also get the status updates as well?
Comment
-
Yes, I would recommend the following approach:- Add an app id to your table that stores the events to fire. This would be the app id that is meant to "consume" the event.
- Create a record for each active session (rather than just the single record for the current sid)
- Table VVSESSDATA contains every active session...column VVSESSID contains the sid
- Change your polling exit program hook to only include the event if the app id is active for the given session
Code:dcl-proc isAppActive; dcl-pi *n ind; pAppId int(10) const; end-pi; dcl-s lExists ind; if pAppId = 0; return *on; else; exec sql select 1 into :lExists from vvSessApps where vvSessId = :gSid and vvAppId = :pAppId; return lExists; endif; end-proc;
Comment
-
Once the job submitted is completed I report this back to the front end, and a message is displayed letting the user know the process is done.
I do not block the user from continuing to use the app while the process is running. Once the process is completed, I would like to refresh all the widgets that the user is currently looking at.
How do I know what widgets are currently being displayed and how do I refresh them without having to hard code in side the event listener.
thanks again...
Comment
-
I do have a suggestion but then found that one portion of it is currently not available (will be on the next update).
I assume that you have a startup script that has an "Valence.util.Helper.addEventListener", correct? Within your function, fire an event as follows:
This will fire an app level local event. So in behaviors, you can choose to listen for this event. Note: it will not be available in the list you will have to click the "Is the event fired from the back-end or derived from an app variable?" text on the bottom. Note to self...this text should actually be changed as this is not only the case any longer.Code:fireEvent('refreshMyWidgets');
Now that you are listening for this event, I was going to suggest to add a "Utility > Refresh" action. This action already exists but we do not make it available against an event listener...this is what we will add for the next update. The associated text with this action is as follows:so this should give you what you are asking for.If button is placed on a widget it will refresh that widget's data; If placed at the application level all visible widgets will be refreshed.
Comment

Comment