Rserve server: how to terminate a blocking instance (eval taking forever)?

≯℡__Kan透↙ 提交于 2019-12-04 05:31:10

OK, this can be done this way (caught it from some nice person who finally answered me on Rserve devel mailing list):

In the thread running the eval supposed to be blocking or too long, and assuming Rserve is started:

private RConnection rEngine = null;
private int rServePid = -1;

//...

// Keep an opened instance and store the related pid
RConnection rconn = new RConnection();
this.rServePid = rconn.eval("Sys.getpid()").asInteger();
this.rEngine = rconn;
LOG.info("Rserve: started instance with pid '" + this.rServePid + "'.");
//...
this.rEngine.eval("some consuming code...");

Which allows to keep track of the pid of the instance related to the said eval (R privides Sys.getpid()).

Then to stop / abort / cancel and since a simple this.rEngine.close() will not stop the task being processed on server side, but only close the connection, we need to kill the targeted Rserve instance. This can be done by calling tools::pskill() (or any other system call like possibly kill -9 my_pid (UNIX*), TASKKILL /PID my_pid /F (Windows), ..., depending on the platform), obviously from another thread than the one above (which is waiting for the "eval part" to return):

// Terminate.
RConnection c2 = new RConnection();
// SIGTERM might not be understood everywhere: so using SIGKILL signal, as well.
c2.eval("tools::pskill("+ this.rServePid + ")");
c2.eval("tools::pskill("+ this.rServePid + ", tools::SIGKILL)");
c2.close();
LOG.info("Rserve: terminated instance with pid '" + this.rServePid + "'.");

That one has the benefit to be plateform independent.

Hope this can help.

How about

rcon.eval("system(\"echo $$\", intern = TRUE)");

It will return pid of running Rserve (not the main) and then you can kill it by using this pid.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!