Promise.cancel() API instead of low-level OBSOLETE_ERROR

This commit is contained in:
Vladimir Krivosheev
2016-07-01 13:04:39 +02:00
parent 96e64198e2
commit e62da1016d
7 changed files with 29 additions and 74 deletions
@@ -24,7 +24,7 @@ import java.util.*
private val LOG = Logger.getInstance(AsyncPromise::class.java)
@SuppressWarnings("ThrowableResultOfMethodCallIgnored")
val OBSOLETE_ERROR = Promise.createError("Obsolete")
private val OBSOLETE_ERROR = Promise.createError("Obsolete")
open class AsyncPromise<T> : Promise<T>(), Getter<T> {
@Volatile private var done: Consumer<in T>? = null
@@ -92,7 +92,7 @@ open class AsyncPromise<T> : Promise<T>(), Getter<T> {
addHandlers(Consumer({ result ->
promise.catchError {
if (fulfilled is Obsolescent && fulfilled.isObsolete) {
promise.setError(OBSOLETE_ERROR)
promise.cancel()
}
else {
promise.setResult(fulfilled.`fun`(result))
@@ -186,6 +186,10 @@ open class AsyncPromise<T> : Promise<T>(), Getter<T> {
return setError(Promise.createError(error))
}
fun cancel() {
setError(OBSOLETE_ERROR)
}
open fun setError(error: Throwable): Boolean {
if (state != Promise.State.PENDING) {
return false
@@ -272,4 +276,9 @@ inline fun <T> AsyncPromise<*>.catchError(runnable: () -> T): T? {
}
}
private val cancelledPromise = RejectedPromise<Any?>(OBSOLETE_ERROR)
@Suppress("CAST_NEVER_SUCCEEDS")
fun <T> cancelledPromise(): Promise<T> = cancelledPromise as Promise<T>
fun <T> rejectedPromise(error: Throwable): Promise<T> = Promise.reject(error)
@@ -69,17 +69,8 @@ public abstract class Promise<T> {
@NotNull
public static Promise<Void> wrapAsVoid(@NotNull ActionCallback asyncResult) {
final AsyncPromise<Void> promise = new AsyncPromise<Void>();
asyncResult.doWhenDone(new Runnable() {
@Override
public void run() {
promise.setResult(null);
}
}).doWhenRejected(new Consumer<String>() {
@Override
public void consume(String error) {
promise.setError(createError(error == null ? "Internal error" : error));
}
});
asyncResult.doWhenDone(() -> promise.setResult(null)).doWhenRejected(
error -> promise.setError(createError(error == null ? "Internal error" : error)));
return promise;
}
@@ -91,12 +82,7 @@ public abstract class Promise<T> {
public void consume(T result) {
promise.setResult(result);
}
}).doWhenRejected(new Consumer<String>() {
@Override
public void consume(String error) {
promise.setError(error);
}
});
}).doWhenRejected(promise::setError);
return promise;
}
@@ -146,16 +132,20 @@ public abstract class Promise<T> {
/**
* Log error if not message error
*/
public static void logError(@NotNull Logger logger, @NotNull Throwable e) {
public static boolean logError(@NotNull Logger logger, @NotNull Throwable e) {
if (e instanceof MessageError) {
ThreeState log = ((MessageError)e).log;
if (log == ThreeState.YES || (log == ThreeState.UNSURE && ApplicationManager.getApplication().isUnitTestMode())) {
logger.error(e);
return true;
}
}
else if (!(e instanceof ProcessCanceledException)) {
logger.error(e);
return true;
}
return false;
}
public abstract void notify(@NotNull AsyncPromise<? super T> child);
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,8 +15,8 @@
*/
package org.jetbrains.debugger
import com.intellij.util.Consumer
import org.jetbrains.concurrency.Promise
import org.jetbrains.concurrency.cancelledPromise
import org.jetbrains.debugger.values.ObjectValue
import org.jetbrains.debugger.values.ValueManager
@@ -25,14 +25,10 @@ abstract class DeclarativeScope<VALUE_MANAGER : ValueManager>(type: Scope.Type,
protected fun loadScopeObjectProperties(value: ObjectValue): Promise<List<Variable>> {
if (childrenManager.valueManager.isObsolete) {
return ValueManager.reject()
return cancelledPromise()
}
return value.properties.done(object : Consumer<List<Variable>> {
override fun consume(variables: List<Variable>) {
childrenManager.updateCacheStamp()
}
})
return value.properties.done { childrenManager.updateCacheStamp() }
}
override fun getVariablesHost() = childrenManager
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,6 +17,7 @@ package org.jetbrains.debugger;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.concurrency.AsyncPromiseKt;
import org.jetbrains.concurrency.Promise;
import org.jetbrains.concurrency.PromiseManager;
import org.jetbrains.debugger.values.ValueManager;
@@ -35,7 +36,7 @@ public abstract class VariablesHost<VALUE_MANAGER extends ValueManager> {
@NotNull
@Override
public Promise load(@NotNull VariablesHost host) {
return host.valueManager.isObsolete() ? ValueManager.Companion.reject() : host.load();
return host.valueManager.isObsolete() ? AsyncPromiseKt.cancelledPromise() : host.load();
}
};
@@ -15,10 +15,7 @@
*/
package org.jetbrains.debugger.values
import org.jetbrains.concurrency.OBSOLETE_ERROR
import org.jetbrains.concurrency.Obsolescent
import org.jetbrains.concurrency.Promise
import org.jetbrains.concurrency.rejectedPromise
import java.util.concurrent.atomic.AtomicInteger
/**
@@ -43,11 +40,4 @@ abstract class ValueManager() : Obsolescent {
fun markObsolete() {
obsolete = true
}
companion object {
val OBSOLETE_CONTEXT_PROMISE = rejectedPromise<Any?>(OBSOLETE_ERROR)
@Suppress("UNCHECKED_CAST")
fun <T> reject() = OBSOLETE_CONTEXT_PROMISE as Promise<T>
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,15 +17,13 @@ package org.jetbrains.debugger
import com.intellij.util.Consumer
import com.intellij.xdebugger.XDebugSession
import org.jetbrains.concurrency.OBSOLETE_ERROR
import org.jetbrains.concurrency.Promise
import org.jetbrains.rpc.LOG
class RejectErrorReporter @JvmOverloads constructor(private val session: XDebugSession, private val description: String? = null) : Consumer<Throwable> {
override fun consume(error: Throwable) {
Promise.logError(LOG, error)
if (error !== OBSOLETE_ERROR) {
session.reportError((if (description == null) "" else "$description: ") + error.message)
if (Promise.logError(LOG, error)) {
session.reportError("${if (description == null) "" else "$description: "}${error.message}")
}
}
}
@@ -1,29 +0,0 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed 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.
*/
package com.intellij.xdebugger.util
import com.intellij.xdebugger.XDebugSession
import org.jetbrains.concurrency.OBSOLETE_ERROR
import org.jetbrains.concurrency.Promise
import org.jetbrains.rpc.LOG
// have to use package "com.intellij.xdebugger.util" to avoid package clash
fun XDebugSession.rejectedErrorReporter(description: String? = null): (Throwable) -> Unit = {
Promise.logError(LOG, it)
if (it != OBSOLETE_ERROR) {
reportError("${if (description == null) "" else description + ": "}${it.message}")
}
}