Oracle APEX 23.1 - Page Processes Enhancements

Running background processes have never been so easy

Introduction

Last week, apex.oracle.com has been upgraded to Oracle APEX 23.1 letting us play with the new features built with ❤ by the APEX team. One of them is new Execution Chain process type that allows us to group page processes and choose between foreground or background execution. It's a pretty interesting feature as it allows us to easily switch long processes to run in the background and monitor the execution using the new built-in apex_page_bg_proc_status view and apex_background_process package.

How to use this new feature?

Creating an Execution Chain process

Like any other type of process, you can add it from the page by right-clicking, creating a process, choosing Run Chain as the type and giving it a name. It looks like you can nest it by associating one runtime chain with another. I haven't tested this yet.

Screenshot showing the new Process Type Execution Chain

You can now add one or more processes to this Execution Chain.

Screenshot showing an Execution Chain associated with 3 processes

By default, the execution chain is executed in the foreground but, and this is the magic, you can enable the "Run in background" setting

Screenshot showing the attributes available when Execute in Background is switch on

You can define 4 additional attributes to control how APEX will handle it in the background:

AttributeExplanation
Serialize ExecutionsAllows you to indicate whether all executions across sessions should be serialized or not. This is to prevent concurrent access to the same elements in the database.
Return Execution ID into ItemAllows you to get the Execution ID returned into a Page Item
Temporary File HandlingSpecify the way APEX will handle the Temporary File, as the actual session is cloned to be executed in the background. You can choose between Ignore (files are not available in the cloned session), Move (files are moved in the cloned session but not available anymore in the current one) or Copy (files are copied in the new session but still available in the current one)
Executions LimitAllows you to limit the number of execution at the same time. You have to specify a number

Reporting the execution status and progress

Executing the chain in the background is easy but how do I report the progress and the status of the execution?

The new apex_background_process API contains two procedures to do it: set_progress and set_status

In the above example, I created 3 processes that do nothing but wait in a loop and update the status and the progress of the execution. Here is the code of one of them

begin
    apex_background_process.set_status(
        p_message => 'Analysing file (1/3)'
    );
    for i in 1..10
    loop
        dbms_session.sleep(1);
        apex_background_process.set_progress(
            p_totalwork => 30,
            p_sofar => i
        );
    end loop;
end;

Of course, in a real-world example, you would not just call dbms_session.sleep(1); .

Displaying the execution status and progress

This is great but what I want to be able to achieve is displaying this information to my end users. So they know that we are doing something in the background and they probably have to wait for it.

To achieve this, you can use the apex_appl_page_bg_proc_status view which contains all the background processes execution information.

select execution_id,
       process_id,
       process_name,
       current_process_name,
       status,
       status_code,
       status_message,
       coalesce(sofar, 0) as sofar,
       coalesce(totalwork, 100) as totalwork,
       coalesce(sofar, 0) / coalesce(totalwork, 30) * 100 progress
  from apex_appl_page_bg_proc_status
 where application_id = :app_id
   and page_id = :app_page_id
   and session_id = :app_session

Now if you use this query with a simple classic report and update the progress column to display a percent graph, you get an Execution Chain Monitor

Animated screenshot showing multiple running background with a progress bar for each of them. By clicking on the refresh button you see the progress and status updated

Pretty nice, isn't it?

Aborting background execution

Sometimes, you do want to stop background tasks and the good news is that there is an API for that: apex_background_process.abort

You can decide to abort all the process executions or only one specific execution

begin
    -- Abort all the execution of the process
    apex_background_process.abort(
        p_process_id => XXX
    );

    -- Abort only the specified execution of the process
    apex_background_process.abort(
        p_execution_id => XXX
    );
end;

Adding the abort execution to the report

Create a new column and in the HTML expression add this code

{case STATUS_CODE/}
    {when SUCCESS/}
    {when ABORTED/}
    {otherwise/}
        <button 
            type="button" 
            onclick="apex.event.trigger(document, 'abort-execution', '#EXECUTION_ID#')" 
            class="t-Button t-Button--icon t-Button--danger t-Button--simple t-Button--iconLeft">
    <span aria-hidden="true" class="t-Icon t-Icon--left fa fa-ban"></span>Abort Execution
</button>
{endcase/}

Then create a dynamic action to react to the abort-execution custom event

Screenshot showing the configuration of the dynamic action Abort Execution that react to the custom abort-execution event

Add a first action type of Set Value to get the execution ID and store it into a page item

Screenshot showing the configuration of the set value action that get the data from the custom event and set the value of a page item with it

Add another action of type Execute Server-side Code to abort the execution

Screenshot showing the action that execute a service side code and call the apex_background_process.abort to abort the execution of a specific background process. It uses the page item that have been previously set with the execution value.

begin
    apex_background_process.abort(p_execution_id => :P23_EXECUTION_ID);
end;

Finally, add a refresh action to refresh the report

Conclusion

This feature is a pretty exciting one because it allows us to easily execute long-running processes in the background in a low-code way. Simply switch on the attribute and use the API to report the status and progress of the execution. This was possible before but requires a lot of manual coding.

One more APEX feature that lets us focus on solving business problems instead of writing custom code! Thanks, Oracle APEX team

Demo available here: https://apex.oracle.com/pls/apex/r/louis/examples/background-processes