安排固定延迟执行器时防止 R 脚本完成
Prevent R script from finishing when scheduling fixed delay executor
我计划使用 FastR 实现编写一个 R 脚本,看起来像
java.addToClasspath("build/libs/polyglot-example-f.jar")
clientClass <- java.type('org.algo.polyglot.JavaClient')
javaClient <- new(clientClass, threadPoolSize=10)
javaClient$startScheduleWithFixedDelay(5)
org.algo.polyglot.JavaClient
class的样子(打包成jar):
package org.algo.polyglot;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.graalvm.polyglot.HostAccess;
import java.text.MessageFormat;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.graalvm.polyglot.HostAccess.Export;
public class JavaClient {
private final ScheduledExecutorService service;
@Export
public JavaClient(int threadPoolSize) {
this.service = Executors.newScheduledThreadPool(threadPoolSize);
}
@Export
public void startScheduleWithFixedDelay(int delayInSeconds) {
service.scheduleWithFixedDelay(
() -> {
postMessage(fetchMessage());
},
0,
delayInSeconds,
TimeUnit.SECONDS
);
}
@Export
public void startScheduleWithFixedRate(int period) {
service.scheduleAtFixedRate(
() -> {},
0,
period,
TimeUnit.SECONDS
);
}
@Export
public PolyglotMessage fetchMessage() {
return new PolyglotMessage(
RandomStringUtils.randomAlphabetic(10, 15),
RandomStringUtils.randomAlphabetic(10, 15),
System.currentTimeMillis()
);
}
@Export
public void postMessage(PolyglotMessage message) {
System.out.println("[Printed from JavaClient] Posting message: " + message.toString());
}
}
当 运行 将脚本与 Rscript sample.R --polyglot
连接时,脚本完成执行并输出:
$ Rscript sample.R --polyglot
NULL
我有这些动机:
- R 脚本应该是入口点,因为我的用例要求我利用 R
中的 java 功能
- 运行 带有提供的 jar 的 R 脚本
- 使用 Rscript 执行脚本
从 R 脚本本身获取 ScheduledExecutorService
运行 固定延迟或固定速率,而无需 R 脚本完成执行(保持活动直到服务 运行ning) 这可以通过返回预定的未来并使用 ScheduledFuture$get()
等待来解决。对脚本和代码所做的更改是:
future <- javaClient$startScheduleWithFixedDelay(5)
future$get()
@Export
public ScheduledFuture<?> startScheduleWithFixedDelay(int delayInSeconds) {
return service.scheduleWithFixedDelay(
() -> {
postMessage(fetchMessage());
},
0,
delayInSeconds,
TimeUnit.SECONDS
);
}
- 将函数从 R 脚本传递给执行器,以便 ScheduledExecutorService 相应地调用该函数(可以将 R 函数传递给 java 代码中的 运行,接收者将是功能接口,示例:)
myFunc <- function() {
# do some stuff
}
javaClient$runProvidedFunction(myFunc)
@Export
public void runProvidedFunction(Runnable runnable) {
runnable.run();
}
但是不同线程的访问受到限制
- 使用 运行nable 脚本和 jar 构建本机映像
我想知道这些动机是否可能,如果可能,正确的方法。
Run the R script with the provided jar
看来是你自己想出来的。您可以使用 java.addToClasspath
或在 --vm.cp=...
开始 R/Rscript 时应该能够添加到 class 路径。这两个选项仅在 JVM 模式下有效。
Execute the script with Rscript
再说一遍,你好像明白了?
Pass a function to the executor from the R script so that the function is called accordingly by the ScheduledExecutorService
这很棘手。 R 是单线程语言,FastR 也是。您不能从多个线程执行 R 代码,但您可以做的是创建多个 FastR 上下文并在每个线程中使用一个新上下文(您可以为此使用 ThreadLocal)。参见 https://www.graalvm.org/reference-manual/embed-languages。您应该能够使用从 R 调用的 Java 代码中的上下文 API 并创建新的上下文。
Build a native image with the runnable script and jar
应该没问题。请注意,某些 R 包和本机映像存在一些我们尚未修复的已知问题。
入口点必须是某个 Java 使用上下文 API 启动 FastR 的应用程序。您可以将 R 脚本作为字符串或资源嵌入到 Java 应用程序中。请注意,不会提前编译 R 代码。它仍将在运行时进行 JIT 编译,但其他所有内容都将提前编译:您的 Java 代码、您使用的任何 Java 库、FastR 解释器和运行时。
我计划使用 FastR 实现编写一个 R 脚本,看起来像
java.addToClasspath("build/libs/polyglot-example-f.jar")
clientClass <- java.type('org.algo.polyglot.JavaClient')
javaClient <- new(clientClass, threadPoolSize=10)
javaClient$startScheduleWithFixedDelay(5)
org.algo.polyglot.JavaClient
class的样子(打包成jar):
package org.algo.polyglot;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.RandomUtils;
import org.graalvm.polyglot.HostAccess;
import java.text.MessageFormat;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import org.graalvm.polyglot.HostAccess.Export;
public class JavaClient {
private final ScheduledExecutorService service;
@Export
public JavaClient(int threadPoolSize) {
this.service = Executors.newScheduledThreadPool(threadPoolSize);
}
@Export
public void startScheduleWithFixedDelay(int delayInSeconds) {
service.scheduleWithFixedDelay(
() -> {
postMessage(fetchMessage());
},
0,
delayInSeconds,
TimeUnit.SECONDS
);
}
@Export
public void startScheduleWithFixedRate(int period) {
service.scheduleAtFixedRate(
() -> {},
0,
period,
TimeUnit.SECONDS
);
}
@Export
public PolyglotMessage fetchMessage() {
return new PolyglotMessage(
RandomStringUtils.randomAlphabetic(10, 15),
RandomStringUtils.randomAlphabetic(10, 15),
System.currentTimeMillis()
);
}
@Export
public void postMessage(PolyglotMessage message) {
System.out.println("[Printed from JavaClient] Posting message: " + message.toString());
}
}
当 运行 将脚本与 Rscript sample.R --polyglot
连接时,脚本完成执行并输出:
$ Rscript sample.R --polyglot
NULL
我有这些动机:
- R 脚本应该是入口点,因为我的用例要求我利用 R 中的 java 功能
- 运行 带有提供的 jar 的 R 脚本
- 使用 Rscript 执行脚本
从 R 脚本本身获取这可以通过返回预定的未来并使用ScheduledExecutorService
运行 固定延迟或固定速率,而无需 R 脚本完成执行(保持活动直到服务 运行ning)ScheduledFuture$get()
等待来解决。对脚本和代码所做的更改是:
future <- javaClient$startScheduleWithFixedDelay(5)
future$get()
@Export
public ScheduledFuture<?> startScheduleWithFixedDelay(int delayInSeconds) {
return service.scheduleWithFixedDelay(
() -> {
postMessage(fetchMessage());
},
0,
delayInSeconds,
TimeUnit.SECONDS
);
}
- 将函数从 R 脚本传递给执行器,以便 ScheduledExecutorService 相应地调用该函数(可以将 R 函数传递给 java 代码中的 运行,接收者将是功能接口,示例:)
myFunc <- function() {
# do some stuff
}
javaClient$runProvidedFunction(myFunc)
@Export
public void runProvidedFunction(Runnable runnable) {
runnable.run();
}
但是不同线程的访问受到限制
- 使用 运行nable 脚本和 jar 构建本机映像
我想知道这些动机是否可能,如果可能,正确的方法。
Run the R script with the provided jar
看来是你自己想出来的。您可以使用 java.addToClasspath
或在 --vm.cp=...
开始 R/Rscript 时应该能够添加到 class 路径。这两个选项仅在 JVM 模式下有效。
Execute the script with Rscript
再说一遍,你好像明白了?
Pass a function to the executor from the R script so that the function is called accordingly by the ScheduledExecutorService
这很棘手。 R 是单线程语言,FastR 也是。您不能从多个线程执行 R 代码,但您可以做的是创建多个 FastR 上下文并在每个线程中使用一个新上下文(您可以为此使用 ThreadLocal)。参见 https://www.graalvm.org/reference-manual/embed-languages。您应该能够使用从 R 调用的 Java 代码中的上下文 API 并创建新的上下文。
Build a native image with the runnable script and jar
应该没问题。请注意,某些 R 包和本机映像存在一些我们尚未修复的已知问题。
入口点必须是某个 Java 使用上下文 API 启动 FastR 的应用程序。您可以将 R 脚本作为字符串或资源嵌入到 Java 应用程序中。请注意,不会提前编译 R 代码。它仍将在运行时进行 JIT 编译,但其他所有内容都将提前编译:您的 Java 代码、您使用的任何 Java 库、FastR 解释器和运行时。