ibmi-brunch-learn

Announcement

Collapse
No announcement yet.

CLP queuing ?

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • CLP queuing ?

    Hello,

    Recently i created 3 CLPs that works differently with each other :

    CLP 1: Turning off a MIMIX Data Group. Clearing a Target Library, Restoring Target library using *savf from Source

    CLP 2: Starting a Data Group using specific Sequence and Receiver

    CLP 3: Running an Audit Rule in the said data group

    I don't mind running all three seperately but is it possible to make it sequential ?
    Like, after all the stuff in CLP 1 gets done it continues with CLP 2 ?

    *Same thing on the CLP 1 is how i make the RSTLIB didn't run immediately without confirming that the CLRLIB already cleared the library until theres nothing left

    Thanks

  • #2
    If you are running each of these one after the other from the command line, then a good method would be to create a master CL program the calls each of them in the order you want them executed in. The master CL program will wait for CLP1 to finish before executing CLP2, and so on. If you enhance CLP1, CLP2, and CLP3 to pass back a parameter (perhaps indicating that it's ok to run the next CLP, or that an error occurred so don't run the next CLP), then the Master CL program could monitor the value of the parameter and react accordingly.

    Comment


    • Lemon Grande
      Lemon Grande commented
      Editing a comment
      So i need to make a Master CL that contains the 3 CLPs ? 
      which means if i were to put for example a SNDUSRMSG in between each CLP with an option to continue or end it will wait for each CLP to run ? (answering an MSGW so that it could proceed ?)

  • #3
    You can make the Master CL as simple or as complex as you need it to be. You can add in error checking and other stuff.

    (I apologize if the formatting of the following examples is a bit off)

    Simple example (run all 3 one after the other):

    Pgm

    Call Pgm(CLP1)

    Call Pgm(CLP2)

    Call Pgm(CLP3)

    EndPgm



    Slightly more complex example (only run the next program if you confirm that you want the next program to run):

    1. Create a display file that contains 3 record formats. These will be used to confirm or end running the programs
    2. In the Master CL, wait for the user to respond to the confirmation prompt before executing the CLP's

    Very Simple (but usable) Display File:

    A DSPSIZ(24 80 *DS3)
    A INDARA
    A CF03(03 'Exit')
    A CF07(07 'Run')
    A R CNF01
    A 7 2'Ok to Run CLP1?'
    A 9 4'F3=Exit F7=Run CLP1'
    A R CNF02
    A 7 2'Ok to Run CLP2?'
    A 9 4'F3=Exit F7=Run CLP2'
    A R CNF03
    A 7 2'Ok to Run CLP3?'
    A 9 4'F3=Exit F7=Run CLP3'



    Master CL using the Display File to confirm running each CLP
    Pgm

    DclF File(CONFDS)

    /* -------------------------------------------- */
    /* Confirm OK to run CLP1 */
    /* -------------------------------------------- */

    DoUntil Cond(&In03 *Eq '1' *Or &In07 *Eq '1')

    SndRcvf Rcdfmt(CNF01)

    /* F3=Exit - Do not continue */
    If Cond(&In03 *Eq '1') Then(GoTo CmdLbl(End))

    Enddo

    /* Run CLP1 */
    Call Pgm(CLP1)

    /* -------------------------------------------- */
    /* Confirm OK to run CLP2 */
    /* -------------------------------------------- */

    DoUntil Cond(&In03 *Eq '1' *Or &In07 *Eq '1')

    SndRcvf Rcdfmt(CNF02)

    /* F3=Exit - Do not continue */
    If Cond(&In03 *Eq '1') Then(GoTo CmdLbl(End))

    Enddo

    /* Run CLP2 */
    Call Pgm(CLP2)

    /* -------------------------------------------- */
    /* Confirm OK to run CLP3 */
    /* -------------------------------------------- */

    DoUntil Cond(&In03 *Eq '1' *Or &In07 *Eq '1')

    SndRcvf Rcdfmt(CNF03)

    /* F3=Exit - Do not continue */
    If Cond(&In03 *Eq '1') Then(GoTo CmdLbl(End))

    Enddo

    /* Run CLP3 */
    Call Pgm(CLP3)

    End:
    EndPgm

    Comment


    • #4
      This is the current CL that i go with, I think it's more or less the same with what you recommend ? (i'm still new to this so i'm not sure myself, really appreciate it though)


      PGM
      DCL VAR(&RPY) TYPE(*CHAR) LEN(1)
      DCL VAR(&RPY2) TYPE(*CHAR) LEN(1)
      DCL VAR(&RPY3) TYPE(*CHAR) LEN(1)
      DCL VAR(&RPY4) TYPE(*CHAR) LEN(1)
      MSG1: SBMJOB CMD(CALL PGM(ABC/CLP1)) +
      JOB(CLP1)
      MSG2: SNDUSRMSG MSG('Make sure bla bla): G --- CONTINUE +
      CLRLIB aKEXTPRD C --- CANCEL') VALUES(G C) +
      MSGRPY(&RPY)
      IF COND(&RPY *EQ 'G') THEN(CHGVAR VAR(&RPY) +
      VALUE('G'))
      IF COND(&RPY = 'G') THEN(DO)
      MSG3: SBMJOB CMD(CALL PGM(ABC/CLP2)) +
      JOB(CLP2)
      ENDDO
      IF COND(&RPY *EQ 'C') THEN(CHGVAR VAR(&RPY) +
      VALUE('C'))
      IF COND(&RPY = 'C') THEN(GOTO CMDLBL(END))
      etc
      etc (same format different call commands)

      END: ENDPGM


      I haven't tried it yet but i need to have at least 1 running job that runs in the batch to show the message contained in the jobs. Which mans following what you recommend (i think) it will be like this

      Pgm

      sbmjob dspsysval job(abc)
      Call Pgm(CLP1)

      Call Pgm(CLP2)

      Call Pgm(CLP3)

      EndPgm


      now lets say in CLP1 i have a CLRLIB command which clears library and i put it in CLP1 without the SBMJOB
      and in CLP2 i have a RSTLIB that restore library and it uses the SBMJOB.
      if i were to see the joblog of the SBMJOB that exist outside of the CLP 1 2 3 queue will it contain the history process of the CLP1 and CLP2 ?

      or will CLP2 still submit jobs outside of the abc SBMJOB ? Does the first SBMJOB abc that's in the Master CL can process all the CLP1,2,3 as 1 JOB if i were to not run the jobs in the CLP1,2,3 in an SBMJOB format like :

      Pgm

      sbmjob dspsysval job(abc)
      Call Pgm(CLP1) ---> CLRLIB WASD

      Call Pgm(CLP2) ---> RSTLIB DAWS

      Call Pgm(CLP3) ---> DSPLIB DAWS

      EndPgm



      ^^^
      Now if i do it with this format, will the first SBMJOB contains the process of all the CL below it(if i were to not use SBMJOB in each CLP), also will the SNDUSRMSG that i use be able to put the first SBMJOB in MSGW state every time it want to go over each CLP process ?

      Thanks,

      Comment


      • #5
        Ah, you are submitting jobs, not running them interactively. Each submitted job becomes a separate job in its own right and will have its own joblog (or none at all, depending on how your system is configured; many times you do not want a joblog created if the submitted job ends normally). The joblog for the main CL will only contain its own message, but none for any of the submitted jobs.

        Based on your response, it sounds like you need a way for the first submitted job to let you know that it's successfully completed (accomplished its task and ended normally) and the second job can now be submitted. and so on for the third job. Traditionally, the simplest was to communicate between interactive and batch programs is by setting a flag in either a physical file (or table) or a data area. Since this is a CL program, a data area would be a good choice.

        CL has a command called DLYJOB which will pause the job for however many seconds you'd like it paused for. Using a DLYJOB command in conjunction with a RTVDTAARA command within a DOUNTIL loop will take a lot of the guess work out of when to submit the next job. Just make sure that your main CL can escape the loop should the job that it's monitoring fail to set the data area.

        An example of the logic would be (you can incorporate your messages into this method, too):

        - change data area to indicate that CLP1 is being submitted
        - submit CLP1 (contains a change data area command to indicate that it has completed)
        - within a DOUNTIL loop (loop until data area value indicates that it's ok to submit the next CLP or stop running)
        -- retrieve the data area
        -- if CLP1 is still running, then delay the job for X seconds
        -- loop
        -
        - change data area to indicate that CLP2 is being submitted
        - submit CLP2 (contains a change data area command to indicate that it has completed)
        - within a DOUNTIL loop (loop until data area value indicates that it's ok to submit the next CLP or stop running)
        -- retrieve the data area
        -- if CLP2 is still running, then delay the job for X seconds
        -- loop
        -
        - change data area to indicate that CLP3 is being submitted
        - submit CLP3 (contains a change data area command to indicate that it has completed)
        - within a DOUNTIL loop (loop until data area value indicates that CLP3 has completed or stop running)
        -- retrieve the data area
        -- if CLP3 is still running, then delay the job for X seconds
        -- loop
        -
        - do some other stuff (if applicable)
        -
        - end

        Comment


        • #6
          I'm wondering why you are submitting CLP1, CLP2 and CLP3 as separate jobs? This seems to be complicating something that seems very simple and I wonder if you are a little confused as to what SBMJOB does.

          Simply put, when you submit a job (SBMJOB), you start a new job. Once the new job is submitted to a JOBQ, control passes back to the calling program. That calling program could be your command line where you typed SBMJOB xxxx or a batch job etc. The important thing to note though, is that SBMJOB starts a new job that runs independently of the job that called it. Control passes back to the program that issued the SBMJOB command when the new job is submitted, not when the new job ends.

          Another way of running a program is to simply call it (using e.g. CALL). When you call a program, the job calling the program runs the instructions so control doesn't return until it has finished. If you call a program from your command line for instance, you will need to wait for the program to end before you can use the command line again.

          For what you are doing, calling the programs seems the sensible approach as the next program instruction won't get executed until the previous one has finished. What you suggest in your changes seems more sensible but...

          You start with "sbmjob dspsysval job(abc)". I don't know what this is supposed to be doing. DSPSYSVAL is used to display a global system value but needs a system value parameter. JOB is not a parameter for it. Maybe JOB is the SBMJOB parameter but I don't know what system value you are trying to print nor for what purpose. What are you trying to achieve here and why are you thinking of submitting it as a new batch job?

          You mentioned CLP1 does a CLRLIB. Is the CLRLIB submitted as a job in CLP1 or does CLP1 do the CLRLIB command? If you submit a job, again you have the issues that it will run independently and the program will continue whether the clear has finished or not.
          You mention that CLP2 will do the RSTLIB using SBMJOB. As per the previous note, why do you submit the restore as a job? Again, this approach means control passes back to CLP2 before the restore has finished. You won't know when the restore finishes without some uneccesary coding.
          You don't make many comments about CLP3 except it's doing a DSPLIB.

          Comment


          • #7
            Originally posted by Herb... View Post
            Ah, you are submitting jobs, not running them interactively. Each submitted job becomes a separate job in its own right and will have its own joblog (or none at all, depending on how your system is configured; many times you do not want a joblog created if the submitted job ends normally). The joblog for the main CL will only contain its own message, but none for any of the submitted jobs.

            Based on your response, it sounds like you need a way for the first submitted job to let you know that it's successfully completed (accomplished its task and ended normally) and the second job can now be submitted. and so on for the third job. Traditionally, the simplest was to communicate between interactive and batch programs is by setting a flag in either a physical file (or table) or a data area. Since this is a CL program, a data area would be a good choice.

            CL has a command called DLYJOB which will pause the job for however many seconds you'd like it paused for. Using a DLYJOB command in conjunction with a RTVDTAARA command within a DOUNTIL loop will take a lot of the guess work out of when to submit the next job. Just make sure that your main CL can escape the loop should the job that it's monitoring fail to set the data area.

            An example of the logic would be (you can incorporate your messages into this method, too):

            - change data area to indicate that CLP1 is being submitted
            - submit CLP1 (contains a change data area command to indicate that it has completed)
            - within a DOUNTIL loop (loop until data area value indicates that it's ok to submit the next CLP or stop running)
            -- retrieve the data area
            -- if CLP1 is still running, then delay the job for X seconds
            -- loop
            -
            - change data area to indicate that CLP2 is being submitted
            - submit CLP2 (contains a change data area command to indicate that it has completed)
            - within a DOUNTIL loop (loop until data area value indicates that it's ok to submit the next CLP or stop running)
            -- retrieve the data area
            -- if CLP2 is still running, then delay the job for X seconds
            -- loop
            -
            - change data area to indicate that CLP3 is being submitted
            - submit CLP3 (contains a change data area command to indicate that it has completed)
            - within a DOUNTIL loop (loop until data area value indicates that CLP3 has completed or stop running)
            -- retrieve the data area
            -- if CLP3 is still running, then delay the job for X seconds
            -- loop
            -
            - do some other stuff (if applicable)
            -
            - end
            What i'm aiming here is so that i have one submitted job that contains the process of all 3 CLPs, with all three of them running after each of them finished processing one by one.
            But for monitoring purpose and i have no knowledge of confirming of each program have finished processing successfully. Hence i tried adding a SNDUSRMSG between each CLP as a way to confirm that one CLP already finished (checking the spooled file manually to confirm and then answering the SNDUSRMSG so that the job can continue to the next CLP steps).
            Thank you for the information about the data area, i might need to read about it first before incorporating about it in the CL.

            Comment


            • #8
              Originally posted by john.sev99 View Post
              I'm wondering why you are submitting CLP1, CLP2 and CLP3 as separate jobs? This seems to be complicating something that seems very simple and I wonder if you are a little confused as to what SBMJOB does.

              Simply put, when you submit a job (SBMJOB), you start a new job. Once the new job is submitted to a JOBQ, control passes back to the calling program. That calling program could be your command line where you typed SBMJOB xxxx or a batch job etc. The important thing to note though, is that SBMJOB starts a new job that runs independently of the job that called it. Control passes back to the program that issued the SBMJOB command when the new job is submitted, not when the new job ends.

              Another way of running a program is to simply call it (using e.g. CALL). When you call a program, the job calling the program runs the instructions so control doesn't return until it has finished. If you call a program from your command line for instance, you will need to wait for the program to end before you can use the command line again.

              For what you are doing, calling the programs seems the sensible approach as the next program instruction won't get executed until the previous one has finished. What you suggest in your changes seems more sensible but...

              You start with "sbmjob dspsysval job(abc)". I don't know what this is supposed to be doing. DSPSYSVAL is used to display a global system value but needs a system value parameter. JOB is not a parameter for it. Maybe JOB is the SBMJOB parameter but I don't know what system value you are trying to print nor for what purpose. What are you trying to achieve here and why are you thinking of submitting it as a new batch job?

              You mentioned CLP1 does a CLRLIB. Is the CLRLIB submitted as a job in CLP1 or does CLP1 do the CLRLIB command? If you submit a job, again you have the issues that it will run independently and the program will continue whether the clear has finished or not.
              You mention that CLP2 will do the RSTLIB using SBMJOB. As per the previous note, why do you submit the restore as a job? Again, this approach means control passes back to CLP2 before the restore has finished. You won't know when the restore finishes without some uneccesary coding.
              You don't make many comments about CLP3 except it's doing a DSPLIB.
              The DSPSYSVAL thing is just a random example, and i might be wrong in putting the paramater

              Pgm

              DCL VAR(&RPY) TYPE(*CHAR) LEN(1)

              sbmjob ABC <---- can be anything just an example
              Call Pgm(CLP1)
              Sndusrmsg
              Call Pgm(CLP2)
              sndusrmsg
              Call Pgm(CLP3)


              What i'm trying to aim here is that this one Master CL contains all 3 CLPs and all three of them can run after one CLP finished after another with a SNDUSRMSG in between each one of them so that i can manually check whether it finished successfully or not (i'm using this method because at the moment i've yet to know a way to verify it finished successfully or not using data area). At the moment what contained in each is in each CLP is in an SBMJOB format.
              Pgm


              sbmjob mimix/enddg


              ^i'm using a replication MIMIX and when i turned off a data group in there all the job in the MIMIX subsystem related to the data group didn't go off immediately it takes time to end them (MIMIX does this using their ENDDG command), hence i put a SNDUSRMSG after this job has been submitted to manually confirm it has been fully deactivated.

              SNDUSRMSG <---- manually confirming the data group has been turned off completely

              CLP1 :
              sbmjob clrlib lib2


              I am still new to this, so the reason i put this in an SBMJOB is because i'm afraid the CLP2 will do the RSTLIB to LIB2 before the CLP1 finished clearing the LIB2

              SNDUSRMSG
              MSG('Make sure LIB2 already cleared') VALUES(G C) +
              MSGRPY(&RPY)
              IF COND(&RPY *EQ 'G') THEN(CHGVAR VAR(&RPY) +
              VALUE('G'))
              IF COND(&RPY = 'G') THEN(DO)
              SBMJOB CMD(CALL PGM(ABC/CLP2)) +
              <----- this part still bugs me, should just use call ? or do i need to use SBMJOB ?
              JOB(RSTLIBOBJ)
              ENDDO
              IF COND(&RPY *EQ 'C') THEN(CHGVAR VAR(&RPY) +
              VALUE('C'))
              IF COND(&RPY = 'C') THEN(GOTO CMDLBL(END))

              i'm sending a user message with an option DO ENDDO so that after i manually confirm the lib already got clreared i can then continue doing the next CLP

              CLP2 :
              sbmjob rstlib savf1 to lib2
              sbmjob rstobj savf2 to lib2
              sbmjob rstobj savf3 to lib2

              ^
              I'm using SBMJOB for the content of this CLP because there are 3 different savfile, or can i just run them without SBMJOB ? Need confirmation on this one

              SNDUSRMSG
              Again the message here is being used to manually confirm that the restored lib and object are successful which i can then proceed to the next CLP

              CLP3 :
              MIMIX/STRDG

              ^in this process i turn back on the data group for the replication


              END: ENDPGM

              Thank you for the advice i appreciate it.

              Comment


              • #9
                I have tried few things based on the advice i was given by all of you here, and the finally i came up with a CL format of

                Master CL:
                pgm
                sbmjob call abc/clp
                endpgm

                CLP:
                call abc/clp1 <--- clrlib

                sndusrmsg: check 1
                if ok, do

                call abc/clp2 <--- rstlib
                enddo

                sndusrmsg: check 2
                if ok, do

                call abc/clp3 <---dsplib
                enddo

                endpgm


                More or less it looked like this, and with this format i finally attained a one submitted job form running all 3 CL sequentially(one running after another one is finished), even though i still do a manual checking before i proceed to the next command (manually checking WRKLIB to check if the library really got cleared until there's 0 object in it, WRKSPLF to check whether all the restored object got successfully restored or not).

                All in all i appreciate all the advice and help, Thank you very much.




                Comment


                • #10
                  Originally posted by Lemon Grande View Post
                  I have tried few things based on the advice i was given by all of you here, and the finally i came up with a CL format of

                  Master CL:
                  Code:
                  pgm
                  sbmjob call abc/clp
                  endpgm
                  You could just submit the ABC/CLP job rather than call a program to submit it. Commands such as SBMJOB that you enter into a CL program can be entered on a command line.

                  Code:
                  CLP:
                  call abc/clp1 <--- clrlib
                  And from your other post:

                  Code:
                  CLP1 :
                  sbmjob clrlib lib2
                  The SBMJOB here will mean a sequential program won't occur as a new job is started and once submitted, the rest of your program will continue. Also note that running CLRLIB in a SBMJOB means it won't go into MSGW if there's an error. You mention you're new to this so you may not be familiar with this. When you create a program and run it in batch, if the command running encounters an error it will normally send a message to the QSYSOPR message queue saying it failed. When that happens, the job pauses on that instruction until the message is answered. If the CLRLIB fails in your program, the job should generate an error. For example, if it failed to clear all objects, it will produce an error in QSYSOPR something like this:

                  Cannot delete some objects in library <whatever the library name is>.

                  Unless you trap this error (using a MONMSG command in the CL program or heaven forbid have an auto-reply for it), the job will go into MSGW and it won't proceed until the message is answered. As such, you shouldn't need manual intervention there. In your example however, you are submitting CLRLIB as a new job so if it fails to clear all the objects the job ends and you need to check the joblog to see if it completed OK or not.

                  If you haven't done it already, you should remove the SBMJOB and just CLRLIB LIB2. You mention you are afraid the restore will occur before the CLRLIB has finished. This won't happen as the CLRLIB will not finish until the library is cleared or a reply has been entered to an error. However, we don't know what CLP1 contains so I can't comment on whether or not you are monitoring for errors. Also, as an FYI, uyou can see the various error message that the command will generate by pressing help (F1) on the command and paging down to the end.


                  Code:
                  call abc/clp2 <--- rstlib
                  enddo
                  And from your other post:

                  Code:
                  CLP2 :
                  sbmjob rstlib savf1 to lib2
                  sbmjob rstobj savf2 to lib2
                  sbmjob rstobj savf3 to lib2
                  You mention you are using 3 different SAVFs. You can do the restores without a SBMJOB however, it means the restores will occur sequentially. The SBMJOB means the 3 jobs can run simultaneously if the subsystem etc allows for it. This is of course faster however, your program will not know when they've finished. If you remove the SBMJOB and code your program like this:

                  Code:
                  CLP2 :
                  rstlib savf1 to lib2
                  rstobj savf2 to lib2
                  rstobj savf3 to lib2

                  rstlib savf1 to lib2 will be executed first. Once complete, rstobj savf2 to lib2 will run. Once that's finished, rstobj savf3 to lib2 will run. As you can see, they will run one after the other so will take longer to restore than running them side by side. Using SBMJOB for the restore has the same issues as CLRLIB where the job will end and you won't know if it was successful or not without looking at the joblog. Running without the SBMJOB means the restore will generate an error message if something goes awry and pause waiting for the reply.
                  Last edited by john.sev99; November 10, 2019, 06:41 PM.

                  Comment


                  • #11
                    Lemme answer some of your concern:
                    1. You could just submit the ABC/CLP job rather than call a program to submit it. Commands such as SBMJOB that you enter into a CL program can be entered on a command line.
                    2. If you haven't done it already, you should remove the SBMJOB and just CLRLIB LIB2.
                    3. You mention you are using 3 different SAVFs. You can do the restores without a SBMJOB however, it means the restores will occur sequentially.

                    1. Yes i am aware that i can just simply do a manual SBMJOB, i just did it in a form of CL to make it easier for my team.

                    2. I already done this for all the CLPs, so now there is only 1 SBMJOB which is the Master CL that contains the other 3 CLP (no more SBMJOB inside them).

                    3. Since i already did this for all other CLP (no longer using SBMJOB inside of them), yes i already make it into your recommended format and move sequentially.
                    rstlib savf1 to lib2
                    rstobj savf2 to lib2
                    rstobj savf3 to lib2


                    The SBMJOB here will mean a sequential program won't occur as a new job is started and once submitted, the rest of your program will continue. Also note that running CLRLIB in a SBMJOB means it won't go into MSGW if there's an error. You mention you're new to this so you may not be familiar with this. When you create a program and run it in batch, if the command running encounters an error it will normally send a message to the QSYSOPR message queue saying it failed. When that happens, the job pauses on that instruction until the message is answered. If the CLRLIB fails in your program, the job should generate an error. For example, if it failed to clear all objects, it will produce an error in QSYSOPR something like this:

                    Cannot delete some objects in library <whatever the library name is>.

                    Unless you trap this error (using a MONMSG command in the CL program or heaven forbid have an auto-reply for it), the job will go into MSGW and it won't proceed until the message is answered. As such, you shouldn't need manual intervention there. In your example however, you are submitting CLRLIB as a new job so if it fails to clear all the objects the job ends and you need to check the joblog to see if it completed OK or not.
                    Now after i finished setting it so that there're no more SBMJOB inside the CLPs and only one SBMJOB i have already tried running the CL and make it so that everytime a CLP is being done the submitted job from the Master CL will show an MSGW and i make it so that the MSGW will inform what needs to be manually done/checked (for example after the CLRLIB CLP finished the MSGW will instruct the user to check the WRKLIB LIB2 to see if it has already been cleared or not, and can reply the MSGW with G to continue to the next CLP or C to cancel the CL).

                    ^I think i'm already ok with this manual format and checking. But if it's possible to do an auto-reply based on my DCL and DO ENDDO, or an auto-checking spooled file/joblog success or not it will be even nicer though.

                    Comment


                    • #12
                      Originally posted by Lemon Grande View Post
                      ^I think i'm already ok with this manual format and checking. But if it's possible to do an auto-reply based on my DCL and DO ENDDO, or an auto-checking spooled file/joblog success or not it will be even nicer though.
                      As I tried to elude to, if these steps fail your job will issue an error message anyway so the manual checks shouldn't be necessary.
                      CLP1 does the CLRLIB. If the CLRLIB fails (doesn't clear all objects for instance), your job will go into MSGW with an error. A CL program can trap errors and ignore them or do some processing however. I can't comment on whether your programs do this or not.

                      As an example, I created a library called TESTLIB. I created 2 files in here, FILE1 and FILE2:
                      Code:
                      Opt  Object      Type      Library     Attribute   Text        
                           FILE1       *FILE     TESTLIB     PF          A file      
                           FILE2       *FILE     TESTLIB     PF          Another file
                      I created a program (TESTCLR) that simply tries to clear this library:
                      Code:
                      PGM
                         CLRLIB     LIB(TESTLIB)
                      
                      ENDPGM
                      On the command line, I allocated FILE1 exclusively. The reason for doing this is to prevent it from getting deleted:
                      ALCOBJ OBJ((TESTLIB/FILE1 *FILE *EXCL))


                      I then submitted my program:
                      SBMJOB CMD(CALL PGM(TESTCLR)) JOB(TESTCLR)


                      By default, the job will wait for 120 seconds to get a lock on an object. As this will fail the job will go into MSGW. And from WRKACTJOB, I can see this:
                      TESTCLR XXXXXXX BCH .0 PGM-TESTCLR MSGW

                      And if I look in the QSYSOPR message queue, I can see:
                      CPF2161 received by procedure TESTCLR. (C D I R)
                      Reply . . .


                      The program is now waiting for a reply to this message and if I look in TESTLIB, FILE1 is the only file in there. As such, you shouldn't need to run the manual checks.

                      If you are still paranoid about it, you could automate a check by displaying the contents to a file and checking the number of records. e.g:
                      Code:
                      PGM                                                  
                         DCL   &NbrRcds   *DEC (10 0)                      
                      
                      
                         CLRLIB     LIB(TESTLIB)                          
                      
                         DSPOBJD    OBJ(TESTLIB/*ALL) OBJTYPE(*ALL) +      
                                    OUTPUT(*OUTFILE) OUTFILE(QTEMP/LIBOBJS)
                         RTVMBRD    FILE(QTEMP/LIBOBJS) NBRCURRCD(&nbrrcds)
                         DLTF       FILE(QTEMP/LIBOBJS)
                         IF         COND(&nbrrcds > 0) THEN(DO)            
                            /* Some objects still present so do something here */                        
                         ENDDO                                            
                      
                      
                      ENDPGM

                      Comment


                      • #13
                        As I tried to elude to, if these steps fail your job will issue an error message anyway so the manual checks shouldn't be necessary.
                        CLP1 does the CLRLIB. If the CLRLIB fails (doesn't clear all objects for instance), your job will go into MSGW with an error. A CL program can trap errors and ignore them or do some processing however. I can't comment on whether your programs do this or not.
                        Okay i'll make it so that i wont be needing to do a manual check.

                        Code:
                        [FONT=courier new]RTVMBRD FILE(QTEMP/LIBOBJS) NBRCURRCD(&nbrrcds)[/FONT]
                        And about this command, can i use this to check whether my 3 different RST command successfully restore all the objects ?

                        Comment


                        • #14
                          Originally posted by Lemon Grande View Post

                          Okay i'll make it so that i wont be needing to do a manual check.

                          Code:
                          [FONT=courier new]RTVMBRD FILE(QTEMP/LIBOBJS) NBRCURRCD(&nbrrcds)[/FONT]
                          And about this command, can i use this to check whether my 3 different RST command successfully restore all the objects ?
                          You could if you know how many objects should be in the library after the restores have completed.
                          The DSPOBJD command that I used in the example program is simply one way of getting a list of objects in a library. The OUTFILE parameter tells the command to put the list of objects into a physical file which you can then use for whatever purposes. 1 record is added to the file for each object in the library. The RTVMBRD command gets information on a file. Because there is 1 record per object, the information I chose to get was the number of records in the file. If there are records in the file, then there are objects in the library so the clear was not successful. Likewise, if you know how many objects should be restored, you can check there are that many objects after the restores have finished.

                          NOTE: My example program was not tested and looking at it, the DSPOBJD command will error if there are no objects in the library which is not useful for an automated process. As I have mentioned in earlier comments though, it is possible for a CL program to trap errors so here is a modified program taking into account the error that will be generated if there are no objects in the library so this will be a more robust program (still not tested though!):

                          Code:
                          PGM
                             DCL   &NbrRcds   *DEC (10 0)
                          
                          
                             CLRLIB     LIB(TESTLIB)
                          
                             DSPOBJD    OBJ(TESTLIB/*ALL) OBJTYPE(*ALL) +
                                        OUTPUT(*OUTFILE) OUTFILE(QTEMP/LIBOBJS)
                             MONMSG     MSGID(CPF2123) EXEC(GOTO  END)
                          
                             RTVMBRD    FILE(QTEMP/LIBOBJS) NBRCURRCD(&nbrrcds)
                             DLTF       FILE(QTEMP/LIBOBJS)
                             /* Objects exist, do something here */
                          
                          
                          END:
                          ENDPGM
                          The RTVMBRD command is not really necessary here as the existence of the file means there are objects.
                          The MONMSG command after the DSPOBJD is monitoring for message ID CPF2123 (No objects of specified name or type exist in library xxxx) generated by this command. If this error is generated, the command in the EXEC parameter is executed, in which case we just go to the end of the program. This is what you want to occur for the CLRLIB command. If the file is created, there are objects in the library so you will want to do something there.
                          Last edited by john.sev99; November 12, 2019, 02:55 PM.

                          Comment

                          Working...
                          X