Load Server Session Results Manually

If the waitForCompletion argument of pro::DelegateToServer is 0, both the data session and the server session run in parallel. This allows the end user to browse and modify data while a delegated procedure is executed on the server side in the background. However, at the end of execution, the results are loaded back in to the data session without any warning. This unannounced loading of data does not provide the best user experience. This article presents the approach to manually control this data transfer between the data and server sessions.

What is Happening Here?

A typical pro::DelegateToServer call looks as below:

if pro::GetPROEndPoint() then
   if pro::DelegateToServer(
      completionCallback :  'pro::session::LoadResultsCallBack' )  then
      return 1;
   endif ;
endif ;

Any procedure written after the above call will be executed on the server session and the results are stored as a data case file with a certain RequestID, a predefined AIMMS identifier. If the completionCallback argument is the predefined procedure pro::session::LoadResultsCallBack, the aforementioned case file is loaded into the data session automatically. pro::session::LoadResultsCallBack has RequestID as a local input argument.

If you want to manually trigger this loading of results, you need:

  1. the RequestID of the case file you want to load,
  2. a procedure to load this case file, and
  3. a button to run this procedure.

Example Implementation

The approach outlined above is implemented in the running example - the Flow Shop project. Download the completed file from 5. Flow Shop - Load Results.

The workflow is as below:

  1. Retrieve the RequestID in a string parameter using a simple assignment procedure.
  2. Define the completionCallback argument of pro::DelegateToServer call as this procedure to trigger the retrieval.
  3. Create a procedure to load the case file corresponding to the retrieved RequestID and link it to a button on the user interface.

Retrieving the RequestID

Create a string parameter spSavedRequestID to store the requestId and a binary parameter bpResultsAvailable to control the visibility of the load button in the user interface.

StringParameter spSavedRequestID {
   InitialData: "";
Parameter bpResultsAvailable {
   Range: binary;
   InitialData: 0;

Now, create an assignment procedure myLoadResultsCallback with a local input argument RequestID to update the values of these identifiers.

Procedure myLoadResultsCallback {
   Arguments: (RequestID);
   Body: {
      spSavedRequestID := RequestID;
      bpResultsAvailable := 1;
   StringParameter RequestID {
      Property: Input;

When run, this procedure simply stores RequestID in spSavedRequestID and updates bpResultsAvailable to 1. This should not be mistaken with the actual loading procedure.

Provide completionCallback argument to pro::DelegateToServer

Now, we need to trigger the assignment procedure myLoadResultsCallback when a solved case file is available on the server session. This is done by providing myLoadResultsCallback as the completionCallback argument.

if pro::GetPROEndPoint() then
   if pro::DelegateToServer(
      completionCallback :  'myLoadResultsCallback',
      waitForCompletion : 0 )
   then return 1;
   endif ;
endif ;

When the solve session is completed, the procedure myLoadResultsCallback is executed which will store the RequestID in spSavedRequestID and make a button visible in the UI by updating the value of bpResultsAvailable to 1.

Create a procedure to load the data

Create a procedure prLoadResults with the below body:

Procedure prLoadResults {
   Body: {
      spSavedRequestID := "";
      bpResultsAvailable := 0 ;

We are executing the predefined procedure pro::session::LoadResultsCallBack to load the case file on the data session, but with our own argument spSavedRequestID instead of the default argument. After the results are loaded, we also empty the spSavedRequestID and bpResultsAvailable to hide the load results button. This last emptying step is not necessary but it is a good practice to not show buttons that are not available anyway.

We want to control the visibility of BtnLoadResults because it makes sense for it to show up only when results are available to load. This appearance acts as a notification for the end user that results are available. The user interface when the results are available, but not yet downloaded looks as follows:


The AIMMS project that does just this, can be downloaded from: 5. Flow Shop - Load Results.


By following the above steps, the end user can control when the case file resulting from an execution on the server session is loaded onto the data session (or available to view by the end user).

Further Opportunities

By following the above steps, the end user can control when the case file resulting from an execution on the server session is loaded onto the data session (or available to view by the end user). Some examples of opportunities for further improvement are:

  1. End users may want to keep track of the progress of the solution process, especially the gap is interesting. In Use the Progress Window in WebUI we show how to do this.
  2. The contents of intermediate solutions can be interesting for the data session at hand. In Show Intermediate Solutions we show how to copy selected intermediate results from the server session to the data session.
  3. Once the solution is “good enough for now”, the end user may want to abort the server session. In Interrupt the Server Session we will show how to interrupt the server session.

Last Updated: February, 2020