Troubleshoot Unresponsive Applications
Executing a pro::DelegateToServer
from a WinUI AIMMS app launched from a distant AIMMS PRO server may fail due to various causes.
In this article, we discuss one potential cause for an app not responding for more than a minute after the DelegateToServer
call - an unstable internet connection. Wireless connections are more likely to be unstable compared to wired connections.
If this behavior is occurring frequently in your applications, you can use the Error Handling functionality offered in AIMMS to mitigate the situation.
Example
The example app executes a procedure on the PRO Server upon pressing the button.
A button is pressed
The action associated with the button is executing the procedure
pr_ButtonComputation
.This procedure will call another procedure
pr_DelegateComputation
that will handle the delegation to an AIMMS PRO server. This is the procedure with thepro::DelegateToServer
call.Finally, the procedure that contains the actual computation
pr_Computation
is called. This is a very trivial procedure in this example but usually contains asolve
statement.
Procedure pr_Computation {
Body: {
pi := 3.14159265359 ;
}
}
We will now explain bottom up the procedure calls:
The Delegate Procedure
The code for the procedure that delegates work to the server is as follows in this example. More elaborate examples can be found in other articles in the category Deployment.
1Procedure pr_DelegateComputation {
2 Body: {
3 !delay( 5 );
4 !raise error "oops, timed out again, sigh." ;
5
6 if pro::DelegateToServer(
7 waitForCompletion:1,
8 completionCallback: 'pro::session::LoadResultsCallback' ) then
9 return ;
10 endif ;
11
12 ! Do the actual work.
13 pr_Computation();
14 }
15}
Lines 3,4: Uncommenting these lines will cause an error. These are added to test
pr_ButtonComputation
as discussed in the next section.Lines 6-10: A typical
pro::DelegateToServer
call.
Troubleshoot Procedure
The real meat of this article is in the pr_ButtonComputation
procedure where we allow the user to recover from an error.
1Procedure pr_ButtonComputation {
2 Body: {
3 p01_DelegateCompleted := 0 ;
4 while not p01_DelegateCompleted do
5 sp_msg := "" ;
6
7 block
8 ! Happy flow here.
9 pr_DelegateComputation();
10
11 ! Mark task as completed.
12 p01_DelegateCompleted := 1 ;
13
14 onerror ep_err do
15
16 ! Error handling here.
17 p01_errorHandled := 0 ;
18 sp_msg := errh::Message(ep_err);
19 if StringOccurrences(sp_msg, "timed out") then
20
21 ! On timed out, provide user with the opportunity to retry.
22 p_ret := DialogAsk(
23 message : sp_msg,
24 button1 : "Retry",
25 button2 : "Cancel",
26 title : "Press Retry, if you want to retry the solve, cancel if you want to handle the issue otherwise");
27 if p_ret = 1 then
28 ! Retry button pressed by user.
29 errh::MarkAsHandled(ep_err);
30 p01_errorHandled := 1;
31 ! Note, p01_DelegateCompleted is still 0, so the
32 ! while loop will re-iterate and
33 ! pr_DelegateComputation() will be called again.
34 endif ;
35 endif ;
36 endblock ;
37 if sp_msg and ( p01_errorHandled = 0 ) then
38 break ; ! Error (perhaps intentionally) not handled by user.
39 endif ;
40 endwhile ;
41 }
42 ElementParameter ep_err {
43 Range: errh::PendingErrors;
44 }
45 StringParameter sp_msg;
46 Parameter p_ret;
47 Parameter p01_DelegateCompleted {
48 Range: binary;
49 }
50 Parameter p01_errorHandled {
51 Range: binary;
52 }
53}
Line 9: The happy flow. When this fails due to a “timed out” condition, an error is raised (see previous procedure).
Lines 18, 19: We retrieve the message and check for the “timed out” condition.
lines 22 - 33: We give the user the opportunity to retry.
The 01 parameters are auxiliary parameters created to ensure the flow of the troubleshoot procedure.