IBM i Activation Groups – Part 2

In the previous article about Activation Groups, Activation Groups – Part 1, you got a theoretical approach about the topic, now it’s time to test it. In this second part you’ll have the opportunity to test what happens in this situation:

  • Use only default activation group

Let me tell you how this test is done. There is one main program called ACTGRP1, a secondary program called ACTGRP2 and a support program called RMVEXTMSG.

ACTGRP1 uses the default activation group

ACTGRP2, which is called by ACTGRP1 ends only with RETURN operation code so the file opened in it won’t be closed when the program ends.

RMVEXTMSG. As the program uses DSPLY operation code to show messages to the external queue, this CL program is used to clean the queue before the messages are written.

Once you run ACTGRP1 you’ll have information about what files are opened before the program calls ACTGRP2, when ACTGRP2 is running and after ACTGRP2 has ended. This information is showed because of execution of command DSPJOB OPTION(*OPNF) inside every program. You should execute the command one more time (this time from the command line) once the main program has finished so you’ll be able to see what files remains opened.

TEST 1 – Default activation group

Let’s begin with ACTGRP1. This program uses the default activation group and calls ACTGRP2 that has actgrp(*caller) so it will run in the same activation group as the calling program, the default activation group in this case.

You can see the code below.

ACTGRP1:

				
					**free
dcl-f file1 extdesc('ASALCEDO1/FILE1');

dcl-pr QCMDEXC extpgm;
  *n char(10000) options(*varsize) const;
  *n packed(15:5) const;
end-pr;

dcl-pr actGrp2 extpgm('ASALCEDO1/ACTGRP2');
end-pr;

dcl-pr rmvMsg extpgm('ASALCEDO1/RMVEXTMSG');
end-pr;

dcl-s command varchar(10000);
dcl-s stopDsply char(1);

rmvMsg();
dsply 'BEFORE ActGrp2 pgm';
dsply 'Press Enter' ' ' stopDsply;

command = 'DSPJOB OPTION(*OPNF)';
qcmdexc(command:%len(command));

actGrp2();

rmvMsg();
dsply 'AFTER ActGrp2 pgm';
dsply 'Press Enter' ' ' stopDsply;

qcmdexc(command:%len(command));

*inlr = *on;     
				
			

Explanation:

Line 1: Code will be fully free.

Line 2file1 is declared. (Use any file of one of your libraries if you are running this program in your environment).

Lines 4-7: Prototype for QCMDEXC to execute commands inside RPG code.

Lines 9-10: Prototype for ACTGRP2.

Lines 12-13: Prototype for RMVEXTMSG, the CL program to clear external queue.

Line 15: Variable to hold the command to be executed.

Line 16: Variable to stop the program when a message is displayed in the external queue using DSPLY operation code.

Line 18: Call to rmvMsg so external queue is cleared.

Line 19: Send a message to the external queue just to inform that ACTGRP2 is not running so the output of the command will show information only for ACTGRP1. This is not necessary to activation groups to work, it’s here just for demonstration purposes.

Line 20: Send a message to the external queue and wait for an answer in the variable stopDsply so the program will wait until Enter key is pressed and the previous message can be viewed.

Lines 22-23: Command DSPJOB will be executed but only to show opened files and the activation group in which they are opened.

Line 25ACTGRP2 is called.

Lines 27-29: External queue is cleared again and a new message is displayed indicating that program ACTGRP2 has ended.

Line 31DSPJOB is executed again to show which files remains opened after ACTGRP2 has run.

Line 33ACTGRP1 ends with Last Record indicator on so files are closed.

ACTGRP2:

				
					**free
ctl-opt actgrp(*caller);

dcl-f file2 extdesc('ASALCEDO1/FILE2');

dcl-pr QCMDEXC extpgm;
  *n char(10000) options(*varsize) const;
  *n packed(15:5) const;
end-pr;

dcl-pr rmvMsg extpgm('ASALCEDO1/RMVEXTMSG');
end-pr;

dcl-s command varchar(10000);
dcl-s stopDsply char(1);

rmvMsg();
dsply 'Inside ACTGRP2';
dsply 'Press Enter' ' ' stopDsply;

command = 'DSPJOB OPTION(*OPNF)';
qcmdexc(command:%len(command));

return;  
				
			

Explanation:

Line 1: Code will be fully free.

Line 2: Compile parameter ACTGRP(*CALLER) is set so this program will run in the same activation group as the calling program.

Line 4: file2 is declared. (Use any file of one of your libraries if you are running this program in your environment.)

Lines 6-9: Prototype for QCMDEXC to execute commands inside RPG code.

Lines 11-12: Prototype for RMVEXTMSG, the CL program to clear external queue.

Line 14: Variable to hold the command to be executed.

Line 15: Variable to stop the program when a message is displayed in the external queue using DSPLY operation code.

Line 17: Call to rmvMsg so external queue is cleared.

Line 18: Send a message to the external queue just to inform that ACTGRP2 is running so the output of the command will show information for ACTGRP2 and its calling program, ACTGRP1. This is not necessary to activation groups to work, it’s here just for demonstration purposes.

Line 19: Send a message to the external queue and wait for an answer in the variable stopDsply so the program will wait until Enter key is pressed and the previous message can be viewed.

Lines 21-22: Command DSPJOB will be executed but only to show opened files and the activation group in which they are opened.

Line 24: ACTGRP2 ends only with RETURN operation code so files are NOT closed.

RMVEXTMSG:

				
					            PGM
             RMVMSG     PGMQ(*EXT) CLEAR(*ALL) RMVEXCP(*NO)
             ENDPGM 
				
			

Explanation:

Line 1: Start CL program.

Line 2: Remove Message command. This will remove all messages from EXTERNAL queue but unhandled exception messages.

Line 3: End CL program.

The test begins with the execution of DSPJOB OPTION(*OPNF) to show there are no opened files before ACTGRP1 is run.

Then ACTGRP1 is called. The program sends a message to the EXTERNAL queue informing that the information to be displayed on the next screen is BEFORE running the ACTGRP2 program.

Pressing Enter the program will continue and it will show the files opened by ACTGRP1.

We can see in this screen that FILE1 is now opened and that the activation group in which is opened is *DFTACTGRP.

Pressing Enter the program will continue.

Now ACTGRP2 is called. The program sends a message to the EXTERNAL queue informing that the information to be displayed on the next screen is about ACTGRP2 program which is now running.

Pressing Enter the program will continue.

Now a new file has been added to the list. Program ACTGRP2 is now running and file FILE2 is now opened. If you look to the activation group in which it is opened it is *DFTACTGRP and this is because of it was compiled with parameter ACTGRP(*CALLER) that means the program will be run in the same activation group as the calling program does,  that is in the same activation group as ACTGRP1.

Pressing Enter the program will continue.

ACTGRP2 has ended. The program sends a message to the EXTERNAL queue informing that the information to be displayed on the next screen is about ACTGRP1 because ACTGRP2 has ended.

Pressing Enter the program will continue.

And as expected file FILE2 is still opened as program ACTGRP2 has ended with just a RETURN operation code so no automatic close of files is done. The question is: Will it be closed once program ACTGRP1 has ended?

Pressing Enter the program will end.

It’s time to see if file FILE2 is still opened. So type DSPJOB OPTION(*OPNF) in any command line and press Enter.

Yes, file FILE2 is still there but file FILE1 is not and that’s the correct behavior when you are using the default activation group and end a program without setting *INLR to *ON, files are not closed automatically.

To close the file just signoff and next time you sing on to the system the file won’t be there. Look at the job number in the picture below, is different from the one of the picture above showing that previous session was ended, file FILE2 was closed  when the session ended and after sign on in a new session all is in its initial state

Leave a Reply

Your email address will not be published. Required fields are marked *