Skip to content

Commit 635eec3

Browse files
authored
Merge pull request #5178 from microsoft/bugfix-cancel-login2
fix a bug of canceling login doesn't cancel background job
2 parents df1094a + 0f97805 commit 635eec3

File tree

3 files changed

+34
-30
lines changed

3 files changed

+34
-30
lines changed

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/ui/DeviceLoginUI.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,15 @@
1414
import lombok.Setter;
1515
import org.jetbrains.annotations.NotNull;
1616
import org.jetbrains.annotations.Nullable;
17-
import reactor.core.Disposable;
17+
18+
import java.util.concurrent.Future;
1819

1920

2021
public class DeviceLoginUI implements IDeviceLoginUI {
2122
private DeviceLoginWindow deviceLoginWindow;
2223

2324
@Setter
24-
private Disposable disposable;
25+
private Future future;
2526

2627
@Nullable
2728
@Override
@@ -45,8 +46,8 @@ public void closePrompt() {
4546

4647
@Override
4748
public void cancel() {
48-
if (disposable != null) {
49-
this.disposable.dispose();
49+
if (future != null) {
50+
this.future.cancel(true);
5051
}
5152
}
5253
}

PluginsAndFeatures/azure-toolkit-for-intellij/src/com/microsoft/intellij/ui/SignInWindow.java

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.intellij.openapi.fileChooser.FileChooser;
1111
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
1212
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
13+
import com.intellij.openapi.progress.ProcessCanceledException;
1314
import com.intellij.openapi.progress.ProgressIndicator;
1415
import com.intellij.openapi.progress.ProgressManager;
1516
import com.intellij.openapi.project.Project;
@@ -49,7 +50,6 @@
4950
import reactor.core.scheduler.Schedulers;
5051
import reactor.util.function.Tuple2;
5152
import rx.Single;
52-
import rx.exceptions.Exceptions;
5353

5454
import javax.swing.*;
5555
import java.awt.*;
@@ -58,6 +58,7 @@
5858
import java.util.List;
5959
import java.util.*;
6060
import java.util.concurrent.Callable;
61+
import java.util.concurrent.CancellationException;
6162
import java.util.concurrent.CompletableFuture;
6263
import java.util.stream.Stream;
6364

@@ -66,7 +67,6 @@
6667
public class SignInWindow extends AzureDialogWrapper {
6768
private static final Logger LOGGER = Logger.getInstance(SignInWindow.class);
6869
private static final String SIGN_IN_ERROR = "Sign In Error";
69-
private static final String USER_CANCEL = "user cancel";
7070

7171
private JPanel contentPane;
7272

@@ -215,21 +215,26 @@ public Single<AuthMethodDetails> login() {
215215
}
216216

217217
private static AuthMethodDetails checkCanceled(ProgressIndicator indicator, Mono<? extends AuthMethodDetails> mono) {
218-
CompletableFuture<AuthMethodDetails> loginFuture = new CompletableFuture<>();
218+
CompletableFuture<? extends AuthMethodDetails> future = mono.toFuture();
219219
Disposable disposable = Flux.interval(Duration.ofSeconds(1)).map(ts -> {
220-
if (indicator != null && indicator.isCanceled()) {
221-
IllegalStateException e = new IllegalStateException(USER_CANCEL);
222-
loginFuture.completeExceptionally(e);
223-
throw e;
220+
if (indicator != null) {
221+
indicator.checkCanceled();
224222
}
225223
return 1;
226-
}).onErrorResume(e -> Mono.empty()).subscribe();
227-
mono.doOnError(loginFuture::completeExceptionally).doOnSuccess(loginFuture::complete).doFinally(e -> disposable.dispose()).subscribe();
224+
}).onErrorResume(e -> {
225+
if (e instanceof ProcessCanceledException) {
226+
future.cancel(true);
227+
}
228+
return Mono.empty();
229+
}).subscribeOn(Schedulers.boundedElastic()).subscribe();
228230
try {
229-
return loginFuture.get();
230-
} catch (Throwable ex) {
231-
Throwable e = Exceptions.getFinalCause(ex);
232-
throw new AzureToolkitRuntimeException("Cannot login due to error: " + ex.getMessage(), ex);
231+
return future.get();
232+
} catch (CancellationException e) {
233+
return null;
234+
} catch (Throwable e) {
235+
throw new AzureToolkitRuntimeException("Cannot login due to error: " + e.getMessage(), e);
236+
} finally {
237+
disposable.dispose();
233238
}
234239
}
235240

@@ -334,25 +339,22 @@ private synchronized AuthMethodDetails doDeviceLogin() {
334339
final IDeviceLoginUI deviceLoginUI = CommonSettings.getUiFactory().getDeviceLoginUI();
335340
final AzureAccount az = com.microsoft.azure.toolkit.lib.Azure.az(AzureAccount.class);
336341
final Account account = az.loginAsync(AuthType.DEVICE_CODE, true).block();
337-
Disposable subscribe = account.continueLogin().doOnCancel(() -> {
338-
deviceCodeLoginFuture.completeExceptionally(new IllegalStateException("user cancel"));
339-
}).doOnSuccess(ac -> {
340-
deviceCodeLoginFuture.complete(fromAccountEntity(ac.getEntity()));
341-
}).doOnError(deviceCodeLoginFuture::completeExceptionally).doFinally(signal -> {
342-
deviceLoginUI.closePrompt();
343-
}).subscribe();
344-
deviceLoginUI.setDisposable(subscribe);
342+
343+
CompletableFuture<AuthMethodDetails> future =
344+
account.continueLogin().map(ac -> fromAccountEntity(ac.getEntity())).doFinally(signal -> {
345+
deviceLoginUI.closePrompt();
346+
}).toFuture();
347+
deviceLoginUI.setFuture(future);
345348
if (ApplicationManager.getApplication().isDispatchThread()) {
346349
deviceLoginUI.promptDeviceCode(((DeviceCodeAccount) account).getDeviceCode());
347350
} else {
348351
AzureTaskManager.getInstance().runAndWait(() ->
349352
deviceLoginUI.promptDeviceCode(((DeviceCodeAccount) account).getDeviceCode()));
350353
}
351-
return Mono.fromFuture(deviceCodeLoginFuture).block();
354+
return future.get();
352355

353356
} catch (Exception ex) {
354-
if (ex instanceof IllegalStateException && USER_CANCEL.equals(ex.getMessage())) {
355-
} else {
357+
if (!(ex instanceof CancellationException)) {
356358
ex.printStackTrace();
357359
ErrorWindow.show(project, ex.getMessage(), SIGN_IN_ERROR);
358360
}

Utils/azuretools-core/src/com/microsoft/azuretools/adauth/IDeviceLoginUI.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
import com.microsoft.aad.adal4j.AuthenticationResult;
1212
import com.microsoft.aad.adal4j.DeviceCode;
1313
import com.microsoft.azuretools.azurecommons.helpers.Nullable;
14-
import reactor.core.Disposable;
14+
15+
import java.util.concurrent.Future;
1516

1617
public interface IDeviceLoginUI {
1718
@Nullable
@@ -26,7 +27,7 @@ default void closePrompt() {
2627

2728
}
2829

29-
default void setDisposable(Disposable disposable) {
30+
default void setFuture(Future future) {
3031

3132
}
3233

0 commit comments

Comments
 (0)