Paralell Processing with ABAP [REV]

  1. SPTA framework
  2. aRFC/ bgRFC

SPTA framework

SPTA framework is the most sophisticated and secured framework for parallel processing provided by SAP. If we want to handle multiple records and want to update/check multiple database tables in parallel, in that case, using conventional way to invoke parallel processing is difficult and there can be some ABAP memory issue. But in SPTA framework there are build in security for all the ABAP memory related issues so it is very secure. Also, SPTA framework is very easy to implement and all the parallel processing work is handled by SAP we do not need to bother how to handle it. In this way, it is also a very sophisticated framework.

FM SPTA_PARA_PROCESS_START_2

The FM is used to set up parallel processing.  The parameter user_param can be used for import/export parameters. We need to create a new separate subroutine pool program with the routines before, after and in_rfc

 call function 'SPTA_PARA_PROCESS_START_2'
      exporting
        server_group             = lv_server_grp
        max_no_of_tasks          = '10'
        before_rfc_callback_form = 'BEFORE_RFC'
        in_rfc_callback_form     = 'IN_RFC'
        after_rfc_callback_form  = 'AFTER_RFC'
        callback_prog            = gc_program 
*       SHOW_STATUS              = ' '
*       RESOURCE_TIMEOUT         = 600
*       TASK_CALL_MODE           = 1
      changing
        user_param               = ls_user_parameter
      exceptions
        invalid_server_group     = 1
        no_resources_available   = 2
        others                   = 3.
    if sy-subrc eq 0.
      rt_output  = ls_user_parameter-export.
    endif.


Routines

BEFORE_RFC

This routine is called by the function module before calling the RFC function module. Here we have to build different work packets which we want to process in the RFC function module.

form before_rfc
     using is_before_rfc_imp        type spta_t_before_rfc_imp
     changing es_before_rfc_exp     type spta_t_before_rfc_exp
              et_rfcdata            type spta_t_indxtab
              ct_failed_objects     type spta_t_failed_objects
              et_objects_in_process type spta_t_objects_in_process
              cs_user_param         type ............
  data:
    lv_package_size   like sy-tabix,
    lt_task_data      type ..................,
    ls_work_area      type ......................,
    ls_failed_obj     like line of ct_failed_objects,
    ls_obj_in_process like line of et_objects_in_process.


  clear: et_objects_in_process.

* Check if there are objects from previously failed tasks left ...
  read table ct_failed_objects index 1 into ls_failed_obj.
  if sy-subrc = 0.

* Add list of objects that are about to be processed to list of "objects in process" so the task manager has that information
    " append ls_obj_in_process to et_objects_in_process.
  else.
* No there aren't. The number of objects that are processed at once is determined by the application.

    data(lv_max_tasks) .....

    describe table cs_user_param-import lines sy-tabix.

    lv_package_size = sy-tabix / lv_max_tasks.

    if lv_package_size > 30.
      lv_package_size = 30.
    elseif lv_package_size < 10.
      lv_package_size = 10.
    else.
      lv_package_size = 1.
    endif.

    do lv_package_size times.

      assign component 1 of structure cs_user_param to <lt_import>.
      if <lt_import> is assigned.

        read table <lt_import> index 1 assigning field-symbol(<ls_order>).
        if sy-subrc is initial.
* Add list of objects that are about to be processed to list of objects in process"  so the task manager has that information
          data(ls_customer) = <ls_order>-partners[ partn_role = 'AG' ].
          insert value #( obj_id =  ls_customer-partn_numb ) into table et_objects_in_process.
          insert <ls_order> into table lt_task_data.

          delete <lt_import> index 1.
        endif.
      endif.
    enddo.
  endif.

* If there is (currently) nothing to do, clear the START_RFC field and leave the form. This informs the task manager that no rfc has to be started.
  if et_objects_in_process is initial.
    clear es_before_rfc_exp-start_rfc.
    exit.
  endif.

* Convert the input data into the INDX structure
* that is needed for the RFC
  call function 'SPTA_INDX_PACKAGE_ENCODE'
    exporting
      data    = lt_task_data
    importing
      indxtab = et_rfcdata.

* Inform task manager that an RFC can be started from the
* data compiled
  es_before_rfc_exp-start_rfc = 'X'.

endform.


IN_RFC

This routine is called by the function module after work packets are created. In this routine, we can use our own RFC enabled function module or custom code to process each work packets.

form in_rfc
     using is_in_rfc_imp      type spta_t_in_rfc_imp
     changing es_in_rfc_exp      type spta_t_in_rfc_exp
              ct_rfcdata         type spta_t_indxtab.

  data: lt_task_data_in      type ...........................

  set update task local.

* Unpack RFC input data (that has been packed in the BEFORE_RFC form)
  call function 'SPTA_INDX_PACKAGE_DECODE'
    exporting
      indxtab = ct_rfcdata
    importing
      data    = lt_task_data_in.

..... Logic

* Repack output data for AFTER_RFC form
  call function 'SPTA_INDX_PACKAGE_ENCODE'
    exporting
      data    = lt_pricing
    importing
      indxtab = ct_rfcdata.

endform.


AFTER_RFC

This routine is called at the end by the function module. After processing of all the work packets, we have to collect all the processed data.
 
form after_rfc
     using it_rfcdata            type spta_t_indxtab
           iv_rfcsubrc           type sy-subrc
           iv_rfcmsg             type spta_t_rfcmsg
           it_objects_in_process type spta_t_objects_in_process
           is_after_rfc_imp      type spta_t_after_rfc_imp
  changing es_after_rfc_exp      type spta_t_after_rfc_exp
           cs_user_param         type.................

  data lt_mat_price_out type.........................

* Decode RFC output data and add RFC-results to global data
  if iv_rfcsubrc eq 0.
    call function 'SPTA_INDX_PACKAGE_DECODE'
      exporting
        indxtab = it_rfcdata
      importing
        data    = lt_mat_price_out.

    append lines of lt_mat_price_out to cs_user_param-export.

  endif.

endform.

Get the server group

    select single classname
    into @data(lv_server_grp)
    from rzllitab where grouptype = 'S'.
    if sy-subrc eq 0.
      rv_classname = lv_server_grp.
    endif.

Get the number of free processes

  statics: sv_max_tasks type i.
    data: lv_free_pbt_wps type i.

    data(lv_serv_group)

    call function 'SPBT_INITIALIZE'
      exporting
        group_name                     = lv_serv_group
      importing
*       MAX_PBT_WPS                    =
        free_pbt_wps                   = lv_free_pbt_wps
      exceptions
        invalid_group_name             = 1
        internal_error                 = 2
        pbt_env_already_initialized    = 3
        currently_no_resources_avail   = 4
        no_pbt_resources_found         = 5
        cant_init_different_pbt_groups = 6
        others                         = 7.
    if sy-subrc eq 0.
      rv_max_tasks =  lv_free_pbt_wps * 40 / 100.
    else.
      rv_max_tasks = 5.
    endif.





Comments