TestAppBackend — correct termination (dispose project/app)
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Tue, 6 Jan 2015 00:09:11 +0000 (01:09 +0100)
committerVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Tue, 6 Jan 2015 00:11:47 +0000 (01:11 +0100)
call setResult on detach if nio used (otherwise inifnite JS debug process closing)

platform/script-debugger/backend/src/org/jetbrains/concurrency/CountDownConsumer.java
platform/script-debugger/backend/src/org/jetbrains/concurrency/Promise.java
platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/connection/BrowserConnection.java
platform/script-debugger/debugger-ui/src/org/jetbrains/debugger/connection/VmConnection.java
platform/script-debugger/debugger-ui/testSrc/org/jetbrains/debugger/TestCompositeNode.java
platform/script-debugger/debugger-ui/testSrc/org/jetbrains/debugger/TestValueNode.java

index deed0153c4bf76d9b4dfff32dd6c35b81877ec1e..6baecd16cb03245956260a9b02570d7d7a3e604c 100644 (file)
@@ -2,20 +2,23 @@ package org.jetbrains.concurrency;
 
 import com.intellij.util.Consumer;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
-class CountDownConsumer implements Consumer<Void> {
+class CountDownConsumer<T> implements Consumer<T> {
   private volatile int countDown;
-  private final AsyncPromise<Void> promise;
+  private final AsyncPromise<T> promise;
+  private final T totalResult;
 
-  public CountDownConsumer(int countDown, @NotNull AsyncPromise<Void> promise) {
+  public CountDownConsumer(int countDown, @NotNull AsyncPromise<T> promise, @Nullable T totalResult) {
     this.countDown = countDown;
     this.promise = promise;
+    this.totalResult = totalResult;
   }
 
   @Override
-  public void consume(Void t) {
+  public void consume(T t) {
     if (--countDown == 0) {
-      promise.setResult(null);
+      promise.setResult(totalResult);
     }
   }
 }
\ No newline at end of file
index 1e1485ecbf8814e9ec162a9374d438cb80eb35d2..c68d45780c0608e6eb282ca092b2731222ccd850 100644 (file)
@@ -51,12 +51,18 @@ public abstract class Promise<T> {
 
   @NotNull
   public static Promise<Void> all(@NotNull Collection<Promise<?>> promises) {
+    return all(promises, null);
+  }
+
+  @NotNull
+  public static <T> Promise<T> all(@NotNull Collection<Promise<?>> promises, @Nullable T totalResult) {
     if (promises.isEmpty()) {
-      return DONE;
+      //noinspection unchecked
+      return (Promise<T>)DONE;
     }
 
-    final AsyncPromise<Void> totalPromise = new AsyncPromise<Void>();
-    Consumer done = new CountDownConsumer(promises.size(), totalPromise);
+    final AsyncPromise<T> totalPromise = new AsyncPromise<T>();
+    Consumer done = new CountDownConsumer<T>(promises.size(), totalPromise, totalResult);
     Consumer<Throwable> rejected = new Consumer<Throwable>() {
       @Override
       public void consume(Throwable error) {
index 71eb20571a35601a614e183222d1adff3c3726b6..352138ddfd7b05058417be9072a3fab9a93e8b11 100644 (file)
@@ -1,7 +1,6 @@
 package org.jetbrains.debugger.connection;
 
 import com.intellij.ide.browsers.WebBrowser;
-import com.intellij.openapi.Disposable;
 import com.intellij.util.io.socketConnection.ConnectionState;
 import com.intellij.util.io.socketConnection.SocketConnectionListener;
 import org.jetbrains.annotations.NotNull;
@@ -11,7 +10,7 @@ public interface BrowserConnection {
   @NotNull
   ConnectionState getState();
 
-  void addListener(@NotNull SocketConnectionListener listener, @NotNull Disposable parentDisposable);
+  void addListener(@NotNull SocketConnectionListener listener);
 
   void executeOnStart(@NotNull Runnable runnable);
 
index 9a1b105bd9f8498c3a13786926e472578e07e5a8..9f9debf07bee7a26e48a2377efabe58d433c634d 100644 (file)
@@ -73,8 +73,8 @@ public abstract class VmConnection<T extends Vm> implements Disposable, BrowserC
   }
 
   @Override
-  public void addListener(@NotNull SocketConnectionListener listener, @NotNull Disposable parentDisposable) {
-    connectionDispatcher.addListener(listener, parentDisposable);
+  public void addListener(@NotNull SocketConnectionListener listener) {
+    connectionDispatcher.addListener(listener);
   }
 
   public DebugEventListener getDebugEventListener() {
@@ -90,7 +90,9 @@ public abstract class VmConnection<T extends Vm> implements Disposable, BrowserC
       return;
     }
 
-    opened.setError(Promise.createError("closed"));
+    if (opened.getState() == Promise.State.PENDING) {
+      opened.setError(Promise.createError("closed"));
+    }
     setState(status, message);
     Disposer.dispose(this, false);
   }
@@ -102,7 +104,9 @@ public abstract class VmConnection<T extends Vm> implements Disposable, BrowserC
 
   @NotNull
   public Promise<Void> detachAndClose() {
-    opened.setError(Promise.createError("detached and closed"));
+    if (opened.getState() == Promise.State.PENDING) {
+      opened.setError(Promise.createError("detached and closed"));
+    }
 
     Vm currentVm = vm;
     Promise<Void> callback;
index 8824dcefa4ac89b189644d7a3d007fa3feebe545..5690136f82a7ee921d598f4b095f18fdcbe8a3a0 100644 (file)
@@ -1,21 +1,22 @@
 package org.jetbrains.debugger;
 
-import com.intellij.openapi.util.ActionCallback;
-import com.intellij.openapi.util.AsyncResult;
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Conditions;
 import com.intellij.ui.SimpleTextAttributes;
-import com.intellij.util.Consumer;
 import com.intellij.xdebugger.frame.*;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.concurrency.AsyncFunction;
+import org.jetbrains.concurrency.AsyncPromise;
+import org.jetbrains.concurrency.Promise;
 import org.jetbrains.debugger.values.ObjectValue;
 
 import javax.swing.*;
+import java.util.ArrayList;
 import java.util.List;
 
 public class TestCompositeNode implements XCompositeNode {
-  private final AsyncResult<XValueChildrenList> result = new AsyncResult<XValueChildrenList>();
+  private final AsyncPromise<XValueChildrenList> result = new AsyncPromise<XValueChildrenList>();
   private final XValueChildrenList children = new XValueChildrenList();
 
   private final XValueGroup valueGroup;
@@ -47,13 +48,13 @@ public class TestCompositeNode implements XCompositeNode {
     }
 
     if (last) {
-      result.setDone(this.children);
+      result.setResult(this.children);
     }
   }
 
   @Override
   public void tooManyChildren(int remaining) {
-    result.setDone(children);
+    result.setResult(children);
   }
 
   @Override
@@ -62,7 +63,7 @@ public class TestCompositeNode implements XCompositeNode {
 
   @Override
   public void setErrorMessage(@NotNull String errorMessage) {
-    result.reject(errorMessage);
+    result.setError(Promise.createError(errorMessage));
   }
 
   @Override
@@ -80,21 +81,35 @@ public class TestCompositeNode implements XCompositeNode {
   }
 
   @NotNull
-  public AsyncResult<XValueChildrenList> getResult() {
+  public Promise<XValueChildrenList> getResult() {
     return result;
   }
 
   @NotNull
-  public AsyncResult<Content> loadContent(@NotNull final Condition<XValueGroup> groupContentResolveCondition, @NotNull final Condition<VariableView> valueSubContentResolveCondition) {
+  public Promise<Content> loadContent(@NotNull final Condition<XValueGroup> groupContentResolveCondition, @NotNull final Condition<VariableView> valueSubContentResolveCondition) {
     assert content == null;
 
-    final AsyncResult<Content> compoundResult = new AsyncResult<Content>();
     content = new Content();
-    result.doWhenDone(new Consumer<XValueChildrenList>() {
+    return result.then(new AsyncFunction<XValueChildrenList, Content>() {
+      private void resolveGroups(@NotNull List<XValueGroup> valueGroups, @NotNull List<TestCompositeNode> resultNodes, @NotNull List<Promise<?>> promises) {
+        for (XValueGroup group : valueGroups) {
+          TestCompositeNode node = new TestCompositeNode(group);
+          boolean computeChildren = groupContentResolveCondition.value(group);
+          if (computeChildren) {
+            group.computeChildren(node);
+          }
+          resultNodes.add(node);
+          if (computeChildren) {
+            promises.add(node.loadContent(Conditions.<XValueGroup>alwaysFalse(), valueSubContentResolveCondition));
+          }
+        }
+      }
+
+      @NotNull
       @Override
-      public void consume(XValueChildrenList children) {
-        ActionCallback.Chunk chunk = new ActionCallback.Chunk();
-        resolveGroups(children.getTopGroups(), content.topGroups, chunk);
+      public Promise<Content> fun(XValueChildrenList list) {
+        List<Promise<?>> promises = new ArrayList<Promise<?>>();
+        resolveGroups(children.getTopGroups(), content.topGroups, promises);
 
         for (int i = 0; i < children.size(); i++) {
           XValue value = children.getValue(i);
@@ -102,38 +117,18 @@ public class TestCompositeNode implements XCompositeNode {
           node.myName = children.getName(i);
           value.computePresentation(node, XValuePlace.TREE);
           content.values.add(node);
-          chunk.add(node.getResult());
+          promises.add(node.getResult());
 
           // myHasChildren could be not computed yet
           if (value instanceof VariableView && ((VariableView)value).getValue() instanceof ObjectValue && valueSubContentResolveCondition.value((VariableView)value)) {
-            chunk.add(node.loadChildren(value));
+            promises.add(node.loadChildren(value));
           }
         }
 
-        resolveGroups(children.getBottomGroups(), content.bottomGroups, chunk);
+        resolveGroups(children.getBottomGroups(), content.bottomGroups, promises);
 
-        chunk.create().doWhenDone(new Runnable() {
-          @Override
-          public void run() {
-            compoundResult.setDone(content);
-          }
-        }).notifyWhenRejected(compoundResult);
-      }
-
-      private void resolveGroups(@NotNull List<XValueGroup> valueGroups, @NotNull List<TestCompositeNode> resultNodes, @NotNull ActionCallback.Chunk chunk) {
-        for (XValueGroup group : valueGroups) {
-          TestCompositeNode node = new TestCompositeNode(group);
-          boolean computeChildren = groupContentResolveCondition.value(group);
-          if (computeChildren) {
-            group.computeChildren(node);
-          }
-          resultNodes.add(node);
-          if (computeChildren) {
-            chunk.add(node.loadContent(Conditions.<XValueGroup>alwaysFalse(), valueSubContentResolveCondition));
-          }
-        }
+        return Promise.all(promises, content);
       }
-    }).notifyWhenRejected(compoundResult);
-    return compoundResult;
+    });
   }
 }
\ No newline at end of file
index 37cbcd91664098ee47bc3b26b1440c11c5e52592..5b6885ebac4ed89b98300c9fd2edd68fd864df26 100644 (file)
@@ -1,6 +1,5 @@
 package org.jetbrains.debugger;
 
-import com.intellij.openapi.util.AsyncResult;
 import com.intellij.openapi.util.Conditions;
 import com.intellij.util.Consumer;
 import com.intellij.xdebugger.XTestValueNode;
@@ -9,29 +8,32 @@ import com.intellij.xdebugger.frame.XValueGroup;
 import com.intellij.xdebugger.frame.presentation.XValuePresentation;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
+import org.jetbrains.concurrency.AsyncPromise;
+import org.jetbrains.concurrency.Promise;
 
 import javax.swing.*;
 
 public class TestValueNode extends XTestValueNode {
-  private final AsyncResult<XTestValueNode> result = new AsyncResult<XTestValueNode>();
+  private final AsyncPromise<XTestValueNode> result = new AsyncPromise<XTestValueNode>();
 
   private volatile Content children;
 
   @NotNull
-  public AsyncResult<XTestValueNode> getResult() {
+  public Promise<XTestValueNode> getResult() {
     return result;
   }
 
   @NotNull
-  public AsyncResult<Content> loadChildren(@NotNull XValue value) {
+  public Promise<Content> loadChildren(@NotNull XValue value) {
     TestCompositeNode childrenNode = new TestCompositeNode();
     value.computeChildren(childrenNode);
-    return childrenNode.loadContent(Conditions.<XValueGroup>alwaysFalse(), Conditions.<VariableView>alwaysFalse()).doWhenDone(new Consumer<Content>() {
-      @Override
-      public void consume(Content content) {
-        children = content;
-      }
-    });
+    return childrenNode.loadContent(Conditions.<XValueGroup>alwaysFalse(), Conditions.<VariableView>alwaysFalse())
+      .done(new Consumer<Content>() {
+        @Override
+        public void consume(Content content) {
+          children = content;
+        }
+      });
   }
 
   @Nullable
@@ -43,6 +45,6 @@ public class TestValueNode extends XTestValueNode {
   public void applyPresentation(@Nullable Icon icon, @NotNull XValuePresentation valuePresentation, boolean hasChildren) {
     super.applyPresentation(icon, valuePresentation, hasChildren);
 
-    result.setDone(this);
+    result.setResult(this);
   }
 }
\ No newline at end of file