Ansicht
Dokumentation

CL_SSI_DISPATCH - ABAP Dispatcher

CL_SSI_DISPATCH - ABAP Dispatcher

ABAP Short Reference   RFUMSV00 - Advance Return for Tax on Sales/Purchases  
Diese Dokumentation steht unter dem Copyright der SAP AG.
SAP E-Book

Funktionalität

Grundprinzip

Die Klasse CL_SSI_DISPATCH unterstützt die Parallelisierung innerhalb eines SAP-Systems. Sie kann insbesondere in Kombination mit asynchronen RFC Aufrufen sehr einfach verwendet werden. Die Hauptvorteile sind:

  • Die Ressourcen-Kontrolle während der Parallelisierung wird intern durchgeführt. Dazu gehören das Vermeiden von Überlast-Situationen durch Verzögerung während des Ablaufs ("throttling") als auch die optimale Auswahl / Verwendung der verfügbaren Ressourcen.
  • Für die internen Verzögerungen (Throttling) wird die ABAP Anweisung WAIT bzw. eine interne Variante davon verwendet.
  • Die Integration in bestehende Anwendungen ist sehr einfach.

Das Grundprinzip, nach der die Klasse arbeitet, beruht auf der "Server-Last-Information", die von jeder ABAP Instanz jede Sekunde berechnet wird. Wenn eine ABAP Instanz für einen Service wie z.B. "DIALOG-Prozess" bzw. für eine Priorität eine hohe Last feststellt, dann teilt sie dies allen anderen ABAP-Instanzen mit (siehe auch die Lastanzeige in Transaktion SM51). Somit gib es im System immer eine relativ aktuelle, über alle ABAP-Instanzen verteilte Last-Information.

CL_SSI_DISPATCH nutzt diese Lastinformation aus und berücksichtigt beim Verteilen der Aufgaben alle Instanzen, deren Last-Situation normal ist. Instanzen mit hoher Last werden hingegen solange ignoriert, bis ihre Last wieder normal ist. In Situationen, in denen entweder die maximale Anzahl von parallelen Aufgaben (sogenannte Tasks) erreicht ist oder es gerade keine ABAP Instanz mit normaler Last gibt, wartet CL_SSI_DISPATCH intern mittels WAIT Anweisung so lange, bis sich entweder Tasks beendet haben oder es wieder ABAP Instanzen mit normaler Last gibt.

Der schematische Ablauf bei Verwendung der Klasse CL_SSI_DISPATCH ist folgender:

  • es wird ein Objekt der Klasse CL_SSI_DISPATCH erzeugt
  • innerhalb einer Schleife
  • wird ein Arbeitspaket erstellt

  • mittels der Methode DISPATCH eine Destination ermittelt

  • das Arbeitspacket durch Aufruf eines asynchronen RFCs mit der ermittelten Destination ausgeführt

Im Nachfolgenden wollen wir eine ABAP Backend Session, welche dieses Coding ausführt, Dispatcher-Session nennen. Eine Instanz der Klasse CL_SSI_DISPATCH werden wir auch als ABAP Dispatcher bezeichnen.

Unterschied zwischen asynchronen RFC Aufrufen mit und ohne "END OF TASK" Callback

Bei Angabe asynchrone RFC Aufrufen kann man eine Callback-Methode (bzw. Form-Routine), angeben, die nach Beendigung des gestarteten Bausteines aufgerufen wird. Dies ermöglicht der Anwendung die Rückgabe von Ergebnissen. Bei Verwendung der Klasse CL_SSI_DISPATCH muss auf alle Fälle ein "END OF TASK" Callback verwendet werden:

  • Nur so kann genau über die aktuell ablaufenden Tasks Buch geführt werden und deren Anzahl sinnvoll begrenzt werden
  • Beim Starten eines asynchronen RFC gibt es immer einen synchronen Teil, bevor die Ausführung nebenläufig weiterläuft. Dieser synchrone Teil ist bei Verwendung von "END OF TASK" wesentlich kürzer.
  • Durch Verwendung von "END OF TASK" wird eine Nachricht von der Task-Session zur Dispatcher-Session gesendet. Dies nutzt CL_SSI_DISPATCH für eine möglichst genaue Buchführung der offenen Tasks aus. Insbesondere bei Verwendung von Task Namen wird damit die Qualität des Dispatchings verbessert.
Dispatching und Kernel-Prioritäten

Der ABAP Kernel unterstützt die Prioritäten HOCH, MITTEL und NIEDRIG. Diese Prioritäten werden nach einem festen Schema den ABAP User-Sessions zugeordnet. Bei der Parallelisierung gilt:

  • läuft die Dispatcher-Session mit Priorität HOCH oder MITTEL, dann werden alle Arbeitspakete mit der nächst niedrigeren Priorität ausgeführt
  • läuft die Dispatcher-Session bereits mit Priorität NIEDRIG, werden auch alle Arbeitspakete mit Priorität NIEDRIG ausgeführt.

Dies ist wichtig, weil es die Berechnung der Anzahl der maximal parallel ausführbaren Arbeitspakte bestimmt. Diese Anzahl ergibt sich als Summe der Prioritäten-Quotas über alle in Frage kommenden ABAP Instanzen (siehe dazu die Parameter rdisp/scheduler/prio_[normal|low]/max_quota.

Anwendungsprioritäten

Es gibt Anwendungen, bei denen Parallelisierungen sehr lange laufen können. Hierbei gibt es den Wunsch, auf Anwendungsebene eine Priorisierung vornehmen zu können. Wird z.B. so ein "Langläufer" mit einer Anwendungspriorität "NIEDRIG" gestartet, soll eine danach gestartete Parallelisierung mit einer höheren Anwendungspriorität vom System mit Vorrang bearbeitet werden. Es ist wichtig, hier Anwendungsprioritäten nicht mit den Kernel-Prioritäten zu verwechseln.

Werden Anwendungsprioritäten verwendet, dann

  • ist 0 die höchste Priorität, die nächst niedrige Priorität ist 1, dann 2 usw. Gülte Prioritäten liegen im Intervall [0, 9].
  • laufen Parallelisierungen mit gleicher Anwendungspriorität nebenläufig
  • kann bei konkurrierenden Anwendungen mit unterschiedlicher Anwendungspriorität zwischen einer "SUSPEND/RESUME" - Strategie und einer "SHARING" - Strategie gewählt werden:
  • SUSPEND/RESUME: Anwendungen mit niedriger Anwendungspriorität werden so lange suspendiert, bis alle Anwendungen mit höherer Priorität beendet wurden.

  • SHARING: alle Anwendungen laufen parallel. Jedoch wird bei Anwendungen mit niedrigerer Anwendungspriorität die Parallelisierung reduziert. Für die Berechnung der maximalen Parallelisierung gibt es zwei Modelle: FIXED_SHARING und DYNAMIC_SHARING.

Um ungewünschte Wechselwirkungen von Anwendungs- und Kernel-Prioritäten zu vermeiden wird bei Verwendung des ABAP Dispatchers die sogenannte Task-Priorität auf NIEDRIG gesetzt. D.h. alle mittels asynchronem RFC ausgeführten Arbeitspakete werden mit der Priorität NIEDRIG bearbeitet. Dadurch verhalten sich ABAP Dispatcher unabhängig von der Kernel-Priorität ihrer ABAP Backend-Session immer gleich.

Des Weiteren kann innerhalb einer ABAP Backend-Session nur ein DISPATCH Objekt mit aktiven Anwendungsprioritäten erzeugt werden.

Task Namen

Wenn die Kapazitäten der verwendeten Server sehr unterschiedlich ist (#CPUs, Hauptspeicher usw.) kann es sein, dass die Aufgaben auf einem Server sehr viel schneller erledig werden als auf einem anderen. Um hier ein optimales Dispatching zu erreichen, darf nicht nur die Anzahl der Workprozesse als Größe beim Dispatching verwendet werden. Vielmehr ist es notwendig, die offenen Aufgaben genauer zu verfolgen. Dies ist dann möglich, wenn die Anwendung "task names" unterstützt:

  • beim Aufruf der Methode DISPATCH wird ein eindeutiger Task Name mitgegeben. Eindeutig heißt, dass für jeden Aufruf ein neuer Task-Name erzeugt wird und dieser Name während des Dispatching nicht wiederverwendet wird.
  • Der asynchrone RFC mit einem "END OF TASK" Callback aufgerufen wird.

Dies erlaubt es, mehr Aufgaben auf Server mit weniger ausstehenden Antworten zu verteilen.

Task-Größen

Evtl. sind die auszuführenden Aufgaben sehr verschieden hinsichtlich ihres Ressourcen-Verbrauchs. Insbesondere wenn Aufgaben sehr große ABAP Sessions erzeugen kann es zu Laufzeitfehlern führen, wenn zu viele solcher Aufgaben zur gleichen Zeit auf einem Server ausgeführt werden. Um solche Fehler zu vermeiden, kann man beim Verteilen eine geschätzte Größe mitgeben (siehe Methode DISPATCH). Ein sehr einfacher Weg, zu Schätzungen und einem lernenden Verhalten zu kommen kann man im Zusammenspiel mit den Klassen CL_SESSION_INFO und CL_SSI_TASK_RT_INFO erhalten. Dazu sind folgende Schritte notwendig:

  • Beim Dispatching Teil der Anwendung:
  • einen Anwendungs-Id verwenden.

  • Task Namen verwenden.

  • Vor dem Beginn der Verarbeitung das "Gedächtnis über bereits abgearbeitete Tasks" bereinigen (siehe dazu Klasse CL_SSI_TASK_RT_INFO, Methode CLEANUP_RUNTIME_INFO_OF_APPL)

  • Den einzelnen Tasks einen "logischen" Namen zuordnen.

  • Diese logischen Namen den Tasks (d.h. dem asynchronen RFC) per Parameter mitgeben.

  • Beim Dispatchen eine geschätzte Größe ermitteln (siehe dazu Klasse CL_SSI_TASK_RT_INFO, Methode GET_RUNTIME_INFO_AVG) und diese Größe der Methode DISPATCH mitgeben.

  • innerhalb einer Task:
  • am Ende der Verarbeitung das Maximum der Session-Größe während der Verarbeitung ermitteln (siehe dazu Klasse CL_SESSION_INFO, Methode GET_MY_MEMORY_PEAK_VALUES).

  • diesen Wert im "Gedächtnis bereits abgearbeitete Tasks" unter dem logischen Namen der Task ablegen (siehe dazu Klasse CL_SSI_TASK_RT_INFO, SET_RUNTIME_INFO).

Dynamische Anpassung bei Veränderungen der verwendeten Server-Liste

ABAP Dispatcher passen sich während ihrer Laufzeit dynamisch an Veränderungen der Server-Liste an. Kommt z.B. eine ABAP Instanz hinzu, die verwendet werden kann, erhöht der ABAP Dispatcher automatisch die maximale Anzahl der ausführbaren Tasks und verteilt Tasks auf die neue Instanz.

Entsprechend wird beim Stoppen einer ABAP Instanz die Anzahl der parallel ausführbaren Tasks verkleinert und die

Verteilung von Task auf die gestoppte ABAP Instanz beendet. Bei Verwendung des Soft Shutdowns sollte diese Anpassung ohne jegliche Abbrüche erfolgen.

Erzeugung eines Objektes

Objekte der Klasse CL_SSI_DISPATCH können mit folgenden Factory-Methoden erzeugt werden:

  • CREATE_DISPATCHER_FOR_SYSTEM: es wird ein Dispatcher erzeugt, der alle Server des Systems verwendet. CREATE_DISPATCHER_FOR_GROUP: es wird ein Dispatcher erzeugt, der Requests für die Server der angegebenen Gruppe erzeugt.
  • Diese Factory-Methoden sind so einfach wie möglich gehalten und erlauben nur das Setzen weniger Parameter ((maximale Anzahl paralleler Tasks, Anwendungspriorität, Strategie für parallel laufende ABAP Dispatcher, Anwendungs-Id und Server-Gruppe).
  • Zusätzlich gibt es einen Klassenkonstruktor, der sehr viel mehr Optionen anbietet. Dieser sollte jedoch möglichst nicht verwendet werden.

Zusätzlich zu den Parametern der Factory-Methoden und des Klassenkonstruktors können einige Eigenschaften zentral mittels Profil-Parametern eingestellt werden:

  • Parameter rdisp/ssi_dispatch/trace: mit diesem Parameter kann ein Tracing des Dispatchers aktiviert werden. Der Dispatcher schreibt dann Einträge mit dem Prefix SSI_DISP in den Developer-Trace.
  • Parameter rdisp/ssi_dispatch/configuration: mit diesem Parameter kann der Default-Wert für die verwendete Strategie verändert werden.

Bei der Instanziierung eines Objektes der Klasse können folgende Parameter angegeben werden:

  • use_all_server_of_system / server_list / server_group / only_active_server: hiermit wird angegeben, welche ABAP Instanzen für die Verteilung in Frage kommen. Es gilt:
  • use_all_server_of_system und die beiden Parameter serverList und server_group schließen sich aus.

  • Werden sowohl eine Liste von Server als auch eine Server-Gruppe angegeben, gelten diese additiv.

  • Als Server-Gruppe wird der Name einer RFC-Server-Gruppe erwartet.

  • only_active_server: nur Server im Zustand "RUNNING" werden berücksichtigt.

  • max_parallel_tasks_as_percent / max_parallel_tasks: hiermit kann festgelegt werden, wie viele parallele Aufgaben erzeugt werden können. Diese Angabe kann als Prozentwert oder absolut erfolgen. Die maximale Parallelität ergibt sich bei einem Wert von 100 %. Dies bedeutet, dass alle zur Verfügung stehenden Workprozesse verwendet werden können.
  • Die weiteren Parameter appl_id, appl_priority, appl_priority_timeout und set_appl_info können verwendet werden, um Anwendungsprioritäten zu aktivieren:
  • appl_id: eine frei wählbare Identifikation der Anwendung

  • appl_priority: eine natürliche Zahl >= 0

  • appl_priority_timeout: wenn ein Dispatch-Objekt mit Anwendungs-Priorität erzeugt wird, wird dies im gesamten System bekannt gegeben um andere Dispatch-Objekte mit niedriger Priorität zu suspendieren bzw. die Resourcen zu verteilen. Falls es jedoch zu einem fehlerhaften Ende der Parallelisierung kommt, muss dies ebenfalls im System bekannt gegeben werden. Dies geschieht spätestens nach Ablauf des angegebenen Timeouts.

  • appl_priority_strategy: es werden die Strategien SUSPEND (Konstante CO_APPL_STRATEGY_SUSPEND), FIXED_SHARING (Konstante CO_APPL_STRATEGY_FIXED_SHARING) und DYNAMIC_SHARING (Konstante CO_APPL_STRATEGY_DYN_SHARING) unterstützt. Die Details sind im nächsten Abschnitt beschrieben.

  • appl_priority_weight: Gewichtung zur Berechnung der maximallen Parallelität

  • set_appl_info: hier kann angegeben werden, ob zu Monitorzwecken eine Anwendungs-Information gesetzt werden soll. Diese kann man dann z.B. mit der Transaktion SM50 angezeigt werden.

  • use_task_names: hier kann angegeben werden, ob die Anwendung für ein verbessertes Dispatching beim Aufruf der Methoden DISPATCH und RECEIVED_RESULT Task-Namen zur Verfügung stellt.
  • max_wait_time: hier kann die interne Wartezeit konfiguriert werden. Falls notwendig wartet CL_SSI_DISPATCH intern, bis ein neuer Task gestartet werden kann. Diese Wartezeit ist ohne Angabe des Parameters nicht begrenzt und kann durch Angabe des Parameters verändert werden. Die Einheit sind Sekunden. Der Wert 0 führt dazu, dass CL_SSI_DISPATCH kein internes Warten durchführt.
Löschen des Objektes / Garbage Collection

Beim Erzeugen des DISPATCH-Objektes werden globale Veränderungen durchgeführt:

  • Das DISPATCH-Objekt wird systemweit sichtbar gemacht
  • Die Task-Priorität der ABAP Session für asynchrone RFC Aufrufe wird reduziert.

Diese Änderungen müssen beim Löschen des Objektes rückgängig gemacht werden. Dies kann zum einen durch die Anwendung mittels Aufruf der Methode END_DISPATCHING erfolgen. Des Weiteren wurde für das DISPATCH Objekt ein Kernel-Destruktur hinterlegt, der die gleichen Aktionen im Rahmen der ABAP Garbage-Collection bzw. in Fehlerfällen beim Aufräumen der ABAP Session durchführt.

Parallelisierung bei Strategie SUSPEND

Bei dieser Methode werden gleichzeitig laufende Anwendungen mit niedrigerer Anwendungspriorität so lange suspendiert, bis sämtliche Anwendungen mit höherer Anwendungspriorität beendet wurden.

Parallelisierung bei Strategie FIXED_SHARING

Bei dieser Sharing-Methode werden die Anwendungsprioritäten gewichtet. Dabei reduziert ein ABAP Dispatcher seine Parallelität, wenn es ABAP Dispacher mit höherer Anwendungspriorität gibt. Für einen ABAP Dispatcher mit Anwendungspriorität appl_prio ergibt sich

  • falls appl_prio die maximale aktive Priorität ist: die neue Parallelität ist gleich der maximalen Parallelität
  • Die "eigene" Anwendungspriorität erhält das feste Gewicht 1.
  • Beim Übergang zur nächst höheren Anwendungspriorität erhöht sich die Gewichtung um die Prioritätengewichtung (appl_priority_weight).
  • Diese Gewichte aller Anwendungsprioritäten mit mindestens einem aktiven ABAP Dispatcher werden addiert und ergeben einen Divisor.
  • die neue Parallelität des ABAP Dispatcher ergibt sich dann aus der Formel maximale Parallelität / Divisor

Beispiel:

max_tasks = 80

appl_priority_weight = 2

1 ABAP Dispatcher A0 mit Anwendungsprioritäten 0 aktiv

2 ABAP Dispatcher A11 und A12 mit Anwendungspriorität 1 aktiv

1 ABAP Dispatcher A2 mit Anwendungspriorität 2 aktiv

Dann ergibt sich für die einzelnen Anwendungen:

für A0:

  • Anwendungspriorität 0 ist die höchste Priorität.
  • die neue Parallelität ist damit 80 / 1 = 80

für A11 und A12:

  • Anwendungspriorität 1 hat Gewicht 1
  • Anwendungspriorität 0 hat Gewicht 2
  • Damit ergibt sich ein Divisor von 3
  • die neue Parallelität für A11 und A12 ist damit 80 / 3 = ~ 27

für A2:

  • Anwendungspriorität 2 hat Gewicht 1
  • Anwendungspriorität 1 hat Gewicht 2
  • Anwendungspriorität 0 hat Gewicht 4
  • Damit ergibt sich ein Divisor von 7
  • die neue Parallelität für A2 ist damit 80 / 7 = ~ 11
Parallelisierung bei Strategie DYNAMIC_SHARING

Bei dieser Sharing-Methode wird die maximale Parallelität anhand aller laufenden ABAP-Dispatcher und ihrer gewichteten Prioritäten ermittelt:

  • Die niedrigste Anwendungspriorität erhält Gewicht 1 erhält.
  • Beim Übergang zur nächst höheren Anwendungspriorität erhöht sich die Gewichtung um die konstante Prioritätengewichtung (appl_priority_weight).
  • Diese Anwendungsgewichte werden mit der Anzahl der laufenden Anwendungen multipliziert und ergeben einen Divisor pro Anwendungspriorität.
  • Diese Divisoren werden zu einem Gesamtdivisor addiert
  • die neue Parallelität für einen ABAP Dispatcher mit Anwendungspriorität appl_prio ergibt sich dann aus der Formel ( maximale Parallelität * Gewicht der Anwendungspriorität appl_prio ) / Gesamtdivisor
  • In dem obigen Beispiel mit A0, A11, A12 und A2:
  • die Prioritäten 0, 1 und 2 sind aktiv. Das ergibt die Gewichte
  • 1 für Prio 2

  • 3 für Prio 1

  • 5 für Prio 0

  • damit ergeben sich die Divisoren
  • 1 für Priorität 2

  • 3 * 2 = 6 für Priorität 1 (zwei ABAP Dispatcher)

  • 5 für Priorität 0

  • Der Gesamtdivisor ist deren Summe und beträgt 12
  • für A0 ergib sich damit die Parallelität von ( 80 * 5 ) / 12 = ~ 33
  • für A11 und A12: ( 80 * 3 ) / 12 = 20
  • Für A2: (80 * 1 ) / 12 = ~ 6
Öffentliche Schnittstelle Instanzmethoden Methode CLEAR_TASK_AFTER_ERROR

Normalerweise wird eine Task und ihre Metainformationen (Name, geschätzte Größe) durch den Aufruf der Methode dispatch in die interne Task-Verwaltung eingetragen und beim Aufruf der Methode RECEIVED_RESULT wieder ausgetragen. Wird für eine ausgeführte Task ein Fehler empfangen, kann die Task mittels dieser Funktion wieder aus der Taskverwaltung entfernt werden (anstatt die Funktion RECEIVED_RESULT aufzurufen).

Methode CONTRUCTOR

Das ist der Klassen-Konstruktor.

Methode DESTRUCTOR

Das ist der Klassen-Destruktor.

Methode DISPATCH

Die Methode DISPATCH liefert den Namen der ABAP Instanz zurück, welche zur Ausführung der nächsten Task verwendet werden sollte. Gibt es momentan keinen geeignete ABAP Instanz oder ist die maximale Anzahl paralleler Tasks erreicht, wird intern mittels der ABAP Anweisung WAIT gewartet. Durch Verwendung des Konstruktor Parameters max_wait_time oder durch Aufruf der Methode SET_MAX_WAIT_TIME kann die maximale Zeit für dieses Warten begrenzt werden. Kommt es zu einer Überschreitung, erzeugt die Methode DISPATCH die Ausnahme CX_SSI_NO_SERVER.

Methode END_DISPATCHING

Diese Methode sollte nach Beendigung des Dispatching aufgerufen werden. Insbesondere bei Verwendung von Anwendungsprioritäten ist dies von Bedeutung, da dadurch

  • evtl. suspendierte Parallelisierungen fortgesetzt werden
  • die globalen Veränderungen zurückgenommen werden (siehe auch Löschen des Objektes)

Der Parameter wait_for_end_of_tasks bestimmt, ob innerhalb der Methode auf noch ausstehende Tasks gewartet werden soll. In diesem Falle gibt der Parameter timeout die maximale Wartezeit in Sekunden an. Der Wert -1 bedeutet keine Begrenzng der Wartezeit.

Nach Aufruf von END_DISPATCHING führen weitere Aufrufe der Methode DISPATCH zu einem Fehler.

Methode ESTIMATED_SIZE_OF_TASK

Falls die Task-Größen-Abschätzung verwendet wird, gibt diese Methode für die angegebene Task den Wert zurück, der beim Aufruf der Methode DISPATCH mitgegeben wurde. Dies gilt jedoch nur solange, wie die Task noch nicht ausgeführt wurde. Ansonsten wird die Exception CX_SSI_NOT_FOUND geworfen.

Methode MAX_NUMBER_OF_PARALLEL_TASKS

Diese Methode gibt anhand der angegebenen ABAP Instanzen und deren Konfiguration die maximale Anzahl von parallel ausführbaren Tasks zurück.

Methode MAX_PENDING_RESPONSES

Diese Methode ermittelt, wie viele parallele Tasks im Moment des Aufrufes möglich sind. Diese Zahl kann unterschiedlich zum von MAX_NUMBER_OF_PARALLEL_TASKS ermittelten Wert sein (z.B. wenn bei Verwendung von Anwendungsprioritäten und einer der sharing Strategien mehrere ABAP Dispatcher aktiv sind).

Methode READ_DISPATCHER_TABLE

Diese Methode ermittelt eine Tabelle aller aktiven ABAP Dispatcher und deren Metadaten. Sie wird innerhalb der Transaktion ABAP_DISPATCHER verwendet und dient dem Monitoring.

Methode READ_DISPATCHER_TASK_TABLE

Diese Methode ermittelt bei aktiver Task-Größen-Schätzung die Größe der ablaufenden Tasks. Sie wird innerhalb der Transaktion ABAP_DISPATCHER verwendet und dient dem Monitoring.

Methode READ_TASK_INFO

Diese Methode liest zu einem ABAP Dispatcher Informationen über die Tasks (maximale Anzahl von Tasks, Anzahl der gerade ausgeführten Tasks, insgesamt verteilte Tasks). Sie wird innerhalb der Transaktion ABAP_DISPATCHER verwendet und dient dem Monitoring.

Methode RECEIVED_RESULT

Diese Methode sollte aufgerufen werden, wenn das Ergebnis einer Task-Ausführung erhalten wurde, d.h. die Task beendet wurde.

Methode SET_FREQUENCY

In gewissen Anwendungen (z.B. beim eMail Versand) ist es wichtig, dass der Task-Durchsatz, d.h. die Anzahl der ausgeführten Tasks pro Zeit, ein gewisses Limit nicht überschreitet. Dieses Limit kann mittels dieser Methode definiert werden.

Methode SET_MAX_TASKS

Mit dieser Methode kann der bei der Instanziierung übergebene Parameter max_parallel_tasks dynamisch verändert werden.

Methode SET_MAX_TASKS_AS_PERCENT

Mit dieser Methode kann der bei der Instanziierung übergebene Parameter max_parallel_tasks_as_percent dynamisch verändert werden.

Methode SET_MAX_WAIT_TIME

Mit dieser Methode kann die maximale Zeit für das interne Warten eingestellt werden. Mögliche Werte sind

  • CO_INFINITE_WAIT_TIME: keine zeitliche Begrenzung für das interne Warten (Standardeinstellung)
  • Werte >= 0: maximale Wartezeit in Sekunden. Wenn in dieser Zeit kein weiterer Aufruf erlaubt ist, erzeugt die Methode DISPATCH die Ausnahme CX_SSI_NO_SERVER. Der Wert 0 führt dazu, dass CL_SSI_DISPATCH kein internes Warten durchführt.
Methode TASK_FAILED

Normalerweise wird eine Task und ihre Metainformationen (Name, geschätzte Größe) durch den Aufruf der Methode dispatch in die interne Task-Verwaltung eingetragen und beim Aufruf der Methode RECEIVED_RESULT wieder ausgetragen. Kommt es vor dem Starten der Task oder beim Starten der Task zu einem Fehler, kann die Task mittels dieser Funktion wieder aus der Taskverwaltung entfernt werden.

Statische Methoden Methode ACTIVE_DISPATCHER

Diese Methode liefert die systemweite Anzahl der aktiven Dispatcher.

Methode ACTIVE_DISPATCHER_WITH_PRIO

Diese Methode liefert die systemweite Anzahl der aktiven Dispatcher mit Anwendungspriorität.

Methoden CREATE_DISPATCHER_FOR_GROUP und CREATE_DISPATCHER_FOR_SYSTEM

Dieser beiden Klassen-Factory-Methoden ermöglichen eine möglichst einfache Erzeugung eines ABAP Dispatchers. Sie bieten nur die wichtigsten Konstruktor-Parameter an.

Methode GET_MAX_NUM_OF_PARALLEL_TASKS

Statische Methode, die analog der Methode MAX_NUMBER_OF_PARALLEL_TASKS die maximale Anzahl paralleler Tasks ermittelt.

Methode GET_MAX_PENDING_RESPONSES

Statische Methode, die analog der Methode MAX_PENDING_RESPONSES die maximale Anzahl der parallel ausführbaren Tasks ermittelt.

Methode GET_TIME

Hilfsfunktion, liefert die Anzahl der vergangenen Sekunden seit dem 1.1.1970.

Methode PARALLEL_TASKS_OF_THIS_SERVER

Diese Methode ermittelt die maximale Anzahl paralleler Tasks für die lokale ABAP Instanz.

Beispiele

Hier ist ein kleines Beispielprogramm, welches die Verwendung von CL_SSI_DISPATCH illustriert:

REPORT zdemo_dispatch.

PARAMETERS: no_rfc TYPE i DEFAULT 100,
sec TYPE i DEFAULT 1,
prio TYPE i DEFAULT -1,
appl_id TYPE string DEFAULT 'Test',
task_max TYPE i DEFAULT 100,
prog_ind AS CHECKBOX DEFAULT 'X'.


DATA: dest TYPE rfcdest,
num_of_rfc_calls TYPE i,
i1 TYPE i,
results_count TYPE i VALUE 0,
taskname(4) TYPE n VALUE 0,
t1 TYPE i,
t2 TYPE i,
time_sum TYPE f,
pending_response TYPE i,
dispatch TYPE REF TO cl_ssi_dispatch.

num_of_rfc_calls = 0.
t1 = 0.

TRY.
" create dispatch object
dispatch = cl_ssi_dispatch=>create_dispatcher_for_system(
EXPORTING
max_parallel_tasks_as_percent = task_max
appl_priority = prio
appl_id = appl_id ).
CATCH cx_ssi_no_server.
CATCH cx_ssi_no_auth.
CATCH cx_ssi_bad_parameter.
RETURN.
ENDTRY.

" Trigger asynchronous RFC calls
DO no_rfc TIMES.
" Take start time of this loop
GET RUN TIME FIELD t1.

taskname = taskname + 1.

" Trigger asynchronous RFC calls.
" get next server
" - method dispatch will sleep internal if all servers of the server list are overloaded
TRY.
dest = dispatch->dispatch( task_name = conv string( taskname ) ).
CATCH cx_ssi_no_server.
WRITE 'No valid server found, abort program'.
RETURN.
ENDTRY.

CALL FUNCTION 'DO_A_SLEEP' DESTINATION dest
STARTING NEW TASK taskname
PERFORMING return_form ON END OF TASK
EXPORTING
seconds = sec
EXCEPTIONS
OTHERS = 1.
IF sy-subrc = 0.
num_of_rfc_calls = num_of_rfc_calls + 1.
IF prog_ind = abap_true.
PERFORM send_msg.
ENDIF.
ENDIF.

" Take end time of this loop and summarize
GET RUN TIME FIELD t2.
time_sum = time_sum + t2 - t1.

ENDDO.

dispatch->end_dispatching( ).

GET RUN TIME FIELD t1.

GET RUN TIME FIELD t2.
time_sum = time_sum + t2 - t1.

pending_response = num_of_rfc_calls - results_count.
IF pending_response = 0.
WRITE: / |Received results of all aRFC calls ({ results_count }, each lasting { sec } seconds), runtime was { time_sum / 1000 } msec|.
ELSE.
WRITE: / |Still results of aRFC calls missing (pending: { pending_response }), runtime was { time_sum / 1000 } msec|.
ENDIF.

" Callback for received results
FORM return_form USING taskname.
RECEIVE RESULTS FROM FUNCTION 'DO_A_SLEEP'
EXCEPTIONS OTHERS = 0.

results_count = results_count + 1.

TRY.
dispatch->received_result( conv string( taskname ) ).
CATCH cx_ssi_bad_parameter.
WRITE: / 'Error: bad parameter'.
RETURN.
CATCH cx_ssi_no_auth.
WRITE: / 'Error: missing authority for dispatch->received_result( )'.
RETURN.
ENDTRY.

ENDFORM.


" Make progress visible
FORM send_msg.
DATA: text(80).

text = |Call: { sy-index } (Pending: { num_of_rfc_calls - results_count }]|.
CALL FUNCTION 'SAPGUI_PROGRESS_INDICATOR'
EXPORTING
text = text.
ENDFORM.

*" The following remote function modul DO_A_SLEEP is needed to run this program:
*
*FUNCTION do_a_sleep.
*"----------------------------------------------------------------------
*"*"Lokale Schnittstelle:
*" IMPORTING
*" VALUE(SEC) TYPE I
*"----------------------------------------------------------------------
*
* WAIT UP TO sec SECONDS.
*
*ENDFUNCTION.

Hinweise

Weiterführende Informationen






Fill RESBD Structure from EBP Component Structure   Addresses (Business Address Services)  
Diese Dokumentation steht unter dem Copyright der SAP AG.

Length: 34946 Date: 20240328 Time: 151237     sap01-206 ( 443 ms )