我计划使用 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
看起来像(打包到一个 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 执行脚本
在这可以通过返回预定的未来并等待它使用ScheduledExecutorService
没有 R 脚本完成执行的情况下从 R 脚本本身以固定延迟或固定速率运行(保持活动状态直到服务运行)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();
}
但是来自不同线程的访问受到限制
- 使用可运行脚本和 jar 构建本机映像
我想知道这些动机是否可能,如果可能的话,这样做的正确方法。