What a great thread.
Thanks everyone for the input. I shall have to re-read all that stuff again later, and hopefully some of it will sink in.
Expect further questions.
Actually I have one already : 6 years ago when we started using ILE, we did apparently have some service programs. They were dropped and the modules bound by copy into all the programs that used them. At least, we have continued to keep all related procedures in the same module. Now, I do not know the reason why service programs were dropped. Noone seems to remember why. I wonder if it could be anything to do with activation groups and mixing OPM with ILE. If an RPGIII called a SRVPGM procedure by means of an RPGIV encapsulating program, then ended and the next RPGIII did the same, aren't there potential problems of the service program not releasing objects or initializing variables?
De : rpg400-l-bounces@xxxxxxxxxxxx [mailto:rpg400-l-bounces@xxxxxxxxxxxx] De la part de Mark S. Waterbury
Envoyé : jeudi 31 juillet 2008 17:45
À : RPG programming on the AS400 / iSeries
Objet : Re: Question about service programs
Once you have decided that using *SRVPGMs is a "good idea," you need to create a "go forward" plan for how to transition from "where you are today" to "where you want to be" ...
A suggested "rule" -- each *MODULE should only ever be bound into one *PGM or *SRVPGM. (This simplifies maintenance.)
First you should decide how you want to structure your service programs.
The choices are:
1. bind all modules into one giant *SRVPGM
(over-simplified -- incurs extra overhead to activate a huge *SRVPGM when only one or a few procedures may actually be needed/called)
2. bind "related" modules into a *SRVPGM that represents how those modules are related to each other (and where typically when one procedure is called, others in the same "related" service program are also likely to be called);
3. create one *SRVPGM for each *MODULE (where the name of the *SRVPGM is the same as the name of the *MODULE)
You also need to think about how you want to use activation groups. For example, if you bind all "related" modules into one service program, it might make sense to assign a persistent activation group (e.g. with the same name as the service program) for that service program. That way, whenever that service program gets "activated" this named activation group gets created automatically. You can force termination of that activation group with RCLACTGRP ACTGRP(name) from a command line (for debugging), or within a CL program, when appropriate.
Once you have decided on your approach, you need to bind all of your modules to create the new service program(s) using CRTSRVPGM.
Next, create a new binding directory that lists only the service programs, and does NOT include any modules.
Now, you will use this new binding directory, in place of the old binding directory, whenever you recompile and bind your programs.
(You might want to rename the old binding directory, then rename the new binding directory to the name of the old binding directory.)
Next, you will need to re-bind all of your existing bound *PGMs from its original *MODULE, using the new binding directory, to create new, much smaller *PGMs that use the *SRVPGMs automatically. (Assuming you keep all *MODULEs around, even after binding, you can just use the CRTPGM command to recreate the *PGMs with the new binding directory.)
If you do not keep the *MODULEs for your *PGMs, for example, if you compile them with the CRTBNDRPG command, and use an H-spec in the source such as:
H DftActGrp(*NO) ActGrp(*CALLER) BndDir('BNDDIR')
H DftActGrp(*NO) ActGrp('QILE') BndDir('BNDDIR')
you might need to recompile each program to create the new version that uses the *SRVPGMs instead of using CRTPGM to recreate from the original *MODULE.
(You could do this re-binding of *PGMs "all at once" or gradually, over a few days or weeks.)
For maintenance, you can use UPDSRVPGM to replace a *MODULE within a *SRVPGM with a new version.
Only when the "interface" (procedure names, number of parameters, etc.) changes, will you need to recompile and re-bind any callers of the changed procedure(s). There are techniques using "signatures" for *SRVPGMs that can avoid the need to re-bind older unmodified callers of those procedures. But that is getting more advanced. For now, you probably do not need to worry about that, to start using service programs and getting the benefits.
Does that help?
Mark S. Waterbury
David FOXWELL wrote:
Looking forward to the reply to that question, Adam, thanks! But it's winter and late downunder so we might have to wait until tomorrow.
I have been having some fun experimenting while creating a new module recently. I made it into a SRVPGM and then to test, bound it to an RPG. At the same time, I experimented with activation groups and got the test program to run in its own group that was deleted at the end of the program.
Interesting, watching my colleagues continuing to have to recompile each time they changed the module being tested, or having to do sign off when the test program didn't let go of a file ! No more of that for me!
But now I am convinced that SRVPGMs are the way to go, changing all those programs doesn't seem to be an easy task.
De : rpg400-l-bounces@xxxxxxxxxxxx
[mailto:rpg400-l-bounces@xxxxxxxxxxxx] De la part de Adam Glauser
Envoyé : jeudi 31 juillet 2008 14:43 À : rpg400-l@xxxxxxxxxxxx Objet :
Re: Question about service programs
On 31/07/2008, at 6:10 PM, David FOXWELL wrote:<snip>
We have not yet implemented the use of service programs. So each
program has its own copy of the code.
If we have 50 people using the same interactive program that weighs
40 Mb, made up of many modules bound by copy and no service
programs, are there 50 copies of that program in activated or is it shared ?
Simon Coulter wrote:
All programs on OS/400 are re-entrant. There is only one copy of the
code loaded. Each user has their own copy of variable storage but
they all share the same copy of the code--even if they are running in
different main storage pools. It's been that way since System/38.
I think that David might have the right idea, but not asking quite the right question. To simplify David's case, lets suppose we have PGM0, consisting of modules MOD_0 and MOD_UTIL. We also have PGM1, consisting of MOD_1 and MOD_UTIL.
If I now run PGM0 which calls PGM1, wouldn't there essentially be two
copies of the code for MOD_UTIL in memory? I think this must be the
case, since if I change MOD_UTIL and rebind PGM0 but don't rebind
PGM1 will still use the "old" version of the MOD_UTIL code.
In any case David, I would echo Simon's recommendation to start using Service Programs. It's really not hard, and it beats the "compile the world" maintenance model hands down.
This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing
list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe,
unsubscribe, or change list options,
or email: RPG400-L-request@xxxxxxxxxxxx Before posting, please take a
moment to review the archives at http://archive.midrange.com/rpg400-l.
This is the RPG programming on the AS400 / iSeries (RPG400-L) mailing list To post a message email: RPG400-L@xxxxxxxxxxxx To subscribe, unsubscribe, or change list options,
or email: RPG400-L-request@xxxxxxxxxxxx
Before posting, please take a moment to review the archives at http://archive.midrange.com/rpg400-l