Sie sind nun wieder eingeladen, die Diskussion spezieller technischer Probleme mit zu verfolgen. Bitte schicken Sie Fragen, Anregungen oder Antworten zu den vorgestellten Themen – ebenso wie Ihre Kritik – an unsere e-Mail-Adressen: dieter.bender@MidrangeMagazin.de oder Redaktion@MidrangeMagazin.de In diesem Beitrag zum Technik-Forum möchte ich einmal ausnahmsweise drei Fragen, die auf den ersten Blick nichts miteinander zu tun haben, in einem Beitrag gesammelt behandeln, da ihre Lösung alle auf der identischen Technik beruhen und mit dem gleichen kleinen Hilfsmittel gelöst werden können: einem Programm für Durchbruchnachrichten. Doch zunächst einmal die Fragestellungen, die in dieser oder ähnlicher Form auch schon in Newsgroups aufgetaucht sind.

Frage:

Wir haben manchmal in unserer Tagesendverarbeitung im Batch die Situation, dass der Job auf einer Meldung sitzt und es wäre für uns hilfreich an die Daten in der QTEMP dieses Jobs heran zu kommen. Gibt es dazu eine Möglichkeit?

Frage:

Bei uns läuft eine Auswertung im interaktiven Job und wir würden diese gerne in den Batch submitten. Ist es möglich, die aus diesem Job erstellten Ergebnisse direkt nach Fertigstellung am Bildschirm des anfordernden Benutzers automatisch anzuzeigen?

Frage:

Wir haben eine fertig gekaufte Anwendung, die ihre Berechtigungseinträge im LDA ablegt und haben den Verdacht, dass diese Steuerung zu fehlerhaften Abläufen führt. Gibt es eine Möglichkeit zur Laufzeit des Programms auf diese Informationen zuzugreifen?

Allen drei Fragen ist gemeinsam, dass man mit den klassischen Mitteln nicht sehr viel weiter kommt. Die Schwierigkeit besteht darin, an den inneren Status eines laufenden Programms heranzukommen, das gerade am Laufen ist oder in einem anderen Job aktiv ist. Würde man sich innerhalb des Programms befinden, wäre die Aufgabenstellung trivial und mit den einfachsten Mitteln lösbar. Alle Ansätze – auch mit STRSRVJOB – führen hier nicht zum Ziel. Es ist scheinbar nicht möglich, den Ablauf eines Programms zu unterbrechen und eine andere Aktivität dazwischen zu schieben. Doch dieser Schein trügt, man kann einen Job jederzeit und leicht unterbrechen, zum Beispiel durch Senden einer Durchbruchnachricht – und hier liegt auch der Lösungsansatz. Wenn man jetzt noch zusätzlich ein Programm zur Behandlung von Durchbruchnachrichten ins Spiel bringt, hat man die auf den ersten Blick unlösbar scheinenden Anforderungen bereits so gut wie gelöst.

Der OS/400-Befehl CHGMSGQ erlaubt es unter dem Parameter DLVRY eine Nachrichtenwarteschlange in den Durchbruchmodus zu stellen; hierfür wird dieser Parameter auf den Wert *BREAK gesetzt. Unter dem Parameter PGM kann man für eine Nachrichtenwarteschlange ein Programm eintragen, dass dann beim Eintreffen einer Nachricht automatisch aufgerufen wird. Diese Einstellung bleibt so lange, wie diese Nachrichtenwarteschlange diesem Job zugeordnet ist, der dazu eine Sperre auf das entsprechende *MSGQ-Objekt einträgt.

Nachrichtenwarteschl. ändern (CHGMSGQ)

Auswahl eingeben und Eingabetaste drücken.

Nachrichtenwarteschlange . . . . MSGQ
Bibliothek . . . . . . . . . . *LIBL
Zustellung . . . . . . . . . . . DLVRY *SAME
Bewertungscodefilter . . . . . . SEV *SAME
Text ‚Beschreibung‘ . . . . . . TEXT *SAME

Zusätzliche Parameter

Programm für Durchbruchnachr. . PGM *SAME
Bibliothek . . . . . . . . . .
Alte Nachrichten zurücksetzen . RESET *NO
Auf Zusatzspeicher sichern . . . FORCE *SAME
Alerts zulassen . . . . . . . . ALWALR *SAME
Zeichensatz-ID . . . . . . . . . CCSID *SAME

Ende
F3=Verlassen F4=Bedienerf. F5=Aktualisieren F12=Abbrechen
F13=Verwendung der Anzeige F24=Weitere Tasten

Dieser Mechanismus bleibt so lange aktiv, bis dieser Job endet oder sich ein anderer Job die Nachrichtenwarteschlange zuordnet. Immer wenn nun eine Nachricht an diese Warteschlange gesendet wird, wird der Job unterbrochen, der sich die Warteschlange zugeordnet hat. Das registrierte Programm wird aufgerufen. Dieses Programm bekommt dann den Namen der Warteschlange, die entsprechende Bibliothek und die Message ID übergeben. Am wichtigsten zur Lösung unserer Fragestellungen ist zunächst, dass das Durchbruchprogramm in dem Job läuft, der sich die Warteschlange mit dem CHGMSGQ zugeordnet hat.

An dieser Stelle wird auch deutlich, dass in allen drei Problemstellungen eine vorbereitende Aktivität erforderlich ist, um den laufenden Prozess durch einen Programmaufruf unterbrechbar zu machen. Das nächste Problem, das jetzt sichtbar wird, besteht darin, dass man keine eigenen Parameter übergeben kann und die Standardparameter auch nicht sehr verlockend aussehen. Es muss also ein Weg gefunden werden, mit dem Durchbruchprogramm zu kommunizieren. Das Naheliegendste in dieser Situation ist, den Nachrichtenmechanismus selber zu nutzen. Man sendet einfach im Nachrichtentext der unterbrechenden Nachricht die Anforderung an das Durchbruchprogramm, welches sich dann diese mit RCVMSG holt. Hört sich alles sehr kompliziert an, ist aber einfach und schnell programmiert.

Ich habe das kleine Beispiel in CL implementiert und zwei Funktionalitäten in einem Programm abgebildet. Wird es mit „INIT“ als dritten Parameter aufgerufen, wird der Mechanismus eingerichtet und das selbe Programm dient anschließend gleich als Durchbruchprogramm.

/*********************************************************************/

/* */
/* Break Message Handler für Test- und Debugzwecke */
/* Aufruf über Command M */
/* Copyright Dieter Bender DV Beratung */
/* db@bender-dv.de */
/* */
/*********************************************************************/
PGM +
PARM( +
&MSGQ /* Message Queue */+
&MSGQLIB /* Message Queue Library */+
&MSGID /* Message ID */+
)

DCL &MSGQ *CHAR 10
DCL &MSGQLIB *CHAR 10
DCL &MSGID *CHAR 4
DCL &MSG *CHAR 75
DCL &CMDLEN *DEC (15 5) 75

IF ( &MSGID = ‚INIT‘) +
DO
CHKOBJ &MSGQLIB/&MSGQ *MSGQ
MONMSG CPF9801 EXEC( +
DO)
CRTMSGQ &MSGQLIB/&MSGQ
ENDDO
CHGMSGQ &MSGQ *BREAK M 0
ENDDO
ELSE +
DO
RCVMSG +
MSGQ(&MSGQLIB/&MSGQ) +
MSGKEY(&MSGID) +
MSG(&MSG)
IF (&MSG = ‚M‘ *OR &MSG = ‚m‘) +
CALL QUSCMDLN
ELSE +
DO
CALL QCMDEXC (&MSG &CMDLEN)
MONMSG CPF0000
ENDDO
ENDDO
ENDPGM

Beim Aufruf mit „INIT“ als dritten Parameter wird gegebenenfalls die Warteschlange angelegt, mit CHGMSGQ in den Durchbruchmodus gesetzt und das Programm selber als Durchbruchprogramm registriert.

Als Message Handler wird im dritten Parameter die Nachrichten-ID übergeben, die nicht mit dem speziellen INIT-Aufruf verwechselt werden kann. Im Programm wird dann im Else-Zweig zunächst mit RCVMSG der Nachrichtentext der gesendeten Nachricht geholt. Wurde der Buchstabe M als Nachricht gesendet, wird das API QUSCMDLN aufgerufen, das in einem interaktiven Job ein kleines Befehlseingabe-Fenster anzeigt. Wurde eine andere Nachricht gesendet, wird diese direkt an den Batch Interpreter QCMDEXC übergeben, der versucht, den Text als Programmaufruf auszuführen.

Am einfachsten sehen wir uns nunmehr an, wie man mit diesem kleinen Programm die drei eingangs gestellten Probleme konkret löst. Im Falle des Batch Jobs muss man zunächst einmal sicherstellen, dass die verwendete Nachrichtenwarteschlange einen systemweit eindeutigen, dem Job zugeordneten Namen bekommt. Dafür ist es naheliegend, diesen aus der Jobnummer zu generieren. Das Batch-Programm muss nun also dahingehend geändert werden, dass zuerst ein solcher Name generiert wird. Im folgenden Ausschnitt wird dazu die Jobnummer an den Buchstaben M angehängt. Dann erfolgt der initialisierende Aufruf des Programms M dieses Artikels. Danach geht es mit der bisherigen Batch-Verarbeitung nahtlos weiter.

/* Snip */

DCL &NBR *CHAR (6)
DCL &MSGQ *CHAR (10) VALUE(‚M ‚)
RTVJOBA NBR(&NBR)
CHGVAR %SST(&MSGQ 2 6) &NBR
CALL M (&MSGQ ‚QGPL‘ ‚INIT‘)
/* Snip */

Wenn man sich nun für interne Informationen des Jobs interessiert, lässt man sich diese geben, indem man eine entsprechende Anforderung an die Nachrichtenwarteschlange sendet. Dazu ermittelt man mit WRKACTJOB oder ähnlichen Befehlen die Jobnummer und kennt damit den Namen der Warteschlange. Für die Übermittlung der QTEMP des Batch Jobs braucht man also nur eine Nachricht SAVOBJ OBJ(*ALL) LIB(QTEMP) DEV(*SAVF) SAVF(MYSAVF) an die Nachrichtenwarteschlange zu senden. Der Batch Job unterbricht dann seine Tätigkeit (oder Untätigkeit) und sichert seine QTEMP in die Sicherungsdatei MYSAVF.

Für den zweiten Fall der Eingangsfragen muss der interaktive Job vor dem SBMJOB der Auswertung eine Warteschlange nach demselben Muster wie im ersten Beispiel erstellen und das Programm M mit „INIT“ als dritten Parameter entsprechend aufrufen. Bei dem SBMJOB muss dann der Namen der Warteschlange mit in die Parameterliste eingebaut werden. Der Batch Job stellt dann seine Auswertung in den Spool, der zum Schluss mit einem gesendeten Command DSPSPLF vom interaktiven Job angezeigt wird.

Im dritten Beispiel kann man die Nachrichtenwarteschlange auch in der eigenen QTEMP anlegen. Dann kann man sich aber nur selber die entsprechende Nachricht senden, da andere nicht an die Nachrichtenwarteschlange in der QTEMP herankommen. Das Ansehen des LDA kann nun jederzeit erfolgen, indem man den Systemabruf betätigt und sich mit der Auswahl 5 die Nachricht „dspdtaara *lda“ an die Nachrichtenwarteschlange M sendet.

Dieser vorgestellte Mechanismus ist dermaßen mächtig, dass aus Sicherheitsgründen extra eine Besonderheit für Durchbruchprogramme in OS/400 eingefügt worden ist: Diese Programme verwenden nicht die Berechtigungsübernahme etwaiger anderer Programme im Callstack zur Ausführungszeit. Mit den drei vorgestellten Anwendungen ist auch nur ein kleiner Einblick in die Mächtigkeit von Durchbruchprogrammen gegeben worden. Ich verwende diesen Mechanismus zum Beispiel auch beim Testen von Programmen, um den Debugger erst dann zu starten, wenn es mir passt, oder in SQL Sitzungen, um ohne CALL QCMDEXC mal eben schnell einen OS/400-Befehl loszuwerden.
Zur Erhöhung des Bedienkomforts habe ich mir noch einen kleinen Befehl M geschrieben, der mir die Parameter-Übergabe erleichtert.

/*********************************************************************/

/* */
/* Break Message Handler für Test- und Debugzwecke */
/* ruft Programm M auf */
/* Copyright Dieter Bender DV Beratung */
/* dieter.bender@t-online.de */
/* */
/*********************************************************************/
CMD ‚System Request Command‘

PARM MSGQ *CHAR 10 DFT(‚M ‚)
PARM MSGQLIB *CHAR 10 DFT(‚QTEMP ‚)
PARM MSGID *CHAR 4 DFT(‚INIT‘)

Für meine Testsitzungen oder die Unterbrechung des interaktiven SQL, brauche ich jetzt vorbereitend nur M ohne jeden Parameter abzusenden. Im interaktiven Job kann ich jetzt auf die Unterbrechungslinie der Systemanfrage direkt „5 m m“ eintippen und bekomme ein Command-Fenster.

Den Autor Dieter Bender erreichen Sie unter dieter.bender@midrangemagazin.de