0

I am making a CSP solver that calculates all the combinatory solutions of a specific problem like this (briefly put):

// Say we are in a Solver class
public void solve() {
  // find solution...
}

// This would be in a Problem class
problem.getSolver().solve();

There is a good chance that the resolution process takes a long time to finish, like more than a couple of minutes. So far, when it has been taking so long I have just stopped the process via console.

But eventually I am going to post my application as a web application in a host that allows Java apps (side-question: I have seen I can do it in Google Cloud and I have been told also about AWS; are they good options?). This means I, or the user, cannot terminate the process anymore if it takes too long.

I want to add the funcionality of having the option of cancelling the resolution process at will.

So I would declare a new method in the Solver class that would terminate the process, which would effectively stop the resolution process:

public void stopResolutionProcess() {
  // kill the process, therefore, stop the resolution process
}

I cannot just call problem.getSolver().stopResolutionProcess() after the resolution process has already started, because the thread is already running and until that process ends, that method call will never be executed.

So how could I do this? How could a client signal the service hosted in the cloud to terminate a running process?

dabadaba
  • 9,064
  • 21
  • 85
  • 155

2 Answers2

0

Since you haven't chosen a cloud host yet this question is really difficult to answer. Generally speaking you need a synchronization object. Something like

volatile boolean keepRunning = true;

and your method would do

public void stopResolutionProcess(){
    keepRunning = false;
}

then in your solve you have to regularly check for that variable

public void solve(){
   while(keepRunning){
       // doSomething();
       Thread.sleep(500);
   }
}

Now i use a variable here but that may not be sufficient. In App Engine your application could run in different instances where static variables are not synchronized. You would need a sync object that is accessible to all your solve threads. In App Engine that would be a datastore object that is also cached in the memcache. But you could use Pub/Sub or other mechanisms to propagate the completion of the task. The specifics are tightly coupled to the environment you'll choose to run this on.

Requests for product recommendations are generally off-topic on Stackoverflow. Choose a product for hosting and if you run into trouble return with a more concrete question.

konqi
  • 5,137
  • 3
  • 34
  • 52
  • This solution wouldn't work. The `solve` method is just calling the Choco method `solver.findSolution()`. It is the `findSolution()` method the one that potentially could take ages to finish. – dabadaba Apr 01 '16 at 09:01
  • As I said. This is more of a general problem and the example is really just a starting point of how you could achieve this in theory. It doesn't really matter where you check for the flag. In AppEngine you wouldn't use Threads at all, you would use Task Queues and check on a cached datastore value, so `keepRunning` would actually be a method that queries the datastore. – konqi Apr 01 '16 at 09:04
  • For thread-safety, make sure to mark the `keepRunning` flag as `volatile` – Adam Michalik Apr 01 '16 at 09:06
  • 1
    @AdamMichalik fine, i added the volatile. The App Engine approach would not use threads though so there wouldn't be the need for volatile. – konqi Apr 01 '16 at 09:09
0

Put the long running process in a different thread. You can stop it from the main thread if necessary. See:

How to stop a thread by another thread?

Community
  • 1
  • 1
stepanian
  • 11,373
  • 8
  • 43
  • 63