Rserve服务器:如何终止阻塞实例(永久评估)? [英] Rserve server: how to terminate a blocking instance (eval taking forever)?

查看:182
本文介绍了Rserve服务器:如何终止阻塞实例(永久评估)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要以多线程方式执行R eval,这正是Rserve提供的功能. 但是,如果一个实例的评估花费的时间太长,我需要能够关闭正在计算阻塞评估的实例.据我测试,给定实例将拒绝关闭,直到完成评估(显然,它需要获取结果,然后再次侦听).所以这是我的问题:

I need to perform R evals in a multi-threaded way, which is something Rserve provides quite well. But, if the eval of one instance takes too long, I need to be able to shutdown the instance which is computing the blocking eval. As far as I tested, the given instance will refuse to shutdown until the eval is done (apparently, it needs to fetch the result, before listening again). So here is my question:

是否有办法在阻塞实例(类似于Process对象)上获取java句柄,以便我可以强行杀死/终止评估(类似于process.destroy()这样的对象)? 换句话说,当我要求一个eval(创建连接,抛出命令)时,如何通过java在正在处理的eval和与其相关的Rsere实例之间建立关系?

Is there a way get a java handle on the blocking instance (something like a Process object), such that I can brute force kill/terminate the eval (something like process.destroy())? In other words, when I ask for an eval (create a connection, throw a command), how do I establish a relationship between the eval being processed, and the instance of Rsere related to it, via java?

还是我错过了有关Rserve的一些知识,已经可以满足这种需求了?

Or did I miss something about Rserve which already allows to deal with this kind of needs?

注意:我已经尝试通过serverEval()而不是常规的eval来运行所有内容(所有评估),后者在主实例上运行计算,但这当然是,不满意,因为它仅使用一个过程(主要过程).我可以杀死那个对象,但是我的主要目标是能够分别关闭在单个实例上运行的阻塞性评估.当然,请保留我的8个CPU内核的优势,也就是说,保留并行性.否则就没有必要使用Rserve(在这种情况下,JRI引擎绰绰有余).

Note: I already tried to run everything (all evals) via serverEval() instead of the regular eval, which runs the computations on the main instance, but this is, of course, not satisfying as it uses only one process (the main one). That one I can kill, but my main goal was to be able to shutdown individually a blocking eval, running on an individual instance. And, naturally, keep advantage of my 8 CPU cores, that is to say, preserve the parallelism. There is no point to use Rserve otherwise (JRI engine would be more than sufficient in this case).

注意::我想避免这种情况(

Note: I would like to avoid this kind of things (thread), dealing with several instances of the main server itself, on different ports. That is not an option.

我已经尝试在Rserve的邮件列表中获取信息,但是没有得到答复. 我希望我已经足够清楚地在这里得到答案或有用的评论.如果没有,请询​​问详细信息.提前非常感谢.

I already tried getting information on Rserve's mailing list, but haven't been answered. I hope I made myself clear enough to get an answer or helpful comment here. If not, please ask for details. Thanks so much by advance.

修改:我还测试了 RCaller ,具有一个R实例的需求,但是,由于它正在将结果写入XML文件以便以后从Java端进行解析(不像Rserve那样真正使用通信协议),因此对于我必须执行的操作来说太慢了.

I also tested RCaller, which deals with as many instances of R one need, but, as it is writing results into XML files for later parsing from java side (not really using a communication protocol as Rserve would), it is far too slow for what I have to perform...

推荐答案

好的,这可以通过这种方式完成(从某个好人那里抓到,他终于在Rserve devel邮件列表上回答了我):

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

在运行eval的线程中,该线程应该阻塞或时间太长,并假设已启动Rserve:

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...");

允许跟踪与所述eval有关的实例的pid(R privides Sys.getpid()).

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

然后停止/中止/取消,由于简单的this.rEngine.close()不会停止正在服务器端处理的任务,而只是关闭连接,因此我们需要终止目标Rserve实例.可以通过调用tools::pskill()(或其他任何系统调用,例如,可能是kill -9 my_pid(UNIX *),TASKKILL /PID my_pid /F(Windows),...,具体取决于平台)来完成此操作,显然是从上述线程以外的线程进行的(正在等待评估部分"返回):

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.

希望这会有所帮助.

这篇关于Rserve服务器:如何终止阻塞实例(永久评估)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆