<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic parallel processing - some questions in Application Development and Automation Discussions</title>
    <link>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075238#M729153</link>
    <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm about to develop a class for task management.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;It should have methods like GET_TASK returning a taskid and task_return importing task_id received and possibly task_fail importing task_id sent with a bad sy-subrc when calling function with starting new task.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The idea behind is: New task is started by system using a dialog process with time limit restriction applying. Thus I have to split the whole task into more small packets than processes available. So I think I have to use the same task again after it returned successfully.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My assumption is I can't use more tasks than processes initially available and I can use the same tsak again after it has successsfully returned results.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I want some ideas and information on that exceeding the SAP documentation.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;TIA.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Clemens&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
    <pubDate>Mon, 19 Nov 2007 12:52:02 GMT</pubDate>
    <dc:creator>Clemenss</dc:creator>
    <dc:date>2007-11-19T12:52:02Z</dc:date>
    <item>
      <title>parallel processing - some questions</title>
      <link>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075238#M729153</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I'm about to develop a class for task management.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;It should have methods like GET_TASK returning a taskid and task_return importing task_id received and possibly task_fail importing task_id sent with a bad sy-subrc when calling function with starting new task.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The idea behind is: New task is started by system using a dialog process with time limit restriction applying. Thus I have to split the whole task into more small packets than processes available. So I think I have to use the same task again after it returned successfully.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;My assumption is I can't use more tasks than processes initially available and I can use the same tsak again after it has successsfully returned results.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I want some ideas and information on that exceeding the SAP documentation.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;TIA.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Clemens&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 19 Nov 2007 12:52:02 GMT</pubDate>
      <guid>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075238#M729153</guid>
      <dc:creator>Clemenss</dc:creator>
      <dc:date>2007-11-19T12:52:02Z</dc:date>
    </item>
    <item>
      <title>Re: parallel processing - some questions</title>
      <link>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075239#M729154</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Clemens,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Here is a sample program for Parallel processing.&lt;/P&gt;&lt;P&gt;Hope this helps.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;REPORT PARAJOB.&lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;UL&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Data declarations&lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;DATA: GROUP LIKE RZLLITAB-CLASSNAME VALUE ' ', &lt;/P&gt;&lt;P&gt;"Parallel processing group. &lt;/P&gt;&lt;P&gt;"SPACE = group default (all&lt;/P&gt;&lt;P&gt;"servers)&lt;/P&gt;&lt;P&gt;WP_AVAILABLE TYPE I, "Number of dialog work processes&lt;/P&gt;&lt;P&gt;"available for parallel processing&lt;/P&gt;&lt;P&gt;"(free work processes) &lt;/P&gt;&lt;P&gt;WP_TOTAL TYPE I, "Total number of dialog work &lt;/P&gt;&lt;P&gt;"processes in the group&lt;/P&gt;&lt;P&gt;MSG(80) VALUE SPACE, "Container for error message in &lt;/P&gt;&lt;P&gt;"case of remote RFC exception.&lt;/P&gt;&lt;P&gt;INFO LIKE RFCSI, C, "Message text &lt;/P&gt;&lt;P&gt;JOBS TYPE I VALUE 10, "Number of parallel jobs &lt;/P&gt;&lt;P&gt;SND_JOBS TYPE I VALUE 1, "Work packets sent for processing &lt;/P&gt;&lt;P&gt;RCV_JOBS TYPE I VALUE 1, "Work packet replies received &lt;/P&gt;&lt;P&gt;EXCP_FLAG(1) TYPE C, "Number of RESOURCE_FAILUREs &lt;/P&gt;&lt;P&gt;TASKNAME(4) TYPE N VALUE '0001', "Task name (name of &lt;/P&gt;&lt;P&gt;"parallel processing work unit)&lt;/P&gt;&lt;P&gt;BEGIN OF TASKLIST OCCURS 10, "Task administration &lt;/P&gt;&lt;P&gt;TASKNAME(4) TYPE C, &lt;/P&gt;&lt;P&gt;RFCDEST LIKE RFCSI-RFCDEST,&lt;/P&gt;&lt;P&gt;RFCHOST LIKE RFCSI-RFCHOST, &lt;/P&gt;&lt;P&gt;END OF TASKLIST. &lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;UL&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Optional call to SBPT_INITIALIZE to check the &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;group in which parallel processing is to take place. &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Could be used to optimize sizing of work packets&lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;work / WP_AVAILABLE).&lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;*&lt;/P&gt;&lt;P&gt;CALL FUNCTION 'SPBT_INITIALIZE' &lt;/P&gt;&lt;P&gt;EXPORTING &lt;/P&gt;&lt;P&gt;GROUP_NAME = GROUP &lt;/P&gt;&lt;P&gt;"Name of group to check&lt;/P&gt;&lt;P&gt;IMPORTING &lt;/P&gt;&lt;P&gt;MAX_PBT_WPS = WP_TOTAL &lt;/P&gt;&lt;P&gt;"Total number of dialog work&lt;/P&gt;&lt;P&gt;"processes available in group&lt;/P&gt;&lt;P&gt;"for parallel processing&lt;/P&gt;&lt;P&gt;FREE_PBT_WPS = WP_AVAILABLE &lt;/P&gt;&lt;P&gt;"Number of work processes &lt;/P&gt;&lt;P&gt;"available in group for &lt;/P&gt;&lt;P&gt;"parallel processing at this&lt;/P&gt;&lt;P&gt;"moment&lt;/P&gt;&lt;P&gt;EXCEPTIONS &lt;/P&gt;&lt;P&gt;INVALID_GROUP_NAME = 1 &lt;/P&gt;&lt;P&gt;"Incorrect group name; RFC &lt;/P&gt;&lt;P&gt;"group not defined. See &lt;/P&gt;&lt;P&gt;"transaction RZ12 &lt;/P&gt;&lt;P&gt;INTERNAL_ERROR = 2 &lt;/P&gt;&lt;P&gt;"R/3 System error; see the&lt;/P&gt;&lt;P&gt;"system log (transaction &lt;/P&gt;&lt;P&gt;"SM21) for diagnostic info &lt;/P&gt;&lt;P&gt;PBT_ENV_ALREADY_INITIALIZED = 3 &lt;/P&gt;&lt;P&gt;"Function module may be &lt;/P&gt;&lt;P&gt;"called only once; is called&lt;/P&gt;&lt;P&gt;"automatically by R/3 if you&lt;/P&gt;&lt;P&gt;"do not call before starting&lt;/P&gt;&lt;P&gt;"parallel processing &lt;/P&gt;&lt;P&gt;CURRENTLY_NO_RESOURCES_AVAIL = 4 &lt;/P&gt;&lt;P&gt;"No dialog work processes &lt;/P&gt;&lt;P&gt;"in the group are available;&lt;/P&gt;&lt;P&gt;"they are busy or server load&lt;/P&gt;&lt;P&gt;"is too high &lt;/P&gt;&lt;P&gt;NO_PBT_RESOURCES_FOUND = 5 &lt;/P&gt;&lt;P&gt;"No servers in the group &lt;/P&gt;&lt;P&gt;"met the criteria of &amp;gt; &lt;/P&gt;&lt;P&gt;"two work processes &lt;/P&gt;&lt;P&gt;"defined. &lt;/P&gt;&lt;P&gt;CANT_INIT_DIFFERENT_PBT_GROUPS = 6&lt;/P&gt;&lt;P&gt;"You have already initialized &lt;/P&gt;&lt;P&gt;"one group and have now tried &lt;/P&gt;&lt;P&gt;"initialize a different group.&lt;/P&gt;&lt;P&gt;OTHERS = 7.. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;CASE SY-SUBRC.&lt;/P&gt;&lt;P&gt;WHEN 0.&lt;/P&gt;&lt;P&gt;"Everything&amp;#146;s ok. Optionally set up for optimizing size of &lt;/P&gt;&lt;P&gt;"work packets.&lt;/P&gt;&lt;P&gt;WHEN 1.&lt;/P&gt;&lt;P&gt;"Non-existent group name. Stop report.&lt;/P&gt;&lt;P&gt;MESSAGE E836. "Group not defined.&lt;/P&gt;&lt;P&gt;WHEN 2. &lt;/P&gt;&lt;P&gt;"System error. Stop and check system log for error &lt;/P&gt;&lt;P&gt;"analysis.&lt;/P&gt;&lt;P&gt;WHEN 3. &lt;/P&gt;&lt;P&gt;"Programming error. Stop and correct program.&lt;/P&gt;&lt;P&gt;MESSAGE E833. "PBT environment was already initialized.&lt;/P&gt;&lt;P&gt;WHEN 4. &lt;/P&gt;&lt;P&gt;"No resources: this may be a temporary problem. You &lt;/P&gt;&lt;P&gt;"may wish to pause briefly and repeat the call. Otherwise&lt;/P&gt;&lt;P&gt;"check your RFC group administration: Group defined &lt;/P&gt;&lt;P&gt;"in accordance with your requirements? &lt;/P&gt;&lt;P&gt;MESSAGE E837. "All servers currently busy.&lt;/P&gt;&lt;P&gt;WHEN 5. &lt;/P&gt;&lt;P&gt;"Check your servers, network, operation modes. &lt;/P&gt;&lt;P&gt;WHEN 6. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;UL&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Do parallel processing. Use CALL FUNCTION STARTING NEW TASK&lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;DESTINATION IN GROUP to call the function module that does the &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;work. Make a call for each record that is to be processed, or &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;divide the records into work packets. In each case, provide the &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;set of records as an internal table in the CALL FUNCTION &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;keyword (EXPORT, TABLES arguments). &lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DO. &lt;/P&gt;&lt;P&gt;CALL FUNCTION 'RFC_SYSTEM_INFO' "Function module to perform &lt;/P&gt;&lt;P&gt;"in parallel &lt;/P&gt;&lt;P&gt;STARTING NEW TASK TASKNAME "Name for identifying this &lt;/P&gt;&lt;P&gt;"RFC call&lt;/P&gt;&lt;P&gt;DESTINATION IN GROUP group "Name of group of servers to &lt;/P&gt;&lt;P&gt;"use for parallel processing.&lt;/P&gt;&lt;P&gt;"Enter group name exactly &lt;/P&gt;&lt;P&gt;"as it appears in transaction &lt;/P&gt;&lt;P&gt;"RZ12 (all caps). You may &lt;/P&gt;&lt;P&gt;"use only one group name in a &lt;/P&gt;&lt;P&gt;"particular ABAP program.&lt;/P&gt;&lt;P&gt;PERFORMING RETURN_INFO ON END OF TASK &lt;/P&gt;&lt;P&gt;"This form is called when the &lt;/P&gt;&lt;P&gt;"RFC call completes. It can &lt;/P&gt;&lt;P&gt;"collect IMPORT and TABLES &lt;/P&gt;&lt;P&gt;"parameters from the called &lt;/P&gt;&lt;P&gt;"function with RECEIVE. &lt;/P&gt;&lt;P&gt;EXCEPTIONS &lt;/P&gt;&lt;P&gt;COMMUNICATION_FAILURE = 1 MESSAGE msg &lt;/P&gt;&lt;P&gt;"Destination server not &lt;/P&gt;&lt;P&gt;"reached or communication &lt;/P&gt;&lt;P&gt;"interrupted. MESSAGE msg &lt;/P&gt;&lt;P&gt;"captures any message &lt;/P&gt;&lt;P&gt;"returned with this &lt;/P&gt;&lt;P&gt;"exception (E or A messages&lt;/P&gt;&lt;P&gt;"from the called FM, for &lt;/P&gt;&lt;P&gt;"example. After exception&lt;/P&gt;&lt;P&gt;"1 or 2, instead of aborting &lt;/P&gt;&lt;P&gt;"your program, you could use &lt;/P&gt;&lt;P&gt;"SPBT_GET_PP_DESTINATION and&lt;/P&gt;&lt;P&gt;"SPBT_DO_NOT_USE_SERVER to &lt;/P&gt;&lt;P&gt;"exclude this server from &lt;/P&gt;&lt;P&gt;"further parallel processing.&lt;/P&gt;&lt;P&gt;"You could then re-try this &lt;/P&gt;&lt;P&gt;"call using a different &lt;/P&gt;&lt;P&gt;"server.&lt;/P&gt;&lt;P&gt;SYSTEM_FAILURE = 2 MESSAGE msg&lt;/P&gt;&lt;P&gt;"Program or other internal &lt;/P&gt;&lt;P&gt;"R/3 error. MESSAGE msg &lt;/P&gt;&lt;P&gt;"captures any message &lt;/P&gt;&lt;P&gt;"returned with this &lt;/P&gt;&lt;P&gt;"exception. &lt;/P&gt;&lt;P&gt;RESOURCE_FAILURE = 3. "No work processes are &lt;/P&gt;&lt;P&gt;"currently available. Your &lt;/P&gt;&lt;P&gt;"program MUST handle this &lt;/P&gt;&lt;P&gt;"exception. &lt;/P&gt;&lt;P&gt;YOUR_EXCEPTIONS = X. "Add exceptions generated by &lt;/P&gt;&lt;P&gt;"the called function module &lt;/P&gt;&lt;P&gt;"here. Exceptions are &lt;/P&gt;&lt;P&gt;"returned to you and you can &lt;/P&gt;&lt;P&gt;"respond to them here. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;CASE SY-SUBRC. &lt;/P&gt;&lt;P&gt;WHEN 0. &lt;/P&gt;&lt;P&gt;"Administration of asynchronous RFC tasks &lt;/P&gt;&lt;P&gt;"Save name of task...&lt;/P&gt;&lt;P&gt;TASKLIST-TASKNAME = TASKNAME. &lt;/P&gt;&lt;P&gt;"... and get server that is performing RFC call. &lt;/P&gt;&lt;P&gt;CALL FUNCTION 'SPBT_GET_PP_DESTINATION' &lt;/P&gt;&lt;P&gt;EXPORTING &lt;/P&gt;&lt;P&gt;RFCDEST = TASKLIST-RFCDEST &lt;/P&gt;&lt;P&gt;EXCEPTIONS &lt;/P&gt;&lt;P&gt;OTHERS = 1. &lt;/P&gt;&lt;P&gt;APPEND TASKLIST. &lt;/P&gt;&lt;P&gt;WRITE: / 'Started task: ', TASKLIST-TASKNAME COLOR 2. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;TASKNAME = TASKNAME + 1. &lt;/P&gt;&lt;P&gt;SND_JOBS = SND_JOBS + 1. &lt;/P&gt;&lt;P&gt;"Mechanism for determining when to leave the loop. Here, a &lt;/P&gt;&lt;P&gt;"simple counter of the number of parallel processing tasks. &lt;/P&gt;&lt;P&gt;"In production use, you would end the loop when you have &lt;/P&gt;&lt;P&gt;"finished dispatching the data that is to be processed. &lt;/P&gt;&lt;P&gt;JOBS = JOBS - 1. "Number of existing jobs &lt;/P&gt;&lt;P&gt;IF JOBS = 0. &lt;/P&gt;&lt;P&gt;EXIT. "Job processing finished &lt;/P&gt;&lt;P&gt;ENDIF. &lt;/P&gt;&lt;P&gt;WHEN 1 OR 2.&lt;/P&gt;&lt;P&gt;"Handle communication and system failure. Your program must &lt;/P&gt;&lt;P&gt;"catch these exceptions and arrange for a recoverable &lt;/P&gt;&lt;P&gt;"termination of the background processing job. &lt;/P&gt;&lt;P&gt;"Recommendation: Log the data that has been processed when&lt;/P&gt;&lt;P&gt;"an RFC task is started and when it returns, so that the &lt;/P&gt;&lt;P&gt;"job can be restarted with unprocessed data. &lt;/P&gt;&lt;P&gt;WRITE msg. &lt;/P&gt;&lt;P&gt;"Remove server from further consideration for &lt;/P&gt;&lt;P&gt;"parallel processing tasks in this program. &lt;/P&gt;&lt;P&gt;"Get name of server just called... &lt;/P&gt;&lt;P&gt;CALL FUNCTION 'SPBT_GET_PP_DESTINATION' &lt;/P&gt;&lt;P&gt;EXPORTING &lt;/P&gt;&lt;P&gt;RFCDEST = TASKLIST-RFCDEST &lt;/P&gt;&lt;P&gt;EXCEPTIONS &lt;/P&gt;&lt;P&gt;OTHERS = 1. &lt;/P&gt;&lt;P&gt;"Then remove from list of available servers.&lt;/P&gt;&lt;P&gt;CALL FUNCTION 'SPBT_DO_NOT_USE_SERVER'&lt;/P&gt;&lt;P&gt;IMPORTING &lt;/P&gt;&lt;P&gt;SERVERNAME = TASKLIST-RFCDEST&lt;/P&gt;&lt;P&gt;EXCEPTIONS &lt;/P&gt;&lt;P&gt;INVALID_SERVER_NAME = 1 &lt;/P&gt;&lt;P&gt;NO_MORE_RESOURCES_LEFT = 2 &lt;/P&gt;&lt;P&gt;"No servers left in group.&lt;/P&gt;&lt;P&gt;PBT_ENV_NOT_INITIALIZED_YET = 3&lt;/P&gt;&lt;P&gt;OTHERS = 4.&lt;/P&gt;&lt;P&gt;WHEN 3. &lt;/P&gt;&lt;P&gt;"No resources (dialog work processes) available at &lt;/P&gt;&lt;P&gt;"present. You need to handle this exception, waiting&lt;/P&gt;&lt;P&gt;"and repeating the CALL FUNCTION until processing &lt;/P&gt;&lt;P&gt;"can continue or it is apparent that there is a &lt;/P&gt;&lt;P&gt;"problem that prevents continuation. &lt;/P&gt;&lt;P&gt;MESSAGE I837. "All servers currently busy.&lt;/P&gt;&lt;P&gt;"Wait for replies to asynchronous RFC calls. Each &lt;/P&gt;&lt;P&gt;"reply should make a dialog work process available again. &lt;/P&gt;&lt;P&gt;IF EXCP_FLAG = SPACE. &lt;/P&gt;&lt;P&gt;EXCP_FLAG = 'X'. &lt;/P&gt;&lt;P&gt;"First attempt at RESOURCE_FAILURE handling. Wait &lt;/P&gt;&lt;P&gt;"until all RFC calls have returned or up to 1 second.&lt;/P&gt;&lt;P&gt;"Then repeat CALL FUNCTION. &lt;/P&gt;&lt;P&gt;WAIT UNTIL RCV_JOBS &amp;gt;= SND_JOBS UP TO '1' SECONDS. &lt;/P&gt;&lt;P&gt;ELSE. &lt;/P&gt;&lt;P&gt;"Second attempt at RESOURCE_FAILURE handling &lt;/P&gt;&lt;P&gt;WAIT UNTIL RCV_JOBS &amp;gt;= SND_JOBS UP TO '5' SECONDS. &lt;/P&gt;&lt;P&gt;"SY-SUBRC 0 from WAIT shows that replies have returned. &lt;/P&gt;&lt;P&gt;"The resource problem was therefore probably temporary&lt;/P&gt;&lt;P&gt;"and due to the workload. A non-zero RC suggests that&lt;/P&gt;&lt;P&gt;"no RFC calls have been completed, and there may be &lt;/P&gt;&lt;P&gt;"problems. &lt;/P&gt;&lt;P&gt;IF SY-SUBRC = 0. &lt;/P&gt;&lt;P&gt;CLEAR EXCP_FLAG.&lt;/P&gt;&lt;P&gt;ELSE. "No replies &lt;/P&gt;&lt;P&gt;"Endless loop handling &lt;/P&gt;&lt;P&gt;... &lt;/P&gt;&lt;P&gt;ENDIF. &lt;/P&gt;&lt;P&gt;ENDIF.&lt;/P&gt;&lt;P&gt;ENDCASE. &lt;/P&gt;&lt;P&gt;ENDDO. &lt;/P&gt;&lt;P&gt;... &lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;UL&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Wait for end of job: replies from all RFC tasks. &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Receive remaining asynchronous replies &lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;WAIT UNTIL RCV_JOBS &amp;gt;= SND_JOBS. &lt;/P&gt;&lt;P&gt;LOOP AT TASKLIST. &lt;/P&gt;&lt;P&gt;WRITE:/ 'Received task:', TASKLIST-TASKNAME COLOR 1, &lt;/P&gt;&lt;P&gt;30 'Destination: ', TASKLIST-RFCDEST COLOR 1. &lt;/P&gt;&lt;P&gt;ENDLOOP. &lt;/P&gt;&lt;P&gt;...&lt;/P&gt;&lt;P&gt;*&lt;/P&gt;&lt;UL&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;This routine is triggered when an RFC call completes and &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;returns. The routine uses RECEIVE to collect IMPORT and TABLE&lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;data from the RFC function module. &lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;*&lt;/P&gt;&lt;UL&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Note that the WRITE keyword is not supported in asynchronous &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;RFC. If you need to generate a list, then your RFC function &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;module should return the list data in an internal table. You &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;can then collect this data and output the list at the conclusion &lt;/P&gt;&lt;/LI&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;of processing. &lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;*&lt;/P&gt;&lt;P&gt;FORM RETURN_INFO USING TASKNAME. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;DATA: INFO_RFCDEST LIKE TASKLIST-RFCDEST.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;RECEIVE RESULTS FROM FUNCTION 'RFC_SYSTEM_INFO' &lt;/P&gt;&lt;P&gt;IMPORTING RFCSI_EXPORT = INFO &lt;/P&gt;&lt;P&gt;EXCEPTIONS &lt;/P&gt;&lt;P&gt;COMMUNICATION_FAILURE = 1 &lt;/P&gt;&lt;P&gt;SYSTEM_FAILURE = 2. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;RCV_JOBS = RCV_JOBS + 1. "Receiving data &lt;/P&gt;&lt;P&gt;IF SY-SUBRC NE 0. &lt;/P&gt;&lt;UL&gt;&lt;LI level="1" type="ul"&gt;&lt;P&gt;Handle communication and system failure &lt;/P&gt;&lt;/LI&gt;&lt;/UL&gt;&lt;P&gt;... &lt;/P&gt;&lt;P&gt;ELSE. &lt;/P&gt;&lt;P&gt;READ TABLE TASKLIST WITH KEY TASKNAME = TASKNAME. &lt;/P&gt;&lt;P&gt;IF SY-SUBRC = 0. "Register data &lt;/P&gt;&lt;P&gt;TASKLIST-RFCHOST = INFO_RFCHOST. &lt;/P&gt;&lt;P&gt;MODIFY TASKLIST INDEX SY-TABIX. &lt;/P&gt;&lt;P&gt;ENDIF. &lt;/P&gt;&lt;P&gt;ENDIF. &lt;/P&gt;&lt;P&gt;... &lt;/P&gt;&lt;P&gt;ENDFORM&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;&amp;lt;b&amp;gt;Reward points if this helps.&lt;/P&gt;&lt;P&gt;Manish&amp;lt;/b&amp;gt;&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 19 Nov 2007 12:53:52 GMT</pubDate>
      <guid>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075239#M729154</guid>
      <dc:creator>Former Member</dc:creator>
      <dc:date>2007-11-19T12:53:52Z</dc:date>
    </item>
    <item>
      <title>Re: parallel processing - some questions</title>
      <link>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075240#M729155</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hi Manish,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;thank you for pasting the SAP documentation without saying so.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I said: "Exceeding SAP documentation"&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The docu text says what I think is not enough:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;"In production use, you would end the loop when you have &lt;/P&gt;&lt;P&gt;"finished dispatching the data that is to be processed. &lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Your answer just wastes my time [and nerves].&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;[Grrr],&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Clemens&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Mon, 19 Nov 2007 13:29:02 GMT</pubDate>
      <guid>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075240#M729155</guid>
      <dc:creator>Clemenss</dc:creator>
      <dc:date>2007-11-19T13:29:02Z</dc:date>
    </item>
    <item>
      <title>Re: parallel processing - some questions</title>
      <link>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075241#M729156</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hey, I got it:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The dispatched processes do not start to process the form given with PERFORMING ... ON END OF TASK before the WAIT statement has been reached.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Then the tasks return their results in the RECEIVING statement in the form.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I tried to start a new task imediately after receiving a result from the first task started. But this did not work, I had too many process fails.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Now I start as many processes as possible, then I wait for all results having been received, then I start again until everything is finished.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;You may try my sample program which was developed under 46C.&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 28 Nov 2007 18:53:32 GMT</pubDate>
      <guid>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075241#M729156</guid>
      <dc:creator>Clemenss</dc:creator>
      <dc:date>2007-11-28T18:53:32Z</dc:date>
    </item>
    <item>
      <title>Re: parallel processing - some questions</title>
      <link>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075242#M729157</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;... and here comes the program (no formatting available with the answer given with "solved".&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;The programs retrieves billing documents with function BAPI_BILLINGDOC_GETLIST - this was the only BAPI I found quickly that has ranges as import parameters. This allows giving packages to the tasks.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE&gt;&lt;CODE&gt;
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp; Report  ZZZPARTEST                                                  *
*&amp;amp;                                                                     *
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;                                                                     *
*&amp;amp;                                                                     *
*&amp;amp;---------------------------------------------------------------------*

REPORT  zzzpartest.

PARAMETERS:
  p_dbcnt                                 TYPE sydbcnt DEFAULT 1010,
  p_pacsz                                 TYPE sydbcnt DEFAULT 95.

CONSTANTS:
  gc_function                             TYPE tfdir-funcname
    VALUE 'BAPI_BILLINGDOC_GETLIST'.

DATA:
  gt_bapivbrksuccess                      TYPE TABLE OF
    bapivbrksuccess,
  gv_activ                                TYPE i,
  gv_rcv                                  TYPE i,
  gv_snd                                  TYPE i,
  BEGIN OF ls_intval,
    task                                  TYPE numc4,
    idxfr                                 TYPE i,
    idxto                                 TYPE i,
    activ                                 TYPE flag,
    fails                                 TYPE i,
  END OF ls_intval,
  gt_intval                               LIKE TABLE OF ls_intval.

START-OF-SELECTION.
  PERFORM paralleltest.

*---------------------------------------------------------------------*
*       CLASS task DEFINITION
*---------------------------------------------------------------------*
*       ........                                                      *
*---------------------------------------------------------------------*
CLASS task DEFINITION.
  PUBLIC SECTION.
    CLASS-METHODS:
      provide
        RETURNING
          value(name)                     TYPE numc4,
      return
        IMPORTING
          name                            TYPE numc4,
      initialize
        RETURNING
          value(group)                    TYPE rzllitab-classname.
  PRIVATE SECTION.
    CLASS-DATA:
      gv_group                            TYPE rzllitab-classname,
      BEGIN OF ls_task,
      name                                TYPE numc4,
      used                                TYPE flag,
      END OF ls_task,
      gt_task                             LIKE TABLE OF ls_task.
ENDCLASS.                    "itab DEFINITION
***       CLASS itab IMPLEMENTATION ***
CLASS task IMPLEMENTATION.
  METHOD initialize.
    DATA:
      lv_max                              TYPE i,
      lv_inc                              TYPE numc7,
      lv_free                             TYPE i.
    CHECK gt_task IS INITIAL.
    SELECT classname
      INTO gv_group
      FROM rzllitab UP TO 1 ROWS
      WHERE grouptype                     = 'S'.
    ENDSELECT.

    CALL FUNCTION 'SPBT_INITIALIZE'
         EXPORTING
              group_name                     = gv_group
         IMPORTING
              max_pbt_wps                    = lv_max
              free_pbt_wps                   = lv_free
         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                           &amp;lt;&amp;gt; 0.
    MESSAGE ID sy-msgid                   TYPE sy-msgty NUMBER sy-msgno
                               WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
    ENDIF.
    SUBTRACT 2 FROM lv_free.
    IF lv_free &amp;gt;= 1.
      DO lv_free TIMES.
        ls_task-name                        = sy-index.
        APPEND ls_task TO gt_task.
      ENDDO.
      group                                 = gv_group.
      MESSAGE s000(r1)
        WITH
        'Parallelverarbeitung benutzt'
        lv_free
        'Prozesse in Gruppe'
        gv_group.
*   &amp;amp; &amp;amp; &amp;amp; &amp;amp;
    ELSE.
      MESSAGE e000(r1)
        WITH
        'Parallelverarbeitung abgebrochen,'
        lv_free
        'Prozesse in Gruppe'
        gv_group.
*   &amp;amp; &amp;amp; &amp;amp; &amp;amp;
    ENDIF.

  ENDMETHOD.                    "initialize
  METHOD provide.
    FIELD-SYMBOLS:
      &amp;lt;task&amp;gt;                              LIKE ls_task.
    IF  gv_group IS INITIAL.
      MESSAGE e000(r1)
        WITH 'Task group not initialized'.
    ENDIF.
    LOOP AT gt_task ASSIGNING &amp;lt;task&amp;gt;
      WHERE used IS initial.
      EXIT.
    ENDLOOP.
    CHECK sy-subrc                        = 0.
    &amp;lt;task&amp;gt;-used                           = 'X'.

    name                                  = &amp;lt;task&amp;gt;-name.
  ENDMETHOD.
  METHOD return.
    LOOP AT gt_task INTO ls_task
      WHERE
      name                                = name
      AND used                            = 'X'.
      DELETE gt_task.
    ENDLOOP.
    IF sy-subrc                           = 0.
      CLEAR ls_task-used.
      APPEND ls_task TO gt_task.
    ELSE.
* fatal error
    ENDIF.
  ENDMETHOD.
ENDCLASS.                    "itab IMPLEMENTATION
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  paralleltest
*&amp;amp;---------------------------------------------------------------------*
FORM paralleltest.
  DATA:
  ls_bapi_ref_doc_range                   TYPE bapi_ref_doc_range,
  lv_done                                 TYPE flag,
  lv_group                                TYPE rzllitab-classname,
  lv_task                                 TYPE numc4,
  lv_msg                                  TYPE text255,
  lv_grid_title                           TYPE lvc_title,
  lv_tfill                                TYPE sytfill,
  lv_vbelv                                TYPE vbelv,
  lv_npacs                                TYPE i,
  lt_vbelv                                TYPE SORTED TABLE OF vbelv
    WITH UNIQUE KEY table_line,
  lv_mod                                  TYPE i.
  FIELD-SYMBOLS:
    &amp;lt;intval&amp;gt;                              LIKE LINE OF gt_intval.

* build intervals
  SELECT vbelv  INTO lv_vbelv
    FROM vbfa.
    INSERT lv_vbelv INTO TABLE lt_vbelv.
    CHECK sy-subrc = 0.
    ADD 1 TO lv_tfill.

    CHECK:
      p_dbcnt                             &amp;gt; 0,
      lv_tfill                            &amp;gt;= p_dbcnt.
    EXIT.
  ENDSELECT.
  DESCRIBE TABLE lt_vbelv LINES lv_tfill.
  IF (
       p_pacsz                            &amp;lt; p_dbcnt OR
       p_dbcnt                            = 0
      ) AND
       p_pacsz                            &amp;gt; 0.
*        p_dbcnt                              &amp;gt; 0 ).
    lv_npacs                              = lv_tfill DIV p_pacsz.
    lv_mod                                = lv_tfill MOD p_pacsz.
    IF lv_mod                             &amp;lt;&amp;gt; 0.
      ADD 1 TO lv_npacs.
    ENDIF.
    DO lv_npacs TIMES.
      ls_intval-idxfr                     = ls_intval-idxto + 1.
      ls_intval-idxto                     = ls_intval-idxfr - 1
                                          + p_pacsz.
      IF ls_intval-idxto                  &amp;gt; lv_tfill.
        ls_intval-idxto                   = lv_tfill.
      ENDIF.
      APPEND ls_intval TO gt_intval.
    ENDDO.
  ELSE.
    ls_intval-idxfr                       = 1.
    ls_intval-idxto                       = lv_tfill.
    APPEND ls_intval TO gt_intval.
  ENDIF.

  WHILE lv_done IS INITIAL.
* find an interval to be processed
    LOOP AT gt_intval ASSIGNING &amp;lt;intval&amp;gt;
      WHERE activ                         = space
        AND fails BETWEEN 0 AND  5.
      EXIT.
    ENDLOOP.
    IF sy-subrc                           &amp;lt;&amp;gt; 0.
* no inactive unprocessed interval. All complete or must wait?
* check for intervals with unsuccesful tries
      LOOP AT gt_intval ASSIGNING &amp;lt;intval&amp;gt;
        WHERE fails BETWEEN 0 AND  5.
        EXIT.
      ENDLOOP.
      IF sy-subrc                         = 0.
* wait until all started processes have been received.
* Note: No receive is executed without WAIT
        WAIT UNTIL gv_activ IS INITIAL UP TO 600 SECONDS.
      ELSE.
* all done
        lv_done                           = 'X'.
      ENDIF.
      UNASSIGN &amp;lt;intval&amp;gt;.
    ENDIF.
* process interval if provided
    IF &amp;lt;intval&amp;gt; IS ASSIGNED.
      WHILE lv_task IS INITIAL.
        IF lv_group IS INITIAL.
* init parallel processing
          lv_group = task=&amp;gt;initialize( ).
        ENDIF.
* get unused task
        lv_task                           = task=&amp;gt;provide( ).
        CHECK lv_task IS INITIAL.
* no unused task? wait for all started task are received
        WAIT UNTIL gv_activ IS INITIAL UP TO 600 SECONDS.
      ENDWHILE.
* call if task assigned
      CHECK NOT lv_task IS INITIAL.
* prepare function parameters
      ls_bapi_ref_doc_range               = 'IBT'.
      READ TABLE lt_vbelv INTO ls_bapi_ref_doc_range-ref_doc_low
        INDEX  &amp;lt;intval&amp;gt;-idxfr.
      READ TABLE lt_vbelv INTO ls_bapi_ref_doc_range-ref_doc_high
        INDEX  &amp;lt;intval&amp;gt;-idxto.
* mark interval as failed
      ADD 1 TO &amp;lt;intval&amp;gt;-fails.
      ADD 1 TO gv_snd.
      CALL FUNCTION gc_function
         STARTING NEW TASK lv_task
         DESTINATION                      IN GROUP lv_group
         PERFORMING bapi_receive ON END OF TASK
         EXPORTING
            refdocrange                   = ls_bapi_ref_doc_range
         EXCEPTIONS
           communication_failure          = 1 MESSAGE lv_msg
           system_failure                 = 2 MESSAGE lv_msg
           RESOURCE_FAILURE               = 3.
      IF sy-subrc                         = 0.
        &amp;lt;intval&amp;gt;-activ                    = 'X'.
        &amp;lt;intval&amp;gt;-task                     = lv_task.
        ADD 1 TO gv_activ.
      ELSE.
        CALL METHOD task=&amp;gt;return EXPORTING name = lv_task.
      ENDIF.
      CLEAR lv_task.
    ENDIF.
  ENDWHILE.
* wait for pending processes
  MESSAGE s000(r1) WITH 'Wait for pending processes'.
  WAIT UNTIL gv_activ IS INITIAL.
* report unfinished intervals
  LOOP AT gt_intval ASSIGNING &amp;lt;intval&amp;gt;
    WHERE fails &amp;gt;= 0.
    READ TABLE lt_vbelv INTO ls_bapi_ref_doc_range-ref_doc_low
      INDEX  &amp;lt;intval&amp;gt;-idxfr.
    READ TABLE lt_vbelv INTO ls_bapi_ref_doc_range-ref_doc_high
      INDEX  &amp;lt;intval&amp;gt;-idxto.
    MESSAGE i000(r1)
    WITH
    'Unverarbeitetes Intervall von'
    ls_bapi_ref_doc_range-ref_doc_low
    'bis'
    ls_bapi_ref_doc_range-ref_doc_high.
  ENDLOOP.

  MESSAGE s000(r1) WITH 'start ALV'.

* transfer results to standard table
  WRITE gv_rcv TO lv_grid_title LEFT-JUSTIFIED.
  lv_grid_title+40(1) = '+'.
  WRITE gv_snd TO lv_grid_title+50 LEFT-JUSTIFIED.
  REPLACE '+' WITH 'RCV/SND' INTO lv_grid_title.
  CONDENSE lv_grid_title.

  CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
       EXPORTING
            i_structure_name = 'BAPIVBRKSUCCESS'
            i_grid_title     = lv_grid_title
       TABLES
            t_outtab         = gt_bapivbrksuccess.


ENDFORM.                    " paralleltest
*&amp;amp;---------------------------------------------------------------------*
*&amp;amp;      Form  bapi_receive
*&amp;amp;---------------------------------------------------------------------*
FORM bapi_receive USING pv_task TYPE any.
  DATA:
    lv_task                               TYPE numc4,
    lt_bapivbrksuccess                    TYPE TABLE OF bapivbrksuccess,
    lv_msg                                TYPE text80,
    lv_subrc                              TYPE sy-subrc.
  FIELD-SYMBOLS:
    &amp;lt;intval&amp;gt;                              LIKE LINE OF gt_intval.
  CLEAR lt_bapivbrksuccess.
  RECEIVE RESULTS FROM FUNCTION gc_function
      TABLES
        success                           = lt_bapivbrksuccess
      EXCEPTIONS
        communication_failure             = 1 MESSAGE lv_msg
        system_failure                    = 2 MESSAGE lv_msg .
  lv_subrc                                = sy-subrc.
  lv_task                                 = pv_task.
  CALL METHOD task=&amp;gt;return EXPORTING name = lv_task.
  LOOP AT gt_intval ASSIGNING &amp;lt;intval&amp;gt;
    WHERE task = lv_task
    AND fails &amp;lt;&amp;gt; -1.
    EXIT.
  ENDLOOP.
  IF sy-subrc                             &amp;lt;&amp;gt; 0.
* fatal error
    MESSAGE e000(r1)
      WITH 'returned task' lv_task 'not in task table'.
  ENDIF.
  CLEAR  &amp;lt;intval&amp;gt;-activ.

  CASE lv_subrc.
    WHEN 0.
      &amp;lt;intval&amp;gt;-fails                      = -1.
      APPEND LINES OF lt_bapivbrksuccess TO gt_bapivbrksuccess.
      ADD 1 TO gv_rcv.
    WHEN 1.
      ADD 1 TO &amp;lt;intval&amp;gt;-fails.
      WRITE: 'communication_failure for task', lv_task, lv_msg.
    WHEN 2.
      WRITE: 'system_failure', lv_task, lv_msg.
      ADD 1 TO &amp;lt;intval&amp;gt;-fails.
  ENDCASE.
  SUBTRACT 1 FROM gv_activ.
ENDFORM.                    " bapi_receive
&lt;/CODE&gt;&lt;/PRE&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Regards,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Clemens&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Wed, 28 Nov 2007 18:56:55 GMT</pubDate>
      <guid>https://community.sap.com/t5/application-development-and-automation-discussions/parallel-processing-some-questions/m-p/3075242#M729157</guid>
      <dc:creator>Clemenss</dc:creator>
      <dc:date>2007-11-28T18:56:55Z</dc:date>
    </item>
  </channel>
</rss>

