Monday 25 February 2019

Parallel Processing using SPTA framework

Using SPTA framework, the parallel processing can be achieved in a more effective & efficient way as everything is handled by the standards. Performance wise also it is more optimized.

CONSTANTS: lc_e TYPE symsgty VALUE 'E'.

  IF gt_op_file[] IS INITIAL.
    RETURN.
  ENDIF.

  "Fetch the server group
  SELECT SINGLE classname
  INTO @DATA(lv_server_grp)
  FROM rzllitab
  WHERE grouptype = 'S'.
  IF sy-subrc NE 0.
    RETURN.
  ENDIF.


*---------------------------------------------------------------------*
*                P A R A L L E L   P R O C E S S I N G
*---------------------------------------------------------------------*
  "to invoke parallel processing framwork
  IF gv_parallel_process EQ abap_true.
    CALL FUNCTION 'SPTA_PARA_PROCESS_START_2'
      EXPORTING
        server_group             = lv_server_grp
        before_rfc_callback_form = 'BEFORE_RFC'
        in_rfc_callback_form     = 'IN_RFC'
        after_rfc_callback_form  = 'AFTER_RFC'
        callback_prog            = sy-repid
      CHANGING
        user_param               = gt_op_file
      EXCEPTIONS
        invalid_server_group     = 1
        no_resources_available   = 2
        OTHERS                   = 3.
    IF sy-subrc NE 0.
      "Populate the log
      PERFORM fill_msg_log USING lc_e
                                 TEXT-e01
                                 space space space
                        CHANGING gt_msg_log.
    ENDIF.
  ELSE.
    "Post the data
    PERFORM post_data CHANGING gt_op_file.
  ENDIF.

*&---------------------------------------------------------------------*
*& Form BEFORE_RFC
*&---------------------------------------------------------------------*
*& Packets are prepared for parallel processing
*&---------------------------------------------------------------------*
FORM before_rfc USING ps_before_rfc_imp     TYPE spta_t_before_rfc_imp
             CHANGING cs_before_rfc_exp     TYPE spta_t_before_rfc_exp
                      ct_rfcdata            TYPE spta_t_indxtab
                      ct_failed_objects     TYPE spta_t_failed_objects
                      ct_objects_in_process TYPE spta_t_objects_in_process
                      ct_file_data          TYPE gtt_op_file.

  TYPES: lty_op_file TYPE TABLE OF gty_op_file WITH EMPTY KEY.
  DATA: lv_counter        TYPE i,
        lv_pck_size       TYPE i VALUE 5000, "One work packet size
        lt_final          TYPE gtt_op_file,
        lv_current_tranno TYPE string.

  IF ct_file_data[] IS INITIAL.
    CLEAR: cs_before_rfc_exp-start_rfc.
    RETURN.
  ENDIF.

** Create small work packets for parallel processing
  SORT ct_file_data BY tranno.
  LOOP AT ct_file_data ASSIGNING FIELD-SYMBOL(<lfs_file_data>).
    IF lv_current_tranno NE <lfs_file_data>-tranno.
      lv_current_tranno = <lfs_file_data>-tranno.
      "count the total records against particular transactions
      DATA(lv_rec_count) = REDUCE i( INIT x = 0 FOR ls_file_data IN ct_file_data
                                  WHERE ( tranno EQ <lfs_file_data>-tranno )
                                  NEXT x = x + 1 ).

      "if the total number of records can be accomodated in the current batch then accomodate it
      IF ( lv_rec_count + lines( lt_final ) ) LE lv_pck_size.
        APPEND <lfs_file_data> TO lt_final.

        "If the record count for particular transactions is more than the pack size
        "then assign the whole lot in a single batch
      ELSEIF lv_rec_count GT lv_pck_size.
        lt_final = VALUE lty_op_file( FOR ls_file_data2 IN ct_file_data
                                      WHERE ( tranno EQ <lfs_file_data>-tranno )
                                          ( ls_file_data2 ) ).
      ENDIF.
    ELSE.
      APPEND <lfs_file_data> TO lt_final.
    ENDIF.
  ENDLOOP.

  "Delete the records which has been grouped
  DELETE ct_file_data FROM 1 TO lv_pck_size.

* Convert the input data into the INDX structure that is needed for the RFC
  CALL FUNCTION 'SPTA_INDX_PACKAGE_ENCODE'
    EXPORTING
      data    = lt_final
    IMPORTING
      indxtab = ct_rfcdata.

* informing task manager that an rfc can be started from the data compiled
  IF lt_final IS NOT INITIAL.
    cs_before_rfc_exp-start_rfc = abap_true.
  ELSE.
    CLEAR cs_before_rfc_exp-start_rfc.
    RETURN.
  ENDIF.

ENDFORM.                    "BEFORE_RFC

*&---------------------------------------------------------------------*
*&      Form  IN_RFC
*&---------------------------------------------------------------------*
*  create own RFC enabled FM or write logic in this routine
*----------------------------------------------------------------------*
FORM in_rfc USING ps_in_rfc_imp TYPE spta_t_in_rfc_imp
         CHANGING cs_in_rfc_exp TYPE spta_t_in_rfc_exp
                  ct_rfcdata    TYPE spta_t_indxtab.


  DATA: lt_final TYPE gtt_op_file.

* Decode the data from the INDX Structure into the process work list
  CALL FUNCTION 'SPTA_INDX_PACKAGE_DECODE'
    EXPORTING
      indxtab = ct_rfcdata
    IMPORTING
      data    = lt_final.

* Simple logic to sort data
  SORT lt_final BY tranno.
  PERFORM post_data CHANGING lt_final.

* Again Encode output data for AFTER_RFC form
  CALL FUNCTION 'SPTA_INDX_PACKAGE_ENCODE'
    EXPORTING
      data    = lt_final
    IMPORTING
      indxtab = ct_rfcdata.

ENDFORM.                    "in_rfc

*&---------------------------------------------------------------------*
*&      Form  AFTER_RFC
*&---------------------------------------------------------------------*
* To collect date after parallel processing
*----------------------------------------------------------------------*
FORM after_rfc USING pt_rfcdata            TYPE spta_t_indxtab
                     pv_rfcsubrc           TYPE sy-subrc
                     pv_rfcmsg             TYPE spta_t_rfcmsg
                     pt_objects_in_process TYPE spta_t_objects_in_process
                     ps_after_rfc_imp      TYPE spta_t_after_rfc_imp
            CHANGING cs_after_rfc_exp      TYPE spta_t_after_rfc_exp
                     cs_user_param         TYPE gtt_op_file.

  DATA: lt_final TYPE gtt_op_file.

* Decode RFC output data and add RFC-results to global data
  IF gv_parallel_process EQ abap_true.
    CALL FUNCTION 'SPTA_INDX_PACKAGE_DECODE'
      EXPORTING
        indxtab = pt_rfcdata
      IMPORTING
        data    = lt_final.
  ENDIF.

* After parallel processing write the records in AL11
  IF lt_final[] IS NOT INITIAL.

  ENDIF.
ENDFORM.                    "AFTER_RFC

6 comments:

  1. This comment has been removed by the author.

    ReplyDelete

Report to find CDS view of Standard Table

A small change has been made to the original program ( SAP YARD Article ) so that it can also display the common CDS used by multiple table...