void () { synchronized (myLock) { if (myState.equals(State.CREATED)) { myState = State.INITIALIZED; Span span = TelemetryManager.getInstance().getTracer(VcsScope).spanBuilder(LogData.Initializing.getName()).startSpan(); Task.Backgroundable backgroundable = new Task.Backgroundable(myProject, VcsLogBundle.message("vcs.log.initial.loading.process"), false) { @Override public void run(@NotNull ProgressIndicator indicator) { runSpanWithScope(span, () -> { indicator.setIndeterminate(true); resetState(); readCurrentUser(); myRefresher.readFirstBlock(); fireDataPackChangeEvent(myRefresher.getCurrentDataPack()); }); } @Override public void onCancel() { synchronized (myLock) { // Here be dragons: // VcsLogProgressManager can cancel us when it's getting disposed, // and we can also get cancelled by invalid git executable. // Since we do not know what's up, we just restore the state, // and it is entirely possible to start another initialization after that. // Eventually, everything gets cancelled for good in VcsLogData.dispose. // But still. if (myState.equals(State.INITIALIZED)) { myState = State.CREATED; myInitialization = null; } } } @Override public void onThrowable(@NotNull Throwable error) { synchronized (myLock) { LOG.error(error); if (myState.equals(State.INITIALIZED)) { myState = State.CREATED; myInitialization = null; } } } @Override public void onSuccess() { synchronized (myLock) { if (myState.equals(State.INITIALIZED)) { myInitialization = null; } } } }; CoreProgressManager manager = (CoreProgressManager)ProgressManager.getInstance(); ProgressIndicator indicator = myRefresher.getProgress().createProgressIndicator(DATA_PACK_REFRESH); Future<?> future = manager.runProcessWithProgressAsynchronously(backgroundable, indicator, null); myInitialization = new SingleTaskController.SingleTaskImpl(future, indicator); } } }