In Part 1 we looked at activation group basics. Now let's take a look at types.
Editor's Note: This article is excerpted from chapter 17 of 21st Century RPG: /Free, ILE, and MVC, by David Shirey.
Activation Group Types
If you set the DFTACTGRP parm to *NO (I want to be ILE), then another parm will miraculously appear on the compile command: the ACTGRP parm, which lets you set the type/name of the activation group that will be associated with this program. That is, this is where you tell the compile what activation group the program will run in and will be started (unless it already exists) when the program is kicked off. Let’s take some time and carefully go through each option.
Just so you know, one of the most important things to notice about each group is how it is ended. With OPM, the environment died when the program did (INLR on), but ILE is not that clear-cut because it wants to give you more control over what happens. In other words, ILE trusts you to make the right decision for your app. Oh, that’s so sweet. And yet, sad, oh so sad.
If *NEW is specified, then a new activation group will be created for this program when it is run. The name of that activation group will be assigned by the system and will be something weird and freaky.
As a result, if two people call the same program with a *NEW activation group, two differently named activation groups will be started.
If you specify *NEW on every compile, then every program will run in its own activation group and you will have essentially an OPM system. That is probably not what you want, but there are definitely times when *NEW is the right option.
On the positive side, this type of activation group is automatically ended when the program associated with this group ends. Thus, the cleanup is automatic and timely.
On the negative side, if you use *NEW for every program, then you will end up with a ton of activation groups that do not share, and you will be no farther along than if you were OPM.
*NEW is not available for service programs. Because they are always called from somewhere else and so, are not really “new.”
If a name is entered, one that you have made up, then this name will be used on the activation group. It is basically the same as *NEW except that you are specifying the name rather than letting the system do it, so it might be more intuitive to you. Or it may just be one more thing you have to think about.
Like *NEW, if you specify a specific name on every compile, then you will have essentially an OPM configuration.
The difference is in the end. Named activation groups will persist even after the program has ended. The theory is that if a program whose compile was pointed at this activation group starts up again, it can then grab that activation group and save the overhead of starting one up, so it makes sense if a program ends and restarts pretty regularly. The only way to get rid of one of these is to run a RCLACTGRP (Reclaim Activation Group) command. If you use this for a program that is used frequently, you might want to set up the RCLACTGRP for that name as part of the daily or weekly process. You really probably don’t want it to live forever.
One additional characteristic of the named activation group is that any global variables you are using in that program will also be visible (that is, usable) by programs in other named activation groups. Whether you think “hey, that is something handy” or “good grief, why did they allow that?” is up to you and says a lot about your personality. It could be either good or bad; just be aware that it can happen. Of course, if you have perfect ILE modules, you shouldn’t have any global variables.
In this case, the program compiled with this will use the activation group of the program that calls it.
Obviously, it makes no sense for *CALLER to be used on the first program in a sequence, but after that it makes lots of sense.
You will find that *CALLER is one of the more popular activation groups that you will use. If you are calling a series of programs in sequence, you might as well run all those programs together, you know, sharing resources and making like you are all friends and everything.
And since it does not really create its own activation group but just gloms you on to an existing one (either a *NEW or named), you don’t have to worry about ending it.
But *CALLER should only be used if the program you want to run was called by another program that set up an activation group first. If *CALLER is the first program in the sequence, then the program involved will end up running in the default activation group—something you don’t want.
And be careful with *CALLER with service programs. The idea of a service program is that it is called from a number of other programs (hopefully a large number), and the result of setting it up as *CALLER is to get a number of versions of it running in different activation groups, which wastes space and resources. You might be better off to set up your service programs to run in a single, named activation group even though you would have to run a RCLACTGRP regularly. It’s something to think about.
This is not the default activation group. The default activation group does not really have a name, it just sort of always exists, and in ILE we do not want to use it.
QILE is simply a name that IBM has assigned (hence the “Q”) to a named activation group, so that if you do not specify a name or *NEW or *CALLER, the program will fall back onto the QILE named activation group. In most compile commands, it is the default value assigned to the ACTGRP parm.
Using QILE still makes the program ILE (that is, determined via the DFTACTGRP parm being *NO, not based on the value in the ACTGRP parm). When a QILE group ends, you must use RCLACTGRP to do the reclaim (because it is really a “named” activation group). It won’t happen on its own as with *NEW.
Generally, using QILE is frowned upon by the cool kids. The main problem is that it is not very discriminating. That is, you might be using it, but it is also possible that some third-party software you are running might be using it, too. Now if you do a RCLACTGRP on QILE (after all, it is a named activation group) to recover your resources, you will also affect other applications that you might not want to have messed with.
The most important thing I want to remind you of is that you do not specify the activation group you want to use when you run the program. You assign it when you do your compile, so it will be the same every time the program runs until you recompile again. Don’t get confused by that.
What Happens When an Activation Group Closes?
So, we have some activation groups where the group goes away when the last program in that group sequence ends, and some activation groups which will live until you use the RCLACTGRP command. In addition, an activation group will go away if every program in that group fails.
But what actually happens when an activation group closes (because what happens will have a direct bearing on how we use them)?
- First, any files that are being used in the activation group will be closed.
- Second, any file overrides associated with those files will also
- Third, storage (both static and allocated) being tied up by that function will be
- Fourth, commitment control will end. That is, database changes will be committed if you are under commitment control (otherwise the changes will take place as they happen).
I don’t know about you, but all this is very exciting for me. But then I’m a real thrill seeker.
This is the command you will need to use to reclaim an activation group that does not end on its own.
As we said earlier, any activation group created with a user-defined name (“named”) or by using QILE will need to be deactivated manually by the RCLACTGRP command. It will not happen automatically.
This is a very simple command, just the name of the activation group you want to reclaim, plus an option for *NORMAL and *ABNORMAL.
*NORMAL does things in a civilized manner: committing any pending changes and sending a polite close notification message to any attached host systems.
*ABNORMAL just gets you the heck out of Dodge, and if someone gets hurt in the process, that’s their problem. It rolls back any uncommitted changes and sends a rather nasty and abrupt message to any attached host systems.
The command should only be used when the activation group is not in use.
There is an option for the activation group name to use, *ELIGIBLE, in which case the command will close all activation groups not currently running a job. Using this is not a good idea and should be avoided as it can result in your closing groups that you did not mean to (and which you have no control over, such as third-party groups).
As a parting shot, if you are used to using RCLRSC, stop it. Just stop it right now! It doesn’t work well in the ILE world, and you should be reclaiming resources by controlling your activation groups.