You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zeppelin.apache.org by mo...@apache.org on 2016/12/01 01:25:17 UTC

[5/7] zeppelin git commit: [ZEPPELIN-212] Multiple paragraph results

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
index 867b726..900d1ac 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventClient.java
@@ -19,6 +19,8 @@ package org.apache.zeppelin.interpreter.remote;
 import com.google.gson.Gson;
 import org.apache.zeppelin.display.AngularObject;
 import org.apache.zeppelin.interpreter.InterpreterContextRunner;
+import org.apache.zeppelin.interpreter.InterpreterResult;
+import org.apache.zeppelin.interpreter.InterpreterResultMessage;
 import org.apache.zeppelin.interpreter.RemoteZeppelinServerResource;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEvent;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEventType;
@@ -230,10 +232,12 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
     }
   }
 
-  public void onInterpreterOutputAppend(String noteId, String paragraphId, String output) {
+  public void onInterpreterOutputAppend(
+      String noteId, String paragraphId, int outputIndex, String output) {
     Map<String, String> appendOutput = new HashMap<>();
     appendOutput.put("noteId", noteId);
     appendOutput.put("paragraphId", paragraphId);
+    appendOutput.put("index", Integer.toString(outputIndex));
     appendOutput.put("data", output);
 
     sendEvent(new RemoteInterpreterEvent(
@@ -241,10 +245,14 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
         gson.toJson(appendOutput)));
   }
 
-  public void onInterpreterOutputUpdate(String noteId, String paragraphId, String output) {
+  public void onInterpreterOutputUpdate(
+      String noteId, String paragraphId, int outputIndex,
+      InterpreterResult.Type type, String output) {
     Map<String, String> appendOutput = new HashMap<>();
     appendOutput.put("noteId", noteId);
     appendOutput.put("paragraphId", paragraphId);
+    appendOutput.put("index", Integer.toString(outputIndex));
+    appendOutput.put("type", type.name());
     appendOutput.put("data", output);
 
     sendEvent(new RemoteInterpreterEvent(
@@ -252,6 +260,17 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
         gson.toJson(appendOutput)));
   }
 
+  public void onInterpreterOutputUpdateAll(
+      String noteId, String paragraphId, List<InterpreterResultMessage> messages) {
+    Map<String, Object> appendOutput = new HashMap<>();
+    appendOutput.put("noteId", noteId);
+    appendOutput.put("paragraphId", paragraphId);
+    appendOutput.put("messages", messages);
+
+    sendEvent(new RemoteInterpreterEvent(
+        RemoteInterpreterEventType.OUTPUT_UPDATE_ALL,
+        gson.toJson(appendOutput)));
+  }
 
   private void sendEvent(RemoteInterpreterEvent event) {
     synchronized (eventQueue) {
@@ -260,10 +279,12 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
     }
   }
 
-  public void onAppOutputAppend(String noteId, String paragraphId, String appId, String output) {
-    Map<String, String> appendOutput = new HashMap<>();
+  public void onAppOutputAppend(
+      String noteId, String paragraphId, int index, String appId, 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("data", output);
 
@@ -273,13 +294,17 @@ public class RemoteInterpreterEventClient implements ResourcePoolConnector {
   }
 
 
-  public void onAppOutputUpdate(String noteId, String paragraphId, String appId, String output) {
-    Map<String, String> appendOutput = new HashMap<>();
+  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)));

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
index 33cc8e4..bf64d9f 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterEventPoller.java
@@ -25,6 +25,7 @@ import org.apache.zeppelin.display.AngularObjectRegistry;
 import org.apache.zeppelin.helium.ApplicationEventListener;
 import org.apache.zeppelin.interpreter.InterpreterContextRunner;
 import org.apache.zeppelin.interpreter.InterpreterGroup;
+import org.apache.zeppelin.interpreter.InterpreterResult;
 import org.apache.zeppelin.interpreter.RemoteZeppelinServerResource;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEvent;
 import org.apache.zeppelin.interpreter.thrift.RemoteInterpreterEventType;
@@ -162,30 +163,56 @@ public class RemoteInterpreterEventPoller extends Thread {
         } else if (event.getType() == RemoteInterpreterEventType.OUTPUT_APPEND) {
           // on output append
           Map<String, String> outputAppend = gson.fromJson(
-                  event.getData(), new TypeToken<Map<String, String>>() {}.getType());
-          String noteId = outputAppend.get("noteId");
-          String paragraphId = outputAppend.get("paragraphId");
-          String outputToAppend = outputAppend.get("data");
-          String appId = outputAppend.get("appId");
+                  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"));
+          String outputToAppend = (String) outputAppend.get("data");
+
+          String appId = (String) outputAppend.get("appId");
 
           if (appId == null) {
-            runner.appendBuffer(noteId, paragraphId, outputToAppend);
+            runner.appendBuffer(noteId, paragraphId, index, outputToAppend);
           } else {
-            appListener.onOutputAppend(noteId, paragraphId, appId, outputToAppend);
+            appListener.onOutputAppend(noteId, paragraphId, index, appId, outputToAppend);
+          }
+        } else if (event.getType() == RemoteInterpreterEventType.OUTPUT_UPDATE_ALL) {
+          Map<String, Object> outputUpdate = gson.fromJson(
+              event.getData(), new TypeToken<Map<String, Object>>() {}.getType());
+          String noteId = (String) outputUpdate.get("noteId");
+          String paragraphId = (String) outputUpdate.get("paragraphId");
+
+          // clear the output
+          listener.onOutputClear(noteId, paragraphId);
+          List<Map<String, String>> messages =
+              (List<Map<String, String>>) outputUpdate.get("messages");
+
+          if (messages != null) {
+            for (int i = 0; i < messages.size(); i++) {
+              Map<String, String> m = messages.get(i);
+              InterpreterResult.Type type =
+                  InterpreterResult.Type.valueOf((String) m.get("type"));
+              String outputToUpdate = (String) m.get("data");
+
+              listener.onOutputUpdated(noteId, paragraphId, i, type, outputToUpdate);
+            }
           }
         } else if (event.getType() == RemoteInterpreterEventType.OUTPUT_UPDATE) {
           // on output update
           Map<String, String> outputAppend = gson.fromJson(
-              event.getData(), new TypeToken<Map<String, String>>() {}.getType());
-          String noteId = outputAppend.get("noteId");
-          String paragraphId = outputAppend.get("paragraphId");
-          String outputToUpdate = outputAppend.get("data");
-          String appId = outputAppend.get("appId");
+              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, outputToUpdate);
+            listener.onOutputUpdated(noteId, paragraphId, index, type, outputToUpdate);
           } else {
-            appListener.onOutputUpdated(noteId, paragraphId, appId, outputToUpdate);
+            appListener.onOutputUpdated(noteId, paragraphId, index, appId, type, outputToUpdate);
           }
         } else if (event.getType() == RemoteInterpreterEventType.APP_STATUS_UPDATE) {
           // on output update
@@ -213,7 +240,7 @@ public class RemoteInterpreterEventPoller extends Thread {
           String settingId = id.substring(0, indexOfColon);
           listener.onMetaInfosReceived(settingId, metaInfos);
         }
-        logger.debug("Event from remoteproceess {}", event.getType());
+        logger.debug("Event from remote process {}", event.getType());
       } catch (Exception e) {
         logger.error("Can't handle event " + event, e);
       }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
index 763e14c..66b08c9 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterProcessListener.java
@@ -16,14 +16,18 @@
  */
 package org.apache.zeppelin.interpreter.remote;
 
+import org.apache.zeppelin.interpreter.InterpreterResult;
+
 import java.util.Map;
 
 /**
  * Event from remoteInterpreterProcess
  */
 public interface RemoteInterpreterProcessListener {
-  public void onOutputAppend(String noteId, String paragraphId, String output);
-  public void onOutputUpdated(String noteId, String paragraphId, String output);
+  public void onOutputAppend(String noteId, String paragraphId, int index, String output);
+  public void onOutputUpdated(
+      String noteId, String paragraphId, int index, InterpreterResult.Type type, String output);
+  public void onOutputClear(String noteId, String paragraphId);
   public void onMetaInfosReceived(String settingId, Map<String, String> metaInfos);
   public void onRemoteRunParagraph(String noteId, String ParagraphID) throws Exception;
   public void onGetParagraphRunners(

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
index ca61145..de91f71 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/remote/RemoteInterpreterServer.java
@@ -489,35 +489,23 @@ public class RemoteInterpreterServer
         InterpreterResult result = interpreter.interpret(script, context);
 
         // data from context.out is prepended to InterpreterResult if both defined
-        String message = "";
-
         context.out.flush();
-        InterpreterResult.Type outputType = context.out.getType();
-        byte[] interpreterOutput = context.out.toByteArray();
-
-        if (interpreterOutput != null && interpreterOutput.length > 0) {
-          message = new String(interpreterOutput);
-        }
-
-        String interpreterResultMessage = result.message();
-
-        InterpreterResult combinedResult;
-        if (interpreterResultMessage != null && !interpreterResultMessage.isEmpty()) {
-          message += interpreterResultMessage;
-          combinedResult = new InterpreterResult(result.code(), result.type(), message);
-        } else {
-          combinedResult = new InterpreterResult(result.code(), outputType, message);
-        }
+        List<InterpreterResultMessage> resultMessages = context.out.toInterpreterResultMessage();
+        resultMessages.addAll(result.message());
 
         // put result into resource pool
-        if (combinedResult.type() == InterpreterResult.Type.TABLE) {
-          context.getResourcePool().put(
-              context.getNoteId(),
-              context.getParagraphId(),
-              WellKnownResourceName.ZeppelinTableResult.toString(),
-              combinedResult);
+        if (resultMessages.size() > 0) {
+          int lastMessageIndex = resultMessages.size() - 1;
+          if (resultMessages.get(lastMessageIndex).getType() ==
+              InterpreterResult.Type.TABLE) {
+            context.getResourcePool().put(
+                context.getNoteId(),
+                context.getParagraphId(),
+                WellKnownResourceName.ZeppelinTableResult.toString(),
+                resultMessages.get(lastMessageIndex));
+          }
         }
-        return combinedResult;
+        return new InterpreterResult(result.code(), resultMessages);
       } finally {
         InterpreterContext.remove();
       }
@@ -603,15 +591,34 @@ public class RemoteInterpreterServer
       paragraphId) {
     return new InterpreterOutput(new InterpreterOutputListener() {
       @Override
-      public void onAppend(InterpreterOutput out, byte[] line) {
-        logger.debug("Output Append:" + new String(line));
-        eventClient.onInterpreterOutputAppend(noteId, paragraphId, new String(line));
+      public void onUpdateAll(InterpreterOutput out) {
+        try {
+          eventClient.onInterpreterOutputUpdateAll(
+              noteId, paragraphId, out.toInterpreterResultMessage());
+        } catch (IOException e) {
+          logger.error(e.getMessage(), e);
+        }
+      }
+
+      @Override
+      public void onAppend(int index, InterpreterResultMessageOutput out, byte[] line) {
+        String output = new String(line);
+        logger.debug("Output Append: {}", output);
+        eventClient.onInterpreterOutputAppend(
+            noteId, paragraphId, index, output);
       }
 
       @Override
-      public void onUpdate(InterpreterOutput out, byte[] output) {
-        logger.debug("Output Update:" + new String(output));
-        eventClient.onInterpreterOutputUpdate(noteId, paragraphId, new String(output));
+      public void onUpdate(int index, InterpreterResultMessageOutput out) {
+        String output;
+        try {
+          output = new String(out.toByteArray());
+          logger.debug("Output Update: {}", output);
+          eventClient.onInterpreterOutputUpdate(
+              noteId, paragraphId, index, out.getType(), output);
+        } catch (IOException e) {
+          logger.error(e.getMessage(), e);
+        }
       }
     });
   }
@@ -706,10 +713,17 @@ public class RemoteInterpreterServer
 
   private RemoteInterpreterResult convert(InterpreterResult result,
       Map<String, Object> config, GUI gui) {
+
+    List<RemoteInterpreterResultMessage> msg = new LinkedList<>();
+    for (InterpreterResultMessage m : result.message()) {
+      msg.add(new RemoteInterpreterResultMessage(
+          m.getType().name(),
+          m.getData()));
+    }
+
     return new RemoteInterpreterResult(
         result.code().name(),
-        result.type().name(),
-        result.message(),
+        msg,
         gson.toJson(config),
         gson.toJson(gui));
   }
@@ -948,15 +962,26 @@ public class RemoteInterpreterServer
                                             final String appId) {
     return new InterpreterOutput(new InterpreterOutputListener() {
       @Override
-      public void onAppend(InterpreterOutput out, byte[] line) {
-        eventClient.onAppOutputAppend(noteId, paragraphId, appId, new String(line));
+      public void onUpdateAll(InterpreterOutput out) {
+
+      }
+
+      @Override
+      public void onAppend(int index, InterpreterResultMessageOutput out, byte[] line) {
+        eventClient.onAppOutputAppend(noteId, paragraphId, index, appId, new String(line));
       }
 
       @Override
-      public void onUpdate(InterpreterOutput out, byte[] output) {
-        eventClient.onAppOutputUpdate(noteId, paragraphId, appId, new String(output));
+      public void onUpdate(int index, InterpreterResultMessageOutput out) {
+        try {
+          eventClient.onAppOutputUpdate(noteId, paragraphId, index, appId,
+              out.getType(), new String(out.toByteArray()));
+        } catch (IOException e) {
+          logger.error(e.getMessage(), e);
+        }
       }
     });
+
   }
 
   private ApplicationContext getApplicationContext(
@@ -1040,20 +1065,20 @@ public class RemoteInterpreterServer
           System.err.println("Resource " + res.get());
         }
         runningApp.app.run(resource);
-        String output = new String(context.out.toByteArray());
+        context.out.flush();
+        InterpreterResultMessageOutput out = context.out.getOutputAt(0);
         eventClient.onAppOutputUpdate(
             context.getNoteId(),
             context.getParagraphId(),
+            0,
             applicationInstanceId,
-            output);
+            out.getType(),
+            new String(out.toByteArray()));
         return new RemoteApplicationResult(true, "");
       } catch (ApplicationException | IOException e) {
         return new RemoteApplicationResult(false, e.getMessage());
       }
     }
-
-
-
   }
 
   private static class RunningApplication {

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
index 2514cb0..2d1c165 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/InterpreterCompletion.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-25")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-29")
 public class InterpreterCompletion implements org.apache.thrift.TBase<InterpreterCompletion, InterpreterCompletion._Fields>, java.io.Serializable, Cloneable, Comparable<InterpreterCompletion> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("InterpreterCompletion");
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
index 3d9aae5..5c73049 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteApplicationResult.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-25")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-29")
 public class RemoteApplicationResult implements org.apache.thrift.TBase<RemoteApplicationResult, RemoteApplicationResult._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteApplicationResult> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteApplicationResult");
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
index eb7c2a0..e721cb3 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterContext.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-25")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-29")
 public class RemoteInterpreterContext implements org.apache.thrift.TBase<RemoteInterpreterContext, RemoteInterpreterContext._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterContext> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterContext");
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
index 9ff5a34..5f4201a 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEvent.java
@@ -51,7 +51,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-25")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-29")
 public class RemoteInterpreterEvent implements org.apache.thrift.TBase<RemoteInterpreterEvent, RemoteInterpreterEvent._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterEvent> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterEvent");
 

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventType.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventType.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventType.java
index 13f1236..fc20cd9 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventType.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterEventType.java
@@ -38,10 +38,11 @@ public enum RemoteInterpreterEventType implements org.apache.thrift.TEnum {
   RESOURCE_GET(7),
   OUTPUT_APPEND(8),
   OUTPUT_UPDATE(9),
-  ANGULAR_REGISTRY_PUSH(10),
-  APP_STATUS_UPDATE(11),
-  META_INFOS(12),
-  REMOTE_ZEPPELIN_SERVER_RESOURCE(13);
+  OUTPUT_UPDATE_ALL(10),
+  ANGULAR_REGISTRY_PUSH(11),
+  APP_STATUS_UPDATE(12),
+  META_INFOS(13),
+  REMOTE_ZEPPELIN_SERVER_RESOURCE(14);
 
   private final int value;
 
@@ -81,12 +82,14 @@ public enum RemoteInterpreterEventType implements org.apache.thrift.TEnum {
       case 9:
         return OUTPUT_UPDATE;
       case 10:
-        return ANGULAR_REGISTRY_PUSH;
+        return OUTPUT_UPDATE_ALL;
       case 11:
-        return APP_STATUS_UPDATE;
+        return ANGULAR_REGISTRY_PUSH;
       case 12:
-        return META_INFOS;
+        return APP_STATUS_UPDATE;
       case 13:
+        return META_INFOS;
+      case 14:
         return REMOTE_ZEPPELIN_SERVER_RESOURCE;
       default:
         return null;

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
index 1a20f39..ce15084 100644
--- a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResult.java
@@ -51,15 +51,14 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
-@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-25")
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-29")
 public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteInterpreterResult, RemoteInterpreterResult._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResult> {
   private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResult");
 
   private static final org.apache.thrift.protocol.TField CODE_FIELD_DESC = new org.apache.thrift.protocol.TField("code", org.apache.thrift.protocol.TType.STRING, (short)1);
-  private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.STRING, (short)2);
-  private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.STRING, (short)3);
-  private static final org.apache.thrift.protocol.TField CONFIG_FIELD_DESC = new org.apache.thrift.protocol.TField("config", org.apache.thrift.protocol.TType.STRING, (short)4);
-  private static final org.apache.thrift.protocol.TField GUI_FIELD_DESC = new org.apache.thrift.protocol.TField("gui", org.apache.thrift.protocol.TType.STRING, (short)5);
+  private static final org.apache.thrift.protocol.TField MSG_FIELD_DESC = new org.apache.thrift.protocol.TField("msg", org.apache.thrift.protocol.TType.LIST, (short)2);
+  private static final org.apache.thrift.protocol.TField CONFIG_FIELD_DESC = new org.apache.thrift.protocol.TField("config", org.apache.thrift.protocol.TType.STRING, (short)3);
+  private static final org.apache.thrift.protocol.TField GUI_FIELD_DESC = new org.apache.thrift.protocol.TField("gui", org.apache.thrift.protocol.TType.STRING, (short)4);
 
   private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
   static {
@@ -68,18 +67,16 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
   }
 
   public String code; // required
-  public String type; // required
-  public String msg; // required
+  public List<RemoteInterpreterResultMessage> msg; // required
   public String config; // required
   public String gui; // required
 
   /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
   public enum _Fields implements org.apache.thrift.TFieldIdEnum {
     CODE((short)1, "code"),
-    TYPE((short)2, "type"),
-    MSG((short)3, "msg"),
-    CONFIG((short)4, "config"),
-    GUI((short)5, "gui");
+    MSG((short)2, "msg"),
+    CONFIG((short)3, "config"),
+    GUI((short)4, "gui");
 
     private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
 
@@ -96,13 +93,11 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
       switch(fieldId) {
         case 1: // CODE
           return CODE;
-        case 2: // TYPE
-          return TYPE;
-        case 3: // MSG
+        case 2: // MSG
           return MSG;
-        case 4: // CONFIG
+        case 3: // CONFIG
           return CONFIG;
-        case 5: // GUI
+        case 4: // GUI
           return GUI;
         default:
           return null;
@@ -149,10 +144,9 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
     tmpMap.put(_Fields.CODE, new org.apache.thrift.meta_data.FieldMetaData("code", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
-    tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     tmpMap.put(_Fields.MSG, new org.apache.thrift.meta_data.FieldMetaData("msg", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, RemoteInterpreterResultMessage.class))));
     tmpMap.put(_Fields.CONFIG, new org.apache.thrift.meta_data.FieldMetaData("config", org.apache.thrift.TFieldRequirementType.DEFAULT, 
         new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
     tmpMap.put(_Fields.GUI, new org.apache.thrift.meta_data.FieldMetaData("gui", org.apache.thrift.TFieldRequirementType.DEFAULT, 
@@ -166,14 +160,12 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
 
   public RemoteInterpreterResult(
     String code,
-    String type,
-    String msg,
+    List<RemoteInterpreterResultMessage> msg,
     String config,
     String gui)
   {
     this();
     this.code = code;
-    this.type = type;
     this.msg = msg;
     this.config = config;
     this.gui = gui;
@@ -186,11 +178,12 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     if (other.isSetCode()) {
       this.code = other.code;
     }
-    if (other.isSetType()) {
-      this.type = other.type;
-    }
     if (other.isSetMsg()) {
-      this.msg = other.msg;
+      List<RemoteInterpreterResultMessage> __this__msg = new ArrayList<RemoteInterpreterResultMessage>(other.msg.size());
+      for (RemoteInterpreterResultMessage other_element : other.msg) {
+        __this__msg.add(new RemoteInterpreterResultMessage(other_element));
+      }
+      this.msg = __this__msg;
     }
     if (other.isSetConfig()) {
       this.config = other.config;
@@ -207,7 +200,6 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
   @Override
   public void clear() {
     this.code = null;
-    this.type = null;
     this.msg = null;
     this.config = null;
     this.gui = null;
@@ -237,35 +229,26 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     }
   }
 
-  public String getType() {
-    return this.type;
+  public int getMsgSize() {
+    return (this.msg == null) ? 0 : this.msg.size();
   }
 
-  public RemoteInterpreterResult setType(String type) {
-    this.type = type;
-    return this;
-  }
-
-  public void unsetType() {
-    this.type = null;
+  public java.util.Iterator<RemoteInterpreterResultMessage> getMsgIterator() {
+    return (this.msg == null) ? null : this.msg.iterator();
   }
 
-  /** Returns true if field type is set (has been assigned a value) and false otherwise */
-  public boolean isSetType() {
-    return this.type != null;
-  }
-
-  public void setTypeIsSet(boolean value) {
-    if (!value) {
-      this.type = null;
+  public void addToMsg(RemoteInterpreterResultMessage elem) {
+    if (this.msg == null) {
+      this.msg = new ArrayList<RemoteInterpreterResultMessage>();
     }
+    this.msg.add(elem);
   }
 
-  public String getMsg() {
+  public List<RemoteInterpreterResultMessage> getMsg() {
     return this.msg;
   }
 
-  public RemoteInterpreterResult setMsg(String msg) {
+  public RemoteInterpreterResult setMsg(List<RemoteInterpreterResultMessage> msg) {
     this.msg = msg;
     return this;
   }
@@ -343,19 +326,11 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
       }
       break;
 
-    case TYPE:
-      if (value == null) {
-        unsetType();
-      } else {
-        setType((String)value);
-      }
-      break;
-
     case MSG:
       if (value == null) {
         unsetMsg();
       } else {
-        setMsg((String)value);
+        setMsg((List<RemoteInterpreterResultMessage>)value);
       }
       break;
 
@@ -383,9 +358,6 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     case CODE:
       return getCode();
 
-    case TYPE:
-      return getType();
-
     case MSG:
       return getMsg();
 
@@ -408,8 +380,6 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     switch (field) {
     case CODE:
       return isSetCode();
-    case TYPE:
-      return isSetType();
     case MSG:
       return isSetMsg();
     case CONFIG:
@@ -442,15 +412,6 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
         return false;
     }
 
-    boolean this_present_type = true && this.isSetType();
-    boolean that_present_type = true && that.isSetType();
-    if (this_present_type || that_present_type) {
-      if (!(this_present_type && that_present_type))
-        return false;
-      if (!this.type.equals(that.type))
-        return false;
-    }
-
     boolean this_present_msg = true && this.isSetMsg();
     boolean that_present_msg = true && that.isSetMsg();
     if (this_present_msg || that_present_msg) {
@@ -490,11 +451,6 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     if (present_code)
       list.add(code);
 
-    boolean present_type = true && (isSetType());
-    list.add(present_type);
-    if (present_type)
-      list.add(type);
-
     boolean present_msg = true && (isSetMsg());
     list.add(present_msg);
     if (present_msg)
@@ -531,16 +487,6 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
         return lastComparison;
       }
     }
-    lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType());
-    if (lastComparison != 0) {
-      return lastComparison;
-    }
-    if (isSetType()) {
-      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type);
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-    }
     lastComparison = Boolean.valueOf(isSetMsg()).compareTo(other.isSetMsg());
     if (lastComparison != 0) {
       return lastComparison;
@@ -599,14 +545,6 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     }
     first = false;
     if (!first) sb.append(", ");
-    sb.append("type:");
-    if (this.type == null) {
-      sb.append("null");
-    } else {
-      sb.append(this.type);
-    }
-    first = false;
-    if (!first) sb.append(", ");
     sb.append("msg:");
     if (this.msg == null) {
       sb.append("null");
@@ -681,23 +619,26 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
             }
             break;
-          case 2: // TYPE
-            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
-              struct.type = iprot.readString();
-              struct.setTypeIsSet(true);
-            } else { 
-              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
-            }
-            break;
-          case 3: // MSG
-            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
-              struct.msg = iprot.readString();
+          case 2: // MSG
+            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
+              {
+                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
+                struct.msg = new ArrayList<RemoteInterpreterResultMessage>(_list0.size);
+                RemoteInterpreterResultMessage _elem1;
+                for (int _i2 = 0; _i2 < _list0.size; ++_i2)
+                {
+                  _elem1 = new RemoteInterpreterResultMessage();
+                  _elem1.read(iprot);
+                  struct.msg.add(_elem1);
+                }
+                iprot.readListEnd();
+              }
               struct.setMsgIsSet(true);
             } else { 
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
             }
             break;
-          case 4: // CONFIG
+          case 3: // CONFIG
             if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
               struct.config = iprot.readString();
               struct.setConfigIsSet(true);
@@ -705,7 +646,7 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
               org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
             }
             break;
-          case 5: // GUI
+          case 4: // GUI
             if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
               struct.gui = iprot.readString();
               struct.setGuiIsSet(true);
@@ -733,14 +674,16 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
         oprot.writeString(struct.code);
         oprot.writeFieldEnd();
       }
-      if (struct.type != null) {
-        oprot.writeFieldBegin(TYPE_FIELD_DESC);
-        oprot.writeString(struct.type);
-        oprot.writeFieldEnd();
-      }
       if (struct.msg != null) {
         oprot.writeFieldBegin(MSG_FIELD_DESC);
-        oprot.writeString(struct.msg);
+        {
+          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.msg.size()));
+          for (RemoteInterpreterResultMessage _iter3 : struct.msg)
+          {
+            _iter3.write(oprot);
+          }
+          oprot.writeListEnd();
+        }
         oprot.writeFieldEnd();
       }
       if (struct.config != null) {
@@ -774,27 +717,27 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
       if (struct.isSetCode()) {
         optionals.set(0);
       }
-      if (struct.isSetType()) {
-        optionals.set(1);
-      }
       if (struct.isSetMsg()) {
-        optionals.set(2);
+        optionals.set(1);
       }
       if (struct.isSetConfig()) {
-        optionals.set(3);
+        optionals.set(2);
       }
       if (struct.isSetGui()) {
-        optionals.set(4);
+        optionals.set(3);
       }
-      oprot.writeBitSet(optionals, 5);
+      oprot.writeBitSet(optionals, 4);
       if (struct.isSetCode()) {
         oprot.writeString(struct.code);
       }
-      if (struct.isSetType()) {
-        oprot.writeString(struct.type);
-      }
       if (struct.isSetMsg()) {
-        oprot.writeString(struct.msg);
+        {
+          oprot.writeI32(struct.msg.size());
+          for (RemoteInterpreterResultMessage _iter4 : struct.msg)
+          {
+            _iter4.write(oprot);
+          }
+        }
       }
       if (struct.isSetConfig()) {
         oprot.writeString(struct.config);
@@ -807,24 +750,30 @@ public class RemoteInterpreterResult implements org.apache.thrift.TBase<RemoteIn
     @Override
     public void read(org.apache.thrift.protocol.TProtocol prot, RemoteInterpreterResult struct) throws org.apache.thrift.TException {
       TTupleProtocol iprot = (TTupleProtocol) prot;
-      BitSet incoming = iprot.readBitSet(5);
+      BitSet incoming = iprot.readBitSet(4);
       if (incoming.get(0)) {
         struct.code = iprot.readString();
         struct.setCodeIsSet(true);
       }
       if (incoming.get(1)) {
-        struct.type = iprot.readString();
-        struct.setTypeIsSet(true);
-      }
-      if (incoming.get(2)) {
-        struct.msg = iprot.readString();
+        {
+          org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+          struct.msg = new ArrayList<RemoteInterpreterResultMessage>(_list5.size);
+          RemoteInterpreterResultMessage _elem6;
+          for (int _i7 = 0; _i7 < _list5.size; ++_i7)
+          {
+            _elem6 = new RemoteInterpreterResultMessage();
+            _elem6.read(iprot);
+            struct.msg.add(_elem6);
+          }
+        }
         struct.setMsgIsSet(true);
       }
-      if (incoming.get(3)) {
+      if (incoming.get(2)) {
         struct.config = iprot.readString();
         struct.setConfigIsSet(true);
       }
-      if (incoming.get(4)) {
+      if (incoming.get(3)) {
         struct.gui = iprot.readString();
         struct.setGuiIsSet(true);
       }

http://git-wip-us.apache.org/repos/asf/zeppelin/blob/850fd81a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
----------------------------------------------------------------------
diff --git a/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
new file mode 100644
index 0000000..c55c72e
--- /dev/null
+++ b/zeppelin-interpreter/src/main/java/org/apache/zeppelin/interpreter/thrift/RemoteInterpreterResultMessage.java
@@ -0,0 +1,520 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * Autogenerated by Thrift Compiler (0.9.2)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ *  @generated
+ */
+package org.apache.zeppelin.interpreter.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.TException;
+import org.apache.thrift.async.AsyncMethodCallback;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
+@Generated(value = "Autogenerated by Thrift Compiler (0.9.2)", date = "2016-11-29")
+public class RemoteInterpreterResultMessage implements org.apache.thrift.TBase<RemoteInterpreterResultMessage, RemoteInterpreterResultMessage._Fields>, java.io.Serializable, Cloneable, Comparable<RemoteInterpreterResultMessage> {
+  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("RemoteInterpreterResultMessage");
+
+  private static final org.apache.thrift.protocol.TField TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("type", org.apache.thrift.protocol.TType.STRING, (short)1);
+  private static final org.apache.thrift.protocol.TField DATA_FIELD_DESC = new org.apache.thrift.protocol.TField("data", org.apache.thrift.protocol.TType.STRING, (short)2);
+
+  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+  static {
+    schemes.put(StandardScheme.class, new RemoteInterpreterResultMessageStandardSchemeFactory());
+    schemes.put(TupleScheme.class, new RemoteInterpreterResultMessageTupleSchemeFactory());
+  }
+
+  public String type; // required
+  public String data; // required
+
+  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+    TYPE((short)1, "type"),
+    DATA((short)2, "data");
+
+    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+    static {
+      for (_Fields field : EnumSet.allOf(_Fields.class)) {
+        byName.put(field.getFieldName(), field);
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, or null if its not found.
+     */
+    public static _Fields findByThriftId(int fieldId) {
+      switch(fieldId) {
+        case 1: // TYPE
+          return TYPE;
+        case 2: // DATA
+          return DATA;
+        default:
+          return null;
+      }
+    }
+
+    /**
+     * Find the _Fields constant that matches fieldId, throwing an exception
+     * if it is not found.
+     */
+    public static _Fields findByThriftIdOrThrow(int fieldId) {
+      _Fields fields = findByThriftId(fieldId);
+      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+      return fields;
+    }
+
+    /**
+     * Find the _Fields constant that matches name, or null if its not found.
+     */
+    public static _Fields findByName(String name) {
+      return byName.get(name);
+    }
+
+    private final short _thriftId;
+    private final String _fieldName;
+
+    _Fields(short thriftId, String fieldName) {
+      _thriftId = thriftId;
+      _fieldName = fieldName;
+    }
+
+    public short getThriftFieldId() {
+      return _thriftId;
+    }
+
+    public String getFieldName() {
+      return _fieldName;
+    }
+  }
+
+  // isset id assignments
+  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+  static {
+    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+    tmpMap.put(_Fields.TYPE, new org.apache.thrift.meta_data.FieldMetaData("type", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    tmpMap.put(_Fields.DATA, new org.apache.thrift.meta_data.FieldMetaData("data", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+    metaDataMap = Collections.unmodifiableMap(tmpMap);
+    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(RemoteInterpreterResultMessage.class, metaDataMap);
+  }
+
+  public RemoteInterpreterResultMessage() {
+  }
+
+  public RemoteInterpreterResultMessage(
+    String type,
+    String data)
+  {
+    this();
+    this.type = type;
+    this.data = data;
+  }
+
+  /**
+   * Performs a deep copy on <i>other</i>.
+   */
+  public RemoteInterpreterResultMessage(RemoteInterpreterResultMessage other) {
+    if (other.isSetType()) {
+      this.type = other.type;
+    }
+    if (other.isSetData()) {
+      this.data = other.data;
+    }
+  }
+
+  public RemoteInterpreterResultMessage deepCopy() {
+    return new RemoteInterpreterResultMessage(this);
+  }
+
+  @Override
+  public void clear() {
+    this.type = null;
+    this.data = null;
+  }
+
+  public String getType() {
+    return this.type;
+  }
+
+  public RemoteInterpreterResultMessage setType(String type) {
+    this.type = type;
+    return this;
+  }
+
+  public void unsetType() {
+    this.type = null;
+  }
+
+  /** Returns true if field type is set (has been assigned a value) and false otherwise */
+  public boolean isSetType() {
+    return this.type != null;
+  }
+
+  public void setTypeIsSet(boolean value) {
+    if (!value) {
+      this.type = null;
+    }
+  }
+
+  public String getData() {
+    return this.data;
+  }
+
+  public RemoteInterpreterResultMessage setData(String data) {
+    this.data = data;
+    return this;
+  }
+
+  public void unsetData() {
+    this.data = null;
+  }
+
+  /** Returns true if field data is set (has been assigned a value) and false otherwise */
+  public boolean isSetData() {
+    return this.data != null;
+  }
+
+  public void setDataIsSet(boolean value) {
+    if (!value) {
+      this.data = null;
+    }
+  }
+
+  public void setFieldValue(_Fields field, Object value) {
+    switch (field) {
+    case TYPE:
+      if (value == null) {
+        unsetType();
+      } else {
+        setType((String)value);
+      }
+      break;
+
+    case DATA:
+      if (value == null) {
+        unsetData();
+      } else {
+        setData((String)value);
+      }
+      break;
+
+    }
+  }
+
+  public Object getFieldValue(_Fields field) {
+    switch (field) {
+    case TYPE:
+      return getType();
+
+    case DATA:
+      return getData();
+
+    }
+    throw new IllegalStateException();
+  }
+
+  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+  public boolean isSet(_Fields field) {
+    if (field == null) {
+      throw new IllegalArgumentException();
+    }
+
+    switch (field) {
+    case TYPE:
+      return isSetType();
+    case DATA:
+      return isSetData();
+    }
+    throw new IllegalStateException();
+  }
+
+  @Override
+  public boolean equals(Object that) {
+    if (that == null)
+      return false;
+    if (that instanceof RemoteInterpreterResultMessage)
+      return this.equals((RemoteInterpreterResultMessage)that);
+    return false;
+  }
+
+  public boolean equals(RemoteInterpreterResultMessage that) {
+    if (that == null)
+      return false;
+
+    boolean this_present_type = true && this.isSetType();
+    boolean that_present_type = true && that.isSetType();
+    if (this_present_type || that_present_type) {
+      if (!(this_present_type && that_present_type))
+        return false;
+      if (!this.type.equals(that.type))
+        return false;
+    }
+
+    boolean this_present_data = true && this.isSetData();
+    boolean that_present_data = true && that.isSetData();
+    if (this_present_data || that_present_data) {
+      if (!(this_present_data && that_present_data))
+        return false;
+      if (!this.data.equals(that.data))
+        return false;
+    }
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    List<Object> list = new ArrayList<Object>();
+
+    boolean present_type = true && (isSetType());
+    list.add(present_type);
+    if (present_type)
+      list.add(type);
+
+    boolean present_data = true && (isSetData());
+    list.add(present_data);
+    if (present_data)
+      list.add(data);
+
+    return list.hashCode();
+  }
+
+  @Override
+  public int compareTo(RemoteInterpreterResultMessage other) {
+    if (!getClass().equals(other.getClass())) {
+      return getClass().getName().compareTo(other.getClass().getName());
+    }
+
+    int lastComparison = 0;
+
+    lastComparison = Boolean.valueOf(isSetType()).compareTo(other.isSetType());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetType()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.type, other.type);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    lastComparison = Boolean.valueOf(isSetData()).compareTo(other.isSetData());
+    if (lastComparison != 0) {
+      return lastComparison;
+    }
+    if (isSetData()) {
+      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.data, other.data);
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+    }
+    return 0;
+  }
+
+  public _Fields fieldForId(int fieldId) {
+    return _Fields.findByThriftId(fieldId);
+  }
+
+  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+  }
+
+  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder sb = new StringBuilder("RemoteInterpreterResultMessage(");
+    boolean first = true;
+
+    sb.append("type:");
+    if (this.type == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.type);
+    }
+    first = false;
+    if (!first) sb.append(", ");
+    sb.append("data:");
+    if (this.data == null) {
+      sb.append("null");
+    } else {
+      sb.append(this.data);
+    }
+    first = false;
+    sb.append(")");
+    return sb.toString();
+  }
+
+  public void validate() throws org.apache.thrift.TException {
+    // check for required fields
+    // check for sub-struct validity
+  }
+
+  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+    try {
+      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+    try {
+      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+    } catch (org.apache.thrift.TException te) {
+      throw new java.io.IOException(te);
+    }
+  }
+
+  private static class RemoteInterpreterResultMessageStandardSchemeFactory implements SchemeFactory {
+    public RemoteInterpreterResultMessageStandardScheme getScheme() {
+      return new RemoteInterpreterResultMessageStandardScheme();
+    }
+  }
+
+  private static class RemoteInterpreterResultMessageStandardScheme extends StandardScheme<RemoteInterpreterResultMessage> {
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot, RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+      org.apache.thrift.protocol.TField schemeField;
+      iprot.readStructBegin();
+      while (true)
+      {
+        schemeField = iprot.readFieldBegin();
+        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+          break;
+        }
+        switch (schemeField.id) {
+          case 1: // TYPE
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.type = iprot.readString();
+              struct.setTypeIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          case 2: // DATA
+            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+              struct.data = iprot.readString();
+              struct.setDataIsSet(true);
+            } else { 
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+            }
+            break;
+          default:
+            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+        }
+        iprot.readFieldEnd();
+      }
+      iprot.readStructEnd();
+
+      // check for required fields of primitive type, which can't be checked in the validate method
+      struct.validate();
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot, RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+      struct.validate();
+
+      oprot.writeStructBegin(STRUCT_DESC);
+      if (struct.type != null) {
+        oprot.writeFieldBegin(TYPE_FIELD_DESC);
+        oprot.writeString(struct.type);
+        oprot.writeFieldEnd();
+      }
+      if (struct.data != null) {
+        oprot.writeFieldBegin(DATA_FIELD_DESC);
+        oprot.writeString(struct.data);
+        oprot.writeFieldEnd();
+      }
+      oprot.writeFieldStop();
+      oprot.writeStructEnd();
+    }
+
+  }
+
+  private static class RemoteInterpreterResultMessageTupleSchemeFactory implements SchemeFactory {
+    public RemoteInterpreterResultMessageTupleScheme getScheme() {
+      return new RemoteInterpreterResultMessageTupleScheme();
+    }
+  }
+
+  private static class RemoteInterpreterResultMessageTupleScheme extends TupleScheme<RemoteInterpreterResultMessage> {
+
+    @Override
+    public void write(org.apache.thrift.protocol.TProtocol prot, RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+      TTupleProtocol oprot = (TTupleProtocol) prot;
+      BitSet optionals = new BitSet();
+      if (struct.isSetType()) {
+        optionals.set(0);
+      }
+      if (struct.isSetData()) {
+        optionals.set(1);
+      }
+      oprot.writeBitSet(optionals, 2);
+      if (struct.isSetType()) {
+        oprot.writeString(struct.type);
+      }
+      if (struct.isSetData()) {
+        oprot.writeString(struct.data);
+      }
+    }
+
+    @Override
+    public void read(org.apache.thrift.protocol.TProtocol prot, RemoteInterpreterResultMessage struct) throws org.apache.thrift.TException {
+      TTupleProtocol iprot = (TTupleProtocol) prot;
+      BitSet incoming = iprot.readBitSet(2);
+      if (incoming.get(0)) {
+        struct.type = iprot.readString();
+        struct.setTypeIsSet(true);
+      }
+      if (incoming.get(1)) {
+        struct.data = iprot.readString();
+        struct.setDataIsSet(true);
+      }
+    }
+  }
+
+}
+