2013 Jun 21 5:00 PM
Hello everyone,
I am experiencing some difficulties in the implementation of a function to use under parallel processing.
Here's what I have:
LOOP AT i_tab INTO aux_tab.
index = sy-tabix.
CONCATENATE 'Task' index INTO taskname.
CALL FUNCTION 'Z_FUNCTION'
STARTING NEW TASK taskname
DESTINATION IN GROUP DEFAULT
PERFORMING receive_results ON END OF TASK
EXPORTING
var1 = var1
var2 = var2, and so on...
ENDLOOP.
FORM receive_results
USING
taskname.
RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'
IMPORTING
var3 = var3, and so on...
ENDFORM.
If I don't use the "RECEIVE RESULTS FROM..." function, everything works (except for the fact that I don't receive the value of 'var3'). However, when I use such function, I receive this error: CALL_FUNCTION_REMOTE_ERROR (short text: "The function module 'Z_FUNCTION' cannot be used for 'remote' calls.").
Even if I don't use generic types for the import variables and check the "Remote-Enabled Module" option I still get errors, but this time they don't have anything to do directly to my code.
Thank you so much in advance!
2013 Jun 24 8:33 AM
Once you switched your FM to RFC enabled, add an exception like NODATA to the FM to raise an error if no data read and add some code like
* Call
CALL FUNCTION 'Z_FUNCTION'
STARTING NEW TASK taskname
DESTINATION IN GROUP DEFAULT
PERFORMING receive_results ON END OF TASK
EXPORTING
var1 = var1
var2 = var2 " , and so on...
EXCEPTIONS
communication_failure = 1
system_failure = 2
resource_failure = 3.
ADD 1 TO gv_active.
* Receive
RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'
IMPORTING
var3 = var3 " and so on...
EXCEPTIONS
nodata = 1.
SUBTRACT 1 FROM gv_active.
And manage the exceptions in the program (Like not submitting more call than available process, look at FM like SPBT_INITIALIZE and other FMs of group SPBT)
Regards,
Raymond
Once you switched your FM to RFC enabled, add an exception like NODATA to the FM to raise an error if no data read and add some code like
* Call
CALL FUNCTION 'Z_FUNCTION'
STARTING NEW TASK taskname
DESTINATION IN GROUP DEFAULT
PERFORMING receive_results ON END OF TASK
EXPORTING
var1 = var1
var2 = var2 " , and so on...
EXCEPTIONS
communication_failure = 1
system_failure = 2
resource_failure = 3.
ADD 1 TO gv_active.
* Receive
RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'
IMPORTING
var3 = var3 " and so on...
EXCEPTIONS
nodata = 1.
SUBTRACT 1 FROM gv_active.
And manage the exceptions in the program (Like not submitting more call than available process, look at FM like SPBT_INITIALIZE and other FMs of group SPBT)
Regards,
Raymond
2013 Jun 21 6:33 PM
Remote-Enabled module has to be turned on to use the starting new task... What is the error you receive when this is enabled?
2013 Jun 21 6:58 PM
Hi, Lucas!
I just did what you told me and also solved some of the issues. Now it's working (kind of).
The results are still not being returned (after using RECEIVE RESULTS...IMPORT var3). Var3 is still empty.
Thanks!
2013 Jun 21 7:31 PM
I can't see any reason you wouldn't be getting back the results you expect... I guess at this point make sure the function module you're calling is working properly (run it on its own to see expected output) and make sure in the receive_results you're putting the results in to some global field that is accessible from the rest of your program.
2013 Jun 22 1:44 PM
You could put WRITE statements everywhere to track flow of logic.
Inside Z_FUNCTION , print var1 var2.
In subroutine receive_results, print var3.
Add var3 to global variable OR append var3 to global internal table.
Increment a counter every time Z_FUNCTION is called. (threads_started)
Increment a counter every time results are received. (threads_finished)
Add a statement right after ENDLOOP. ( WAIT UNTIL threads_finished >= threads_started. )
After WAIT statement, all threads should have completed and your global variable/table will have aggregated results.
2013 Jun 21 8:02 PM
Hi Rafael,
The form execute only when program is roll out state. This is asynchronous call so we have to make calling program wait for receiving result that is make program roll out state. We can done it by statement WAIT UNTILL<LOGICAL STAMENT>
I think we cannot use generic type in rfc FM as parameters,we should use dictionary type
For more details
http://help.sap.com/saphelp_nw70/helpdata/en/fa/096e92543b11d1898e0000e8322d00/content.htm
Regards,
Sreenivas.
2013 Jun 23 4:07 AM
Hi Rafael,
Add this line after your call function statement.
WAIT UNTIL NOT ( <f1> IS INITIAL AND <f2> IS INITIAL AND ..<fn> IS INITIAL).
2013 Jun 24 8:33 AM
Once you switched your FM to RFC enabled, add an exception like NODATA to the FM to raise an error if no data read and add some code like
* Call
CALL FUNCTION 'Z_FUNCTION'
STARTING NEW TASK taskname
DESTINATION IN GROUP DEFAULT
PERFORMING receive_results ON END OF TASK
EXPORTING
var1 = var1
var2 = var2 " , and so on...
EXCEPTIONS
communication_failure = 1
system_failure = 2
resource_failure = 3.
ADD 1 TO gv_active.
* Receive
RECEIVE RESULTS FROM FUNCTION 'Z_FUNCTION'
IMPORTING
var3 = var3 " and so on...
EXCEPTIONS
nodata = 1.
SUBTRACT 1 FROM gv_active.
And manage the exceptions in the program (Like not submitting more call than available process, look at FM like SPBT_INITIALIZE and other FMs of group SPBT)
Regards,
Raymond
2013 Jun 24 8:45 AM
2013 Jun 24 10:26 AM
Counter gv_active is meant to keep track of number of active tasks (parallel threads).
Counter is incremented every time new task is started.
Counter is decremented every time results are received.
This variable can be used in WAIT UNTIL statement to check whether all tasks have completed.
2013 Jun 24 12:04 PM
Mmm, good idea. what's type of this variable(gv_active). I can't find any in the system field list.
2013 Jun 24 12:16 PM
Define it as an integer in global area of the program, its purpose is to keep the number of already active call (called but not yet received, so number of interactive process used by those call, look at transaction RZ12 for group definition, and SM50 during execution to see your active call)
So in your loop after each call wait until this number get lower or equal than the maximum number of process returned by SPBT_INITIALIZE. (WAIT UNTIL gv_active LE max_pbt_wps.)
For more information, read some documentation like Implementing Parallel Processing.
Regards,
Raymond
2013 Jun 24 12:23 PM
Integer type would work fine.
The SAP Help example uses two counters in WAIT UNTIL condition.
WAIT UNTIL RCV_JOBS >= SND_JOBS UP TO '1' SECONDS.
While using gv_active, statement would be something like this.
WAIT UNTIL gv_active = 0 UP TO '1' SECONDS.
So, gv_active is essentially the difference between rcv_jobs and snd_jobs.
| User | Count |
|---|---|
| 3 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 | |
| 1 |