| Easily Identify What Message a Job Is Waiting On |
|
|
|
| Programming - APIs | |
| Written by Bruce Vining | |
| Wednesday, 01 October 2008 | |
|
With the QUSRJOBI and QMHRCVM APIs and MONBCH2, you know exactly what the message is and how to reply.
In a previous article, "Keep Those Batch Jobs Running (Or How to Enjoy Your Off Time)," we saw how to detect when a batch job was waiting for a message to be replied to and how to inform a user of that situation. In that introductory article, we simply sent a generic message indicating that job X was waiting for a response to a message. In this article, we'll enhance the MONBCH program and inform the operator of which exact message the job is waiting on. Note that this enhancement to MONBCH will use a V6R1 feature that is not available on previous releases.
The new program, MONBCH2, is shown below with the functional changes highlighted.
h dftactgrp(*no)
dMonBch2 pr extpgm('MONBCH2') dMonBch2 pi
dSetup pr * dDelay pr dProcessMsgW pr
dListJob pr extpgm('QSYS/QUSLJOB') d SpcName 20 const d Format 8 const d JobName 26 const d Status 10 const d QUSEC likeds(QUSEC) options(*nopass) d JobType 1 const options(*nopass) d NbrKeyFlds 10i 0 const options(*nopass) d KeyFlds likeds(KeyFlds) options(*nopass) d ContinHdl 48 const options(*nopass)
dSndDtaQMsg pr extpgm('QSYS/QSNDDTAQ') d DtaQName 10 const d DtaQLib 10 const d DataLen 5 0 const d Data 65535 const options(*varsize) d KeyLen 3 0 const options(*nopass) d KeyValue 65535 const options(*varsize :*nopass) d Asynch 10 const options(*nopass) d JrnEntry 10 const options(*nopass)
/copy qsysinc/qrpglesrc,qusgen /copy qsysinc/qrpglesrc,qusljob /copy qsysinc/qrpglesrc,qusec
dGenHdr ds likeds(QUSH0100) d based(GenHdrPtr)
dLstEntry ds likeds(QUSL020001) d based(LstPtr)
dAttrEntry ds likeds(QUSLKF) d based(AttrPtr)
dKeyFlds ds d KeyValues 10i 0 dim(25)
dUsrSpcName ds d Name 10 inz('MONBCHLJOB') d Library 10 inz('QTEMP')
dJobsToList ds d JobName 10 inz('*ALL') d JobUser 10 inz('*ALL') d JobNbr 6 inz('*ALL')
dDtaQMsg ds d DtaQJobName 10 d 1 d DtaQJobUsr 10 d 1 d DtaQJobNbr 6 d 1 inz(':') d DtaQMsgID 7 d 1 d DtaQMsgTxt 256
dPSDS sds 429 qualified d Line 21 28 d MsgID 40 46 d ExcpDta 91 170 d JobName 244 253 d JobUser 254 263 d JobNbr 264 269
dLstCount s 10i 0 dAttrCount s 10i 0 dAttrValue s 100 based(AtrValPtr) dNbrKeyFlds s 10i 0 dContinue s n inz(*on) dMonBchCtl s 1 dtaara('VININGTST/MONBCHCTL')
dDtaQName c 'MESSAGES' dDtaQLib c 'VININGTST'
/free
monitor;
GenHdrPtr = Setup();
dow Continue; ListJob( UsrSpcName :'JOBL0200' :JobsToList :'*ACTIVE' :QUSEC :'B' :NbrKeyFlds :KeyFlds :*blanks);
// Check to see if the list is complete if (GenHdr.QUSIS = 'C') or (GenHdr.QUSIS = 'P');
// Get to the first list entry and process the list LstPtr = GenHdrPtr + GenHdr.QUSOLD;
for LstCount = 1 to GenHdr.QUSNBRLE; // Get first attribute and process all returned if LstEntry.QUSJIS = ' '; AttrPtr = LstPtr + %size(QUSL020001); for AttrCount = 1 to LstEntry.QUSNBRFR; AtrValPtr = AttrPtr + %size(QUSLKF); select; when AttrEntry.QUSKF = 0101; if %subst(AttrValue :1 :AttrEntry.QUSLD00) = 'MSGW'; ProcessMsgW(); endif; endsl; AttrPtr += AttrEntry.QUSLFIR; endfor; endif; LstPtr += GenHdr.QUSSEE; endfor; Delay(); else; DtaQJobName = PSDS.JobName; DtaQJobUsr = PSDS.JobUser; DtaQJobNbr = PSDS.JobNbr; DtaQMsgID = *blanks; DtaQMsgTxt = 'MONBCH is unable to access batch job information.'; SndDtaQMsg( DtaQName :DtaQLib :%len(%trimr(DtaQMsg)):DtaQMsg); *inlr = *on; return; endif; enddo;
*inlr = *on; return;
on-error; DtaQJobName = PSDS.JobName; DtaQJobUsr = PSDS.JobUser; DtaQJobNbr = PSDS.JobNbr; DtaQMsgID = *blanks; DtaQMsgTxt = 'Job failed at statement ' + PSDS.Line + ' with message ' + PSDS.MsgID + ': ' + PSDS.ExcpDta; SndDtaQMsg( DtaQName :DtaQLib :%len(%trimr(DtaQMsg)) :DtaQMsg);
return;
endmon;
/end-free
*****************************************************************
pProcessMsgW b
dProcessMsgW pr dProcessMsgW pi
dRJobI pr extpgm('QSYS/QUSRJOBI') d RcvVar 1 options(*varsize) d LenRcvVar 10i 0 const d Format 8 const d JobID 26 const d IntJobID 16 const d QUSEC likeds(QUSEC) options(*nopass) d ResetStats 1 const options(*nopass)
dRcvMsg pr extpgm('QSYS/QMHRCVM') d RcvVar 1 options(*varsize) d LenRcvVar 10i 0 const d Format 8 const d QualMsgQ 20 const d MsgType 10 const d MsgKey 4 const d WaitTime 10i 0 const d MsgAction 10 const d QUSEC likeds(QUSEC) d CCSID 10i 0 const options(*nopass) d AlwDftRspRjct 10 const options(*nopass)
/copy qsysinc/qrpglesrc,qmhrcvm /copy qsysinc/qrpglesrc,qusrjobi
dMHRcvVar ds likeds(QMHM0200) d based(MHRcvVarPtr)
dMsgTxt s 32767 based(MsgTxtPtr)
/free
monitor; RJobI ( QUSI020000 :%size(QUSI020000) :'JOBI0200' :'*INT' :LstEntry.QUSIJI00 :QUSEC); if ((QUSMR01 = '1') and (QUSMK <> *loval)); DtaQJobName = QUSJN03; DtaQJobUsr = QUSUN03; DtaQJobNbr = QUSJNBR03;
RcvMsg( QMHM0200 :8 :'RCVM0200' :(QUSMQ + QUSMQLIB) :'*INQ' :QUSMK :0 :'*SAME' :QUSEC); MHRcvVarPtr = %alloc(QMHBAVL01); RcvMsg( MHRcvVar :QMHBAVL01 :'RCVM0200' :(QUSMQ + QUSMQLIB) :'*INQ' :QUSMK :0 :'*SAME' :QUSEC); DtaQMsgID = MHRcvVar.QMHMI02; MsgTxtPtr = (%addr(MHRcvVar) +%size(QMHM0200) +MHRcvVar.QMHLDRTN); if MHRcvVar.QMHLMRTN <= %size(DtaQMsgTxt); DtaQMsgTxt = *blanks; DtaQMsgTxt = %subst(MsgTxt :1 :MHRcvVar.QMHLMRTN); else; DtaQMsgTxt = %subst(MsgTxt :1 :%size(DtaQMsgTxt)); endif; SndDtaQMsg( DtaQName :DtaQLib :%len(%trimr(DtaQMsg)) :DtaQMsg); dealloc MHRcvVarPtr;   | |


