Launch an external process asynchronously

Automatically translated from English

Sometimes you have to run processes in the background, and as soon as one finishes, perform some actions according to its exit code. From the v19 R4, 4D allows you to start a process in the background with the new 4D.SystemWorker class and execute callback methods automatically when the process returns information. This way, your application UI stays responsive during the execution of the external process, and when finished, you can display the result to the user right away!

HDI sytem worker

A SystemWorker is an object created using the constructor 4D.SystemWorker.new(process). It creates a new worker that starts the process passed in parameter and waits until the end of it.

Here are a few examples of how to run various git commands using a SystemWorker.

Let’s start simple and imagine you need to retrieve the git version installed on your computer. You have two ways to do so:

  • If you want to do it asynchronously, to let your client continue to use the interface freely, just use a call back that will be called at the end of the process:
$param:=New object
// Close the process after 2s if not already terminated
$param.timeout:=2
// Callback formula called when the response is totaly received by the systemworker
$param.onResponse:=Formula(ALERT($1.response))
// Start the system worker with the parameter defined above
$sys:=4D.SystemWorker.new("git --version"; $param)
  • If you prefer to wait for the process response, just use .wait():
$param:=New object
// Close the process after 2s if not already terminated
$param.timeout:=2
// Start the system worker with the parameter defined above
$sys:=4D.SystemWorker.new("git --version";$param)

// Wait for the end or the process and return the response from Git
ALERT($sys.wait().response)

Let’s continue with a commit that waits for a commit message. In this example, the process waits for standard input. If you are in a console, it means that the console waits for the user to enter a value:

In such cases, you can use the .postMessage() function to send your message and  the .closeInput() function to indicate to the process that the message is sent:

$param:=New object
$param.currentDirectory:=$myProjectDirectory

$sys:=4D.SystemWorker.new("git commit -F -";$param)
$sys.postMessage("This is my first commit")
$sys.closeInput()

As you can notice, the system worker goes further than the Launch external process command. It allows you to start processes asynchronously and receive easily the outputStream and errorStream from the called process. In addition, you can use a new way to communicate with your process through the postMessage() function.

Don’t forget to test this feature with the HDI above and learn how to use it to start several processes in parallel.

Check out the developer center for more details!

Fabrice Mainguené

• Product Owner •

Fabrice Mainguené joined 4D Program team in November, 2016. As a Product Owner, he is in charge of writing the user stories then translating it to functional specifications. His role is also to make sure that the feature implementation delivered is meeting the customer need.

After obtaining a Bachelor degree in Computer Science at CNAM, Fabrice joined a small software publishing company as a Windev developer. Then he worked for different companies in industry and trade areas as a Windev and web developer as well as technical advisor on new features.