Better coding starts with a design

David Shirey’s article, Managing RPG Program Complexity is, as the title suggests, aimed primarily at IBM i developers. The general principles, however, are true for anyone doing any sort of development and is worth a read. I particularly liked the last couple of paragraphs:

Limiting program complexity is a way of thinking, not a series of tips, and it starts with thinking through your design before you begin putting code on the screen. What are you trying to accomplish? What individual logical ideas make up your overall goal? How do you want to structure those ideas using programs and subprocedures?

… Most important, simplicity doesn’t just happen. Complexity just happens—you have to work at simplicity. But in today’s world, I can’t think of a more worthy endeavor.

If you didn’t manage to read that far, the TL;DR version is that any application consists of several descrete logical steps. Each of these discrete steps should be coded seperately and should be small enough that anyone (with the relavant language skills, obiously) should be able to glance at it and know exactly what it is doing. How you break out the various functional pieces is less important than that you do break them out.

Or, to rephrase it slightly, people who write massively monolithic programs deserve to have their fingers broken.

Debugging RPG Programs in Batch

If you spend any time developing RPG applications you will find that, sooner or later, you will need to debug a program that runs in batch. There are a few steps that you need to take in order to do this and, because my memory is terrible, I’m putting them here.

  • Know what job queue your job is being submitted to. Hold this job queue.
  • Submit your job.
  • Your job is now sitting on the held job queue waiting to be released. Display the job and make a note of the user name, job name and number.
  • Start a service job using STRSRVJOB entering the name, job name and number from the previous step.
  • STRDBG PGM(ProgramName). You can’t enter any breakpoints yet, so hit F12 to exit the source display
  • Release the job queue
  • The Start Serviced Job screen will be displayed asking you to press F10 to enter debug commands for the job. Press F10.
  • DSPMODSRC and enter your breakpoints.
  • Press F12 to resume and F3 to return to the Start Serviced Job screen.
  • Press Enter to start your job.

The job will now begin running and will stop, passing control back to your screen, when the first breakpoint is reached.

Application modernisation on the IBM i: Developers, Developers, Developers!

RPG, the programming language that remains very popular on the IBM i platform is often criticised for being a bit… venerable. It is certainly true that the language goes all the way back to 1959 and is one of the very few languages developed for punched card processing that is still in common use today.

However, in its current incarnation the language is a very different beast to its precursors. ILE RPG is every bit as modern, functional and flexible as its more recent rivals and, when it comes to encapsulating business rules, ILE RPG on an IBM i remains an unbeatable combination.

This is only true, however, if programmers take advantage of the features provided and, in far too many cases, they don’t.

When people talk about modernising RPG or about modernising i applications it is worth keeping in mind that the perceived datedness does not stem from either the languages or the tools. The real problem lies in the army of semi-competent, under-resourced developers scattered across isolated offices and churning out code that would have been embarrassing twenty years ago.

The backward compatibility that the IBM i retains is a hugely important part of the box’s appeal. Knowing that you can simply apply any upgrade that comes along without any downtime or breakages is a significant part of the i’s stability and provides a great deal of peace of mind to those administering it. The downside of this, however, is that it also makes it very easy for developers to settle into their comfort zones and quietly watch the rest of the industry pass them by.

These are the people that IBM needs to reach out to. IBM needs to convince these people that it is in their interest to understand how to make the most of the available languages and tools. I suspect that IBM will also need to convince IT managers that the productivity gains to be made from moving forward far outweigh the cost of training, but this is what marketing folks are for.

The IBM i is a secure, stable, reliable and powerful platform and RPG is a powerful, functional and flexible language that enables very small teams to develop and maintain very large systems. I am increasingly of the view that what undermines the platform more than anything else is the large number of developers who are unwilling to keep up with the technology.

This rant was provoked by the goto statement I found in a three year old program.

Display Program Locks: The quick way of finding who is using a program

Another week, another utility. I’m supporting an application which, among other things, includes the concept of Conflicting Programs. This works by attaching an Activity Level to each program – essentially a count of how many instances of that program are active. When someone launches a program, its Activity Level is incremented and when they exit the program its activity level is decremented.

Each program within the application also has a list of Conflicting Programs attached to it. When you try to launch a program, the activity level of each of its conflicting programs is checked and if any of these activity levels is not zero, the program will not start. Instead, you will see a message telling you which Conflicting Program is active.

It’s a simple and (usually) effective method of ensuring that end users can’t cause data discrepancies by executing tasks when they shouldn’t – you can’t start entering transactions when a month end close is in progress, for example. The problem is that the application can only tell you that a program is active – not who is using it. When someone is preventing you from starting the month close and going home by leaving a transaction entry screen open, identifying who is holding things up is something you want to be able to do as quickly as possible. This is where the Display Program Locks utility comes in.

What this utility does is scans the active jobs on the system and, for each one found, checks its call stack. If the offending program is found, the job is added to a list which is displayed on the screen. The screen handling is pretty basic, but sufficient for the environment in which I am using this utility.

Three source files are attached, for the Display File (DSPPGMLCKD.DSPF), the RPG (DSPPGMLCKR.RPGLE) and the Command Source (DSPPGMLCK.CMD). Feel free to take a look and, if you decide to download and compile it, you will be able to use the DSPPGMLCK command to find exactly who is using any given program.

As ever, comments, observations and improvements are always welcome.

SQL in RPG: Updating tables with and without journaling

When you compile a SQLRPGLE program, the default Commitment Control option is *CHG. This indicates that tables you update will be locked until the changes are committed or rolled back. This is all well and good, but you do need to have journaling switched on for the tables for it to work.

The compiler doesn’t check this so, by default, a program to update an unjournaled table will compile and can be executed. It just won’t make any updates and you will need to dig through the job log to track this down.

The Right Way

What you should do is journal everything and take full advantage of commitment control.

In order to do this, you would need to create a journal receiver and a journal…

CRTJRNRCV JRNRCV(MYLIB/MYRECV) TEXT('My Journal Receiver')
CRTJRN JRN(MYLIB/MYJRN) JRNRCV(MYLIB/MYRECV) TEXT('My Journal')

And start journaling your files…
STRJRNPF FILE(FILEA, FILEB, FILEC, …) JRN(MYLIB/MYJRN) IMAGES(*BOTH) OMTJRNE(*OPNCLO)

When you want to stop journaling a file, you can do this:
ENDJRNPF FILE(*ALL | FILEA, FILEB, FILEC, …) JRN(MYJRN)

Bear in mind that the journal receivers can get pretty big pretty quickly so you will need to talk to your operations folks about disconnecting and purging these on a regular basis.

The Other Way

Of course, you may well be working with a third party application which is not taking advantage of commitment control and, for which, you can’t justify implementing a whole set of journals. This leaves you needing to turn off commitment control for your SQLRPGLE program. There are two ways of doing this:

What you can do, every time you come to compile this program, is ensure that you compile it with COMMIT(*NONE).

This approach works but it does rely on you, and every developer that follows you, remembering to change the COMMIT parameter. To me, this is a guarantee that sooner or later someone will forget and a trivial change will suddenly break a previously reliable program.

It is much better to explicitly turn off commitment control in the program itself, ideally in the header spec. Unfortunately, I’m on release 6.1 and this doesn’t include a compiler option for commitment control in the h-spec, so I am left with the following workaround.

Put this line of code at the start of you program:
exec sql Set Option Commit = *NONE;

Commitment control is now switched off and your SQLRPGLE program will happily update your horrible, unjournaled, third-party table.

More fun with APIs

So the application I mentioned on Monday was finally approved late yesterday and, today, it’s written and working. There were, inevitably enough, some changes to the spec. The application that has been approved can be executed once an outage has been started and will send a break message to any session still signed on that shouldn’t be, and generate a simple report so the operations folks can visit the offending users with a baseball bat.

This, in itself, wouldn’t be enough for me to bother reposting the code but since I also took the opportunity to develop the application in RPG (or Free Format ILE RPG if you want to be search engine friendly). Doing this gave me a great deal more flexibility over the earlier CL code and also allowed me to prototype the API names into something a lot more readable. You’ll see what I mean if you take a look at the code.

Again, I have filed off the serial numbers and you can take a look at the code here: Lockout.RPGLE

Feel free to copy it, compile it and modify it if it is of any use to you. And if you have any comments or observations, I’d love to hear them.

I do mean it about the baseball bat, though.