示例#1
0
 protected void reconnect() {
   if (retries <= 0) {
     Flog.log("Giving up!");
     context.shutdown();
     return;
   }
   delay = Math.min(10000, Math.round((float) 1.5 * delay));
   Flog.log("Connection lost. Reconnecting in %sms", delay);
   context.setTimeout(
       delay,
       new Runnable() {
         @Override
         public void run() {
           Flog.log("Attempting to reconnect.");
           connect();
         }
       });
 }
  public void send_patch(String current) {

    String before_md5;
    String textPatch;
    String after_md5;

    String previous = buf;
    before_md5 = md5;
    after_md5 = DigestUtils.md5Hex(current);
    LinkedList<diff_match_patch.Patch> patches = dmp.patch_make(previous, current);
    textPatch = dmp.patch_toText(patches);

    set(current, after_md5);
    if (before_md5.equals(after_md5)) {
      Flog.log("Not patching %s because no change.", path);
      return;
    }
    outbound.patch(textPatch, before_md5, this);
  }
示例#3
0
 @Override
 public void channelUnregistered(final ChannelHandlerContext ctx) {
   Flog.log("Disconnected from %s", ctx.channel().remoteAddress());
   reconnect();
 }
示例#4
0
 @Override
 public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
   Flog.log("Channel is now inactive.");
 }
示例#5
0
 @Override
 public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
   Flog.log("%s", evt.toString());
 }
示例#6
0
 @Override
 public void channelActive(ChannelHandlerContext ctx) throws Exception {
   Flog.log("Connected to %s", ctx.channel().remoteAddress());
   handler.on_connect();
 }
  public void patch(final FlooPatch res) {
    final TextBuf b = this;
    Flog.info("Got _on_patch");

    String text;
    String md5FromDoc;
    final Document d;

    String oldText = buf;
    VirtualFile virtualFile = b.getVirtualFile();
    if (virtualFile == null) {
      Flog.warn("VirtualFile is null, no idea what do do. Aborting everything %s", this);
      getBuf();
      return;
    }
    d = Buf.getDocumentForVirtualFile(virtualFile);
    if (d == null) {
      Flog.warn("Document not found for %s", virtualFile);
      getBuf();
      return;
    }
    String viewText;
    if (virtualFile.exists()) {
      viewText = d.getText();
      if (viewText.equals(oldText)) {
        b.forced_patch = false;
      } else if (!b.forced_patch) {
        b.forced_patch = true;
        oldText = viewText;
        b.send_patch(viewText);
        Flog.warn("Sending force patch for %s. this is dangerous!", b.path);
      }
    } else {
      viewText = oldText;
    }

    b.cancelTimeout();

    String md5Before = DigestUtils.md5Hex(viewText);
    if (!md5Before.equals(res.md5_before)) {
      Flog.warn("starting md5s don't match for %s. this is dangerous!", b.path);
    }

    List<diff_match_patch.Patch> patches = dmp.patch_fromText(res.patch);
    final Object[] results = dmp.patch_apply((LinkedList<diff_match_patch.Patch>) patches, oldText);
    final String patchedContents = (String) results[0];
    final boolean[] patchesClean = (boolean[]) results[1];
    final FlooPatchPosition[] positions = (FlooPatchPosition[]) results[2];

    for (boolean clean : patchesClean) {
      if (!clean) {
        Flog.log("Patch not clean for %s. Sending get_buf and setting readonly.", d);
        getBuf();
        return;
      }
    }
    // XXX: If patchedContents have carriage returns this will be a problem:
    String md5After = DigestUtils.md5Hex(patchedContents);
    if (!md5After.equals(res.md5_after)) {
      Flog.info("MD5 after mismatch (ours %s remote %s)", md5After, res.md5_after);
    }

    if (!d.isWritable()) {
      d.setReadOnly(false);
    }
    if (!ReadonlyStatusHandler.ensureDocumentWritable(context.project, d)) {
      Flog.info("Document: %s is not writable.", d);
      return;
    }

    final Editor[] editors = EditorFactory.getInstance().getEditors(d, context.project);
    final HashMap<ScrollingModel, Integer[]> original = new HashMap<ScrollingModel, Integer[]>();
    for (Editor editor : editors) {
      if (editor.isDisposed()) {
        continue;
      }
      ScrollingModel scrollingModel = editor.getScrollingModel();
      original.put(
          scrollingModel,
          new Integer[] {
            scrollingModel.getHorizontalScrollOffset(), scrollingModel.getVerticalScrollOffset()
          });
    }
    for (FlooPatchPosition flooPatchPosition : positions) {
      int start = Math.max(0, flooPatchPosition.start);
      int end_ld = Math.max(start + flooPatchPosition.end, start);
      end_ld = Math.min(end_ld, d.getTextLength());
      String contents = NEW_LINE.matcher(flooPatchPosition.text).replaceAll("\n");
      Throwable e = null;
      try {
        Listener.flooDisable();
        d.replaceString(start, end_ld, contents);
      } catch (Throwable exception) {
        e = exception;
      } finally {
        Listener.flooEnable();
      }

      if (e != null) {
        Flog.warn(e);
        getBuf();
        return;
      }
    }
    text = d.getText();
    md5FromDoc = DigestUtils.md5Hex(text);
    if (!md5FromDoc.equals(res.md5_after)) {
      Flog.info("md5FromDoc mismatch (ours %s remote %s)", md5FromDoc, res.md5_after);
      b.setGetBufTimeout();
    }

    for (Map.Entry<ScrollingModel, Integer[]> entry : original.entrySet()) {
      ScrollingModel model = entry.getKey();
      Integer[] offsets = entry.getValue();
      model.scrollHorizontally(offsets[0]);
      model.scrollVertically(offsets[1]);
    }

    b.set(text, md5FromDoc);
    Flog.log("Patched %s", res.path);
  }