Skip to main content

Hullo all. I hope the collective intelligence of the community can help guide us here.

We have a large-ish program written & running under AcuGT (Extend) for Windows. It has a Windows UI. It is a real-time transaction processing engine with a UI to monitor and control the activity. So it runs in 2+ threads but its a single program.

We want to split this into two programs:

  1. A transaction processing engine that runs as a Windows Service, so it launches on boot and is always running. No UI at all.
  2. A UI that interacts with the above program. Ideally we would just take the existing code - the current UI thread - and make minimal changes to it, so it will still be an AcuGT/Extend program. But users could launch/run it using AcuToWeb.

We want to put minimal effort into this, as it does not extend the functionality of our product, it just solves some security + remote-access issues.

It should not be too hard to simply split this one program (currently implemented as two threads) into two programs. But what would be the easiest (and most robust) way to implement (inter-process) communications between them? They will be running on a single server.

Note there could be multiple instances of the UI app. We will have to figure that out. We can utilize a design that allows only one at a time.

Thank you!

Hullo all. I hope the collective intelligence of the community can help guide us here.

We have a large-ish program written & running under AcuGT (Extend) for Windows. It has a Windows UI. It is a real-time transaction processing engine with a UI to monitor and control the activity. So it runs in 2+ threads but its a single program.

We want to split this into two programs:

  1. A transaction processing engine that runs as a Windows Service, so it launches on boot and is always running. No UI at all.
  2. A UI that interacts with the above program. Ideally we would just take the existing code - the current UI thread - and make minimal changes to it, so it will still be an AcuGT/Extend program. But users could launch/run it using AcuToWeb.

We want to put minimal effort into this, as it does not extend the functionality of our product, it just solves some security + remote-access issues.

It should not be too hard to simply split this one program (currently implemented as two threads) into two programs. But what would be the easiest (and most robust) way to implement (inter-process) communications between them? They will be running on a single server.

Note there could be multiple instances of the UI app. We will have to figure that out. We can utilize a design that allows only one at a time.

Thank you!

So, you need to replace send/receive thread messages with something else.  C$SOCKET is your best solution, just make sure waiting for a connection doesn't block, nor does trying to read messages from a connection.   Just reserve a port on the local machine and use either localport or 172.0.0.1 as the IP address.  With C$SOCKET you could also move the client to a different machine.   Alternatively, for a local solution, you could also use send/receive files in a shared folder.  Client writes to file x, and then creates a matching "done" file.  Service watches for incoming message files using C$LIST-DIRECTORY, reads the file when it sees the .done.  Processes, removes the original file, creates a response file, also with a .done file.  Client has to watch the folder too.  Use C$SLEEP liberally to avoid busy loops.


So, you need to replace send/receive thread messages with something else.  C$SOCKET is your best solution, just make sure waiting for a connection doesn't block, nor does trying to read messages from a connection.   Just reserve a port on the local machine and use either localport or 172.0.0.1 as the IP address.  With C$SOCKET you could also move the client to a different machine.   Alternatively, for a local solution, you could also use send/receive files in a shared folder.  Client writes to file x, and then creates a matching "done" file.  Service watches for incoming message files using C$LIST-DIRECTORY, reads the file when it sees the .done.  Processes, removes the original file, creates a response file, also with a .done file.  Client has to watch the folder too.  Use C$SLEEP liberally to avoid busy loops.

For using C$SOCKET, I would probably set up a copy library with a thread command replacment routines: TCPSEND, TCPRECEIVE, TCPWAIT.  In the client program, set up whatever variables those routines would need to pass down to a subprogram (buffer, size, timeout), then PERFORM them, and use whatever response variables get set.  Those library routines should use the same subprogram for the C$SOCKET calls, so they can share the handle of an open socket.  Just pass down a variable indicating which operation is being requested.  (send can auto-connect, and receive/wait can use the server routine to wait for a connection if there isn't one yet)


So, you need to replace send/receive thread messages with something else.  C$SOCKET is your best solution, just make sure waiting for a connection doesn't block, nor does trying to read messages from a connection.   Just reserve a port on the local machine and use either localport or 172.0.0.1 as the IP address.  With C$SOCKET you could also move the client to a different machine.   Alternatively, for a local solution, you could also use send/receive files in a shared folder.  Client writes to file x, and then creates a matching "done" file.  Service watches for incoming message files using C$LIST-DIRECTORY, reads the file when it sees the .done.  Processes, removes the original file, creates a response file, also with a .done file.  Client has to watch the folder too.  Use C$SLEEP liberally to avoid busy loops.

Robert thank you for replying, and for giving this so much thought.

We would run the server side (ACCEPT) on the transaction processing engine. But as I understand the documentation, the ACCEPT will block all threads until it receives a connection. And it will be relatively rare for it to receive a connection. So that seems to be a fatal flaw, unless I am mis-reading it.

For this reason we coded non-blocking socket routines in C many years ago. But they are complex to use, partly because of the non-blocking nature.

I guess I was hoping there was some kind of IPC messaging capability that I wasn't aware of. Do you have any knowledge of the Acucobol integration wiht IBM Websphere MQ ?


Robert thank you for replying, and for giving this so much thought.

We would run the server side (ACCEPT) on the transaction processing engine. But as I understand the documentation, the ACCEPT will block all threads until it receives a connection. And it will be relatively rare for it to receive a connection. So that seems to be a fatal flaw, unless I am mis-reading it.

For this reason we coded non-blocking socket routines in C many years ago. But they are complex to use, partly because of the non-blocking nature.

I guess I was hoping there was some kind of IPC messaging capability that I wasn't aware of. Do you have any knowledge of the Acucobol integration wiht IBM Websphere MQ ?

Hmmm. I am taking a closer look at the socksrvm sample program and the AGS-NEXT-READ op-code. It seems this provides a way to wait for client connections without blocking. And also to wait for incoming messages on those sockets without blocking. Is that right?


Hullo all. I hope the collective intelligence of the community can help guide us here.

We have a large-ish program written & running under AcuGT (Extend) for Windows. It has a Windows UI. It is a real-time transaction processing engine with a UI to monitor and control the activity. So it runs in 2+ threads but its a single program.

We want to split this into two programs:

  1. A transaction processing engine that runs as a Windows Service, so it launches on boot and is always running. No UI at all.
  2. A UI that interacts with the above program. Ideally we would just take the existing code - the current UI thread - and make minimal changes to it, so it will still be an AcuGT/Extend program. But users could launch/run it using AcuToWeb.

We want to put minimal effort into this, as it does not extend the functionality of our product, it just solves some security + remote-access issues.

It should not be too hard to simply split this one program (currently implemented as two threads) into two programs. But what would be the easiest (and most robust) way to implement (inter-process) communications between them? They will be running on a single server.

Note there could be multiple instances of the UI app. We will have to figure that out. We can utilize a design that allows only one at a time.

Thank you!

First, I should note that I am not an expert on C$SOCKET, but I have used it, so I figure my skill level is intermediate.

Without blocking?  Effectively.  Technically, it will block for the timeout value when there is no data waiting to be read, but keep that small and you hardly block at all.  When waiting for a connection, keep the timeout small and add a sleep when nothing happens, to avoid wasting time just waiting for connection(s).  Please note, this assumes that your server side stuff needs to run while waiting for a connection.  You could simplify things if the server side required the client to be running/connected in order to do anything, but I think you would be better off letting the client disconnect/reconnect as needed.

With the AGS-READ, you can choose to block for a small timeout, or use the zero-size read trick to check for data, then read only that amount of data.  This results is a zero-wait read with a test/read (technically 2 reads, one to test for data, one to get it).  Given that this is a replacement for checking for messages, that should work.  (Warning: Since the packets could have only part of the message due to network traffic optimization etc, you will also have to test if the message is completely received, or if you have to save what you have so far, treat the message as not received yet, and check for more the next time you check for the message.  And handle a dropped connection by resetting the buffer info, and changing your internal flags that mark the connection as on or off.  You know, programming stuff.)


First, I should note that I am not an expert on C$SOCKET, but I have used it, so I figure my skill level is intermediate.

Without blocking?  Effectively.  Technically, it will block for the timeout value when there is no data waiting to be read, but keep that small and you hardly block at all.  When waiting for a connection, keep the timeout small and add a sleep when nothing happens, to avoid wasting time just waiting for connection(s).  Please note, this assumes that your server side stuff needs to run while waiting for a connection.  You could simplify things if the server side required the client to be running/connected in order to do anything, but I think you would be better off letting the client disconnect/reconnect as needed.

With the AGS-READ, you can choose to block for a small timeout, or use the zero-size read trick to check for data, then read only that amount of data.  This results is a zero-wait read with a test/read (technically 2 reads, one to test for data, one to get it).  Given that this is a replacement for checking for messages, that should work.  (Warning: Since the packets could have only part of the message due to network traffic optimization etc, you will also have to test if the message is completely received, or if you have to save what you have so far, treat the message as not received yet, and check for more the next time you check for the message.  And handle a dropped connection by resetting the buffer info, and changing your internal flags that mark the connection as on or off.  You know, programming stuff.)

THANK YOU, this is extremely helpful - exactly what we need.

Yes, I have decades of experience around performance and responsiveness. I know we have to sleep in every loop, and keep these blocks under a few milliseconds so we can respond to other demands quickly. And I know that socket messages can be received in pieces. But I am not sure I would have figured out the "zero-size read trick". Thanks for that, too.

I wish I had understood years ago the runtime has the ability to do socket communications without blocking. I swear I consulted Acucobol (the company name at the time) when we implemented this. But I have looked back to the 8.1.3 release notes and the documentation is the same as it is now, so I don't think this has changed.

Again, thank you!