Zeppelin源码分析-独立解释器 JVM 相关分析(1)

来源:互联网 发布:镇江网络广播电视 编辑:程序博客网 时间:2024/06/06 00:32

Zeppelin 是将所有的消息都封装在 RemoteInterpreterEvent 类中,它在 thirft 协议文件中定义如下,其中有一个数据类型字段和数据字段:

struct RemoteInterpreterEvent {  1: RemoteInterpreterEventType type,  2: string data      // json serialized data}

RemoteInterpreterEventClient

这个类的对象存在于在每个独立的 JVM 线程中,最重要的作用就是维护了一个 RemoteInterpreterEvent 队列,用于存放该 JVM 中需要传送给主进程的所有消息:

private final List<RemoteInterpreterEvent> eventQueue = new LinkedList<>();

因此这个类中也有好多提供给外界的往自身队列中添加消息的方法,比如以下代码,其中 sendEvent 方法就是向自身的队列中添加消息:

public void onAppOutputUpdate(    String noteId, String paragraphId, int index, String appId,    InterpreterResult.Type type, String output) {  Map<String, Object> appendOutput = new HashMap<>();  appendOutput.put("noteId", noteId);  appendOutput.put("paragraphId", paragraphId);  appendOutput.put("index", Integer.toString(index));  appendOutput.put("appId", appId);  appendOutput.put("type", type);  appendOutput.put("data", output);  logger.info("onAppoutputUpdate = {}", output);  sendEvent(new RemoteInterpreterEvent(      RemoteInterpreterEventType.OUTPUT_UPDATE,      gson.toJson(appendOutput)));}

另外它也是 ResourcePoolConnector 的子类,用于获取资源和读取资源。

RemoteInterpreterEventPoller

这个类是主进程中的一个线程,用于拉取解释器 JVM 中的消息,并回调 NotebookServer 类或者其他类中相应方法,比如下面的代码就是从解释器 JVM 中拉去消息并发现消息类型是 OUTPUT_UPDATE 时,调用 listener 的相应方法,其中 listener 的类型是 RemoteInterpreterProcessListener ,运行时实际类型其实是 NotebookServer ( appListener 暂时不用看,暂时用不到):

if (event.getType() == RemoteInterpreterEventType.OUTPUT_UPDATE) {  // on output update  Map<String, String> outputAppend = gson.fromJson(      event.getData(), new TypeToken<Map<String, Object>>() {}.getType());  String noteId = (String) outputAppend.get("noteId");  String paragraphId = (String) outputAppend.get("paragraphId");  int index = Integer.parseInt(outputAppend.get("index"));  InterpreterResult.Type type =      InterpreterResult.Type.valueOf((String) outputAppend.get("type"));  String outputToUpdate = (String) outputAppend.get("data");  String appId = (String) outputAppend.get("appId");  if (appId == null) {    listener.onOutputUpdated(noteId, paragraphId, index, type, outputToUpdate);  } else {    appListener.onOutputUpdated(noteId, paragraphId, index, appId, type, outputToUpdate);  }}

但是这个类中也并不是全部是从解释器 JVM 中拉取消息,也有一些方法是向解释器发送消息,比如 sendResourcePoolResponseGetAll 方法和 sendResourceResponseGet 方法。
另外该类中使用一个定时任务每隔 AppendOutputRunner.BUFFER_TIME_MS 向前台推送 ParaGraph 的 Append 信息:

private final ScheduledExecutorService appendService =      Executors.newSingleThreadScheduledExecutor();AppendOutputRunner runner = new AppendOutputRunner(listener);ScheduledFuture<?> appendFuture = appendService.scheduleWithFixedDelay(    runner, 0, AppendOutputRunner.BUFFER_TIME_MS, TimeUnit.MILLISECONDS);

ScheduleThreadPoolExecutor 的工作原理与使用示例请自行百度。

原创粉丝点击