Skip to Content
Technical Articles
Author's profile photo Mario Dietrich Collada

Asynchronous code execution using ABAP Cloud

Introduction

With the introduction of ABAP Cloud we now have a new, modern ABAP development model to build cloud-ready business apps, services, and extensions. If you are not yet familiar with this innovation, I highly recommend having a look at this introduction and this architectural overview.

A common requirement when developing business applications is the ability to execute certain logic asynchronously. This may be due to a number of reasons. Maybe a large amount of data must be processed, which takes a long time, and the business process shall continue while that takes place. Maybe there is the need for a recurring mass activity that shall run in the background. In any case, asynchronous processing is crucial.

In this blog post I want to lay out the different possibilities that are available with ABAP Cloud. Currently we have three different approaches:

  1. Background Processing Framework (bgPF)
  2. Application Jobs
  3. Eventing

Each option has its own merits and advantages, and it will be up to you to identify which one is the most appropriate for your use case.

A short reminder on the availability of ABAP Cloud: it is enforced on SAP BTP ABAP Environment and SAP S/4HANA Cloud, public edition (Developer Extensibility is available in the 3-system landscape starting with release 2208) and it is available on SAP S/4HANA Cloud, private edition & on-premise (starting with release 2022).

Background Processing Framework

The newest of the features presented in this blog is the background processing framework (bgPF). This provides a simple and straight-forward way to execute custom logic asynchronously, without any configuration overhead. Developers can even decide whether to enforce transactional control for the asynchronously executed logic.

The first step is to create a class that implements either the if_bgmc_op_single (enforcing transactional consistency) or if_bgmc_op_single_tx_uncontr (unontrolled – no enforcement of transactional consistency) interface. The execute method of either interface should contain the logic that shall be executed asynchronously:

CLASS zmdc_bgpf_impl DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
  INTERFACES if_bgmc_op_single_tx_uncontr.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zmdc_bgpf_impl IMPLEMENTATION.

  METHOD if_bgmc_op_single_tx_uncontr~execute.
    "Custom code
  ENDMETHOD.

ENDCLASS.

The second step is to simply call the logic in question at the desired point in your business process. This is achieved using the previously created custom class and the standard class cl_bgmc_process_factory:

    DATA(new) = NEW zmdc_bgpf_impl(  ).

    DATA background_process TYPE REF TO if_bgmc_process_single_op.

    TRY.
        background_process = cl_bgmc_process_factory=>get_default(  )->create(  ).
*        background_process->set_operation( new ).
        background_process->set_operation_tx_uncontrolled( new ).
        background_process->save_for_execution(  ).
        COMMIT WORK. "not needed in RAP since the framework will do that for you

      CATCH cx_bgmc INTO DATA(exception).
        "handle exception
    ENDTRY.

Depending on the context, you may have to trigger the execution with a COMMIT WORK statement. This is not required if the process is triggered from within the RAP runtime, as the framework will trigger the commit.

This feature was initially released with release 2308 for SAP BTP, ABAP environment and SAP S/4HANA Cloud, public edition and with release 2023 for SAP S/4HANA Cloud, private edition and on-premise. Keep in mind that further improvements are planned and will be delivered with future releases.

Application Jobs

Another option for decoupling parts of your code are custom application jobs. Alongside the standard jobs delivered by SAP, you can create your own jobs containing custom code. These can then be scheduled through different means:

  1. Manually by a business user in the corresponding Fiori app (Application Jobs).
  2. Programatically, directly from your custom ABAP code.

An application job is defined by a job catalog entry, a job template and a handler class containing the custom code to be executed. The handler class implements interfaces if_apj_dt_exec_object (for design-time) and if_apj_rt_exec_object (for runtime). Most importantly, the if_apj_rt_exec_object~execute method contains the logic that shall be executed asynchronously:

CLASS zcl_mdc_apj DEFINITION
  PUBLIC
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.

    INTERFACES if_apj_dt_exec_object .
    INTERFACES if_apj_rt_exec_object .

  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.



CLASS zcl_mdc_apj IMPLEMENTATION.

  METHOD if_apj_rt_exec_object~execute.
    " Custom logic
  ENDMETHOD.

We then need to make sure that this application job is scheduled. In cases where the business application shall take care of this automatically, it makes sense to make use of the released class cl_apj_rt_api. The code should look something like:

  METHOD schedule.

    DATA lv_job_text TYPE cl_apj_rt_api=>ty_job_text VALUE 'Trigger Custom Job'.
    DATA lv_template_name TYPE cl_apj_rt_api=>ty_template_name VALUE 'ZMDC_APJ_DEMO_TEMP'.
    DATA ls_start_info TYPE cl_apj_rt_api=>ty_start_info.
    DATA ls_scheduling_info TYPE cl_apj_rt_api=>ty_scheduling_info.
    DATA ls_end_info TYPE cl_apj_rt_api=>ty_end_info.
    DATA lv_jobname TYPE cl_apj_rt_api=>ty_jobname.
    DATA lv_jobcount TYPE cl_apj_rt_api=>ty_jobcount.

********** Set scheduling options *******************
    ls_start_info-start_immediately = 'X'.
    ls_scheduling_info-periodic_granularity = ''.
    ls_scheduling_info-periodic_value = 1.
    ls_scheduling_info-test_mode = abap_false.
    ls_scheduling_info-timezone = 'CET'.
    ls_end_info-type = 'NUM'.
    ls_end_info-max_iterations = 3.
*****************************************************

    TRY.
        cl_apj_rt_api=>schedule_job(
          EXPORTING
            iv_job_template_name = lv_template_name
            iv_job_text          = lv_job_text
            is_start_info        = ls_start_info
            is_scheduling_info   = ls_scheduling_info
            is_end_info          = ls_end_info
          IMPORTING
            ev_jobname           = lv_jobname
            ev_jobcount          = lv_jobcount
        ).
      CATCH cx_apj_rt INTO DATA(exc).
        DATA(lv_txt) = exc->get_longtext( ).
        DATA(ls_ret) = exc->get_bapiret2( ).
    ENDTRY.
  ENDMETHOD.

Finally, we can just call the schedule method as required to trigger some asynchronous processing. You can find a nice tutorial from my colleague Andre Fischer here.

Eventing

As of release 2208, RAP supports the usage of custom RAP events. Such events are easily defined in any custom behavior definition and can then be raised during the save sequence. By executing the relevant business logic everytime the event is raised we can achieve the desired asynchrony.

Events can be consumed locally with minimal configuration effort. They can also be consumed remotely, which requires integration with the eventing infrastructure provided by SAP Event Mesh on SAP BTP (see for example the integration documentation for SAP S/4HANA Cloud, public edition). You will require entitlements for the corresponding BTP services and will need to perform the  corresponding connectivity setup (check out this tutorial for a great guide for SAP BTP ABAP Environment).

Event definition

Define an event by declaring it in your behavior definition as shown below. You will also need to define an additional save method:

managed implementation in class ZCL_MDC_BIP unique;
strict ( 2 );
with draft;

define behavior for Z_I_MDC_EVT alias CustomBO
persistent table zmdc_evt_db
draft table ZMDC_EVT_DB_D
with additional save
authorization master( global )
lock master total etag id
{
  create;
  update;
  delete;

  event customEvent parameter ZMDC_Event_Parameter;

This custom event should now be raised in the implementation of the additional save method:

CLASS lsc_z_i_mdc_evt DEFINITION INHERITING FROM cl_abap_behavior_saver.
  PROTECTED SECTION.
    METHODS save_modified REDEFINITION.
ENDCLASS.

CLASS lsc_z_i_mdc_evt IMPLEMENTATION.

  METHOD save_modified.
    RAISE ENTITY EVENT z_i_mdc_evt~customEvent
      FROM VALUE #( ( Name = 'TestName' Quantity = 10 ) ).
  ENDMETHOD.

ENDCLASS.

PUBLISH FOR LOCAL CONSUMPTION

If you are going to consume the event in the same system, then the implementation is already done!

PUBLISH FOR REMOTE CONSUMPTION

If you want to expose the event to the SAP BTP Event Mesh service, you will additionally need to create an event binding in ADT and expose the event to the eventing infrastructure. This will allow consumption of the event from external systems.

For more information, see Business Events.

Event publishing

LOCAL CONSUMPTION

If you are consuming an event locally, in the same system, then you only require a local event handler class. This class inherits from cl_abap_behavior_event_handler and can contain handler methods for different events:

CLASS lcl_abap_behv_event_handler DEFINITION INHERITING FROM cl_abap_behavior_event_handler.

  PRIVATE SECTION.

    METHODS consume_custom_event FOR ENTITY EVENT event_parameters FOR CustomBO~customEvent.

ENDCLASS.

CLASS lcl_abap_behv_event_handler IMPLEMENTATION.

  METHOD consume_custom_event.
    " Custom logic
  ENDMETHOD.

ENDCLASS.

REMOTE CONSUMPTION

If you are consuming an event from SAP Event Mesh, you instead need to create an event consumption model:

Event%20Consumption%20Model

Event Consumption Model

Along with the event consumption model itself, several additional objects are automatically created. The generated handler class (zcl_newevent in the screenshot) contains the event handler methods:

CLASS zcl_newevent DEFINITION
  PUBLIC
  INHERITING FROM zcl_newevent_base
  FINAL
  CREATE PUBLIC .

  PUBLIC SECTION.
    METHODS zif_newevent_handler~handle_zmdctest_create_v1 REDEFINITION.
  PROTECTED SECTION.
  PRIVATE SECTION.
ENDCLASS.


CLASS zcl_newevent IMPLEMENTATION.
  METHOD zif_newevent_handler~handle_zmdctest_create_v1.
    "Custom logic
  ENDMETHOD.
ENDCLASS.

With that, you can execute some of your business logic asynchronously, either in the original system or in remote systems. For more information, see Business Event Consumption

Summary

You now have 3 different ways of executing code asynchronously when developing with ABAP Cloud. You should analyze your use case and determine which of these options is the best for you.

Feel free to share any interesting use cases that you have encountered and, of course, do not hesitate to post any questions that you may have. We are always happy to help all ABAP developers out there to make the journey into the cloud!

Assigned Tags

      9 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Matthew Billingham
      Matthew Billingham

      Please can you edit your blog and use the {;} button for your code instead of screenshots. That way we can easily cut and paste.

      Author's profile photo Andrew Fordham
      Andrew Fordham

      But the pain of typing it in is what makes you remember it 😉

      Author's profile photo Mario Dietrich Collada
      Mario Dietrich Collada
      Blog Post Author

      Hi Matthew, thanks a lot for the suggestion. I have replaced the screenshots with actual code.

      Author's profile photo Matthew Billingham
      Matthew Billingham

      Super. now I can like it! 🙂

      Author's profile photo Petr Plenkov
      Petr Plenkov

      It would be great if SAP also delivers something like JS Promise natively. I have reviewed CL_ABAP_PARALLEL - indeed it does a lot of good stuff to prevent system overload, but parallel execution is not same as async/await logic just because that in fact it still stays synchronous.

      I have developed the concept in this project https://github.com/abapify/promise which breaks this paradigm.

      You can start some threads, keep working on another things in your code and then come later for results. However it is not possible to use it in the cloud because no RFC functions is allowed ( even if it's allowed internally ).

      If SAP would reconsider such limitation and would allow devs to use aRFC ( or similar functionality ) in the cloud abap - that would be a different story.

      Unfortunately non of methods mentioned above still cover a case like this without persisting data

      1. start doing this
      2. start doing that
      3. if this is finished..
      4. if that is finished..
      5. if this failed..
      6. if that failed..
      7. if both finished..
      8. if at least one failed..
      9. if first is finished..

      And my promises PoC is capable to cover those cases, but not in cloud yet..

      Author's profile photo Jochen Haase
      Jochen Haase

      We are using "Parallel-processing as a special variant of asynchonous RFC" (Link), especially for "mass-invoicing" (Point-of-Sales processing), or mass-data processing in general. It's an rather old framework, but very effective.

      An OO-framework (instead of RFC function-calls) would be nice - any plans to do that?

      Just found that Blog: Restricted ABAP for SAP BTP ABAP Environment - cl_abap_parallel  -  nice!

      thx

      Author's profile photo Andrew Fordham
      Andrew Fordham

      It already exists using class CL_ABAP_PARALLEL, if you have access to that.

      Author's profile photo Natalia Rios
      Natalia Rios

      Dear Mario,

      We are using S4 On premise. Still, we would like to have our custom code as cloud-ready as possible. We tried to make use of background processing framework (bgPF) classes to run a process in background (instead of the traditional FM in background task). But, the interface & classes are not available in the on premise S4 version.

      Do you know if there are any plans for the release of this functionality in the next S4 Onprem versions?

      Thanks

      Natalia

      Author's profile photo Alexander Rother
      Alexander Rother

      Hi Natalia,

      yes absolutely. The new bgPF is available with SAP S/4HANA 2023. The full scope will be available in release 2025. Please check the official roadmap for details.

      Best regards,
      Alexander