The RPG converter will not only convert your code to Java or C#, it can also help improving its structure. In this example, we are going to see how to remove useless intermediate files. This will improve maintainability and performance of the code.

Intermediate files are a common pattern in RPG programming. They show up in CL script as files that are created before a program run and removed right after:

CRTPF FILE(QTEMP/TMPA) ...
CALL PGM(PGM001)
CALL PGM(PGM002)
DLTF FILE(QTEMP/TMPA)

The intermediate file is used as output by one program and as input by another program. Here is the first program:

     H* PROGRAM PGM001
        ...
     C* Open intermediate file as output
     FTMPA    O E K DISK
        ... some loops ...
     C* Write data to intermediate file
     C WRITE TMPA

And here is the second program:

     H* PROGRAM PGM002
        ...
     C* Open intermediate file as input
     FTMPA   IF   E           K DISK
        ...
     C* Read data from intermediate file
     C                   READ      TMPA                                   90
     C     *IN90         DOWEQ     '0'
        ... do something with the data ...

The default conversion strategy maps an RPG File Specification to an instance of the Java interface File, and attaches file instances to actual files on the system. Here the system file TMPA is still used as an intermediate file:

// PGM001.java
// This attaches tmpa to a system file and opens it for input
File tmpa = new SystemFile("TMPA", "I");
...
void pgm001()
{
   ... some loops ... {
// Write data to intermediate file
      tmpa.write();
   }       
}
// PGM002.java
// This attaches tmpa to a system file and opens it for output
File tmpa = new SystemFile("TMPA", "O");
...
void pgm002()
{
    in90 = tmpa.read();
    while(in90 == false) {
       ... do something with the data ...
           in90 = tmpa.read();
    }

(By the way, we will see in an upcoming example how the RPG converter can make this loop much more Java-like).

So far so good, our Java program works as expected. But do we really need to store data to the file system and re-read it immediately after? Modern servers can hold most workloads in memory. This makes programs orders of magnitude faster, and avoids an entire category of problems related to file processing.

What we can do here is to use a different implementation of the File interface, that reads and write to an in-memory buffer.

We must also pass this File instance as a parameter to pgm001() and pgm002(), since they must work on the same in-memory buffer. This transformation must be made manually, as it is not (yet?) supported by the RPG converter. This is what it looks like:

// This attaches tmpa to an in-memory buffer
File tmpa = new MemoryFile("TMPA", "IO");
...
void main()
{
    // Now run both programs with the same in-memory buffer
    // This removes the need for an intermediate file
   pgm001(tmpa);
   pgm002(tmpa);
}

If memory size is an issue, another possible program architecture is to use two threads communicating via a fixed-size buffer such as java.util.concurrent.ArrayBlockingQueue. At any point in time, there will never be more than a fixed number of element in the buffer between the two programs. This limits memory usage and makes the entire application more responsive.

// This attaches tmpa to an in-memory synchronized buffer
File tmpa = new SynchronizedBufferFile("TMPA", "IO");
...
void main()
{
   // Create a thread for each program. 
   // They will communicate and synchronize through tmpa
   Thread t1 = new Thread(() -> pgm001(tmpa));
   Thread t2 = new Thread(() -> pgm002(tmpa));
 
   // Start both threads in parallel
   t1.start(); t2.start();
   // Wait for both threads to terminate
   t1.join(); t2.join();
}

Et voilà! You’re doing parallel programming with your RPG programs!