4 votes

Plusieurs aRFC avec WAIT, comment synchroniser l'accès à la variable dans le callback ?

J'utilise des appels RFC asynchrones pour effectuer des travaux parallèles dans SAP. Voici mon pseudo-code.

* class variable
data: gv_counter type i .

....

method start_tasks .

    do 10 times .

        call function 'my_remote_function'
            starting new task task_identifier
            calling task_finish on end of task .

    enddo .

    wait for asynchronous tasks until gv_counter eq 10 .    

endmethod .

.....

method task_finish .

    gv_counter = gv_counter + 1 .

endmethod .

Comme vous pouvez le voir, je lance 10 processus et j'attends qu'ils soient tous terminés.

Ma question porte sur la méthode task_finish et l'accès à la variable globale de la classe gv_counter . Comment puis-je m'assurer que l'accès à la variable gv_counter est synchronisé ?

Par exemple, en Java, je ferais quelque chose comme ça :

synchronized {
    gv_counter += 1 ;
}

5voto

Jagger Points 2869

Voici une citation du SAP la documentation sur le sujet.

Ajout 2

... {CALLING meth}|{PERFORMING subr} À LA FIN DE LA TÂCHE

...

Si plusieurs routines de rappel sont enregistrées au cours d'une section de programme, elles sont exécutées dans un ordre indéfini lorsque le processus de travail change lors d'un roll-in.

Pour moi, cela signifie qu'ils seront exécutés l'un après l'autre (dans l'ordre), ce qui n'est toutefois pas défini. Cela signifierait que votre variable atteindrait toujours la valeur 10.

Vous pouvez en fait le déboguer, pour voir comment il est traité séquentiellement lorsque vous placez un point d'arrêt dans le fichier task_finish méthode. Voici mon exemple.

REPORT ZZZ.

CLASS lcl_main DEFINITION FINAL CREATE PRIVATE.
  PUBLIC SECTION.
    CLASS-METHODS:
      main,
      task_finish
        IMPORTING
          p_task TYPE clike.
  PRIVATE SECTION.
    CLASS-DATA:
      gv_counter TYPE i.
    CLASS-METHODS:
      start_tasks.
ENDCLASS.

CLASS lcl_main IMPLEMENTATION.
  METHOD main.
    start_tasks( ).
  ENDMETHOD.

  METHOD start_tasks.
    DATA: l_task TYPE string.
    DO 10 TIMES.
      l_task = sy-index.
      CALL FUNCTION 'Z_ARFC_ECHO'
        STARTING NEW TASK l_task
        CALLING task_finish ON END OF TASK
        EXPORTING
          i_value       = sy-index.

    ENDDO.

    WAIT FOR ASYNCHRONOUS TASKS UNTIL gv_counter = 10.
  ENDMETHOD.

  METHOD task_finish.
    DATA: l_value TYPE sy-index.
    RECEIVE RESULTS FROM FUNCTION 'Z_ARFC_ECHO'
      IMPORTING
        e_echo = l_value.

    WRITE: /, p_task, l_value.

    gv_counter = gv_counter + 1.
  ENDMETHOD.
ENDCLASS.

START-OF-SELECTION.
  lcl_main=>main( ).

Mon RFC se présente comme suit

FUNCTION Z_ARFC_ECHO.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*"  IMPORTING
*"     VALUE(I_VALUE) TYPE  SY-INDEX
*"  EXPORTING
*"     VALUE(E_ECHO) TYPE  SY-INDEX
*"----------------------------------------------------------------------

e_echo = i_value.

ENDFUNCTION.

Ce qui est également intéressant (et également mentionné dans la documentation), c'est la liste des déclarations de sortie telles que WRITE ne sont pas traitées dans un tel gestionnaire, c'est pourquoi vous ne voyez rien s'imprimer à la fin de l'exécution du rapport susmentionné.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X