/** * Waits for the given process to finish, in a separate background thread, holding {@link * CloudSdkServiceManager#getSdkReadLock()} lock. */ @SuppressWarnings("FutureReturnValueIgnored") private void holdCloudSdkReadLock(Process process) { ThreadUtil.getInstance() .executeInBackground( () -> { CloudSdkServiceManager.getInstance().getSdkReadLock().lock(); try { process.waitFor(); } catch (InterruptedException e) { // unexpected interruption, nothing can be done. Logger.getInstance(AppEngineExecutor.class) .warn("Waiting for gcloud process unexpectedly interrupted", e); } finally { CloudSdkServiceManager.getInstance().getSdkReadLock().unlock(); } }); } }
private void executeWithSdkWriteLock(ThrowableRunnable<Exception> runWithLock) throws Exception { try { // if write lock is not available, show a progress to a user that all SDK processes must be // finished in order to update SDK. if (!CloudSdkServiceManager.getInstance().getSdkWriteLock().tryLock()) { ProgressListener waitForSdkProcessesProgress = ManagedCloudSdkServiceUiPresenter.getInstance().createProgressListener(this); waitForSdkProcessesProgress.start( CloudSdkMessageBundle.message("managedsdk.progress.wait.for.processes"), ProgressListener.UNKNOWN); try { CloudSdkServiceManager.getInstance().getSdkWriteLock().lockInterruptibly(); } finally { // make sure the indicator goes away in case of this job error/cancel waitForSdkProcessesProgress.done(); } } runWithLock.run(); } finally { CloudSdkServiceManager.getInstance().getSdkWriteLock().unlock(); } }
@Test public void install_blocks_whenSDKReadOperations_running() throws Exception { emulateMockSdkInstallationProcess(MOCK_SDK_PATH); SdkInstaller mockInstaller = mock(SdkInstaller.class); when(mockManagedCloudSdk.newInstaller()).thenReturn(mockInstaller); CloudSdkServiceManager.getInstance().getSdkReadLock().lock(); try { // signal when install is about to start write operation. CountDownLatch waitForInstallToStart = new CountDownLatch(1); doAnswer( invocationOnMock -> { waitForInstallToStart.countDown(); return false; }) .when(mockManagedCloudSdk) .isInstalled(); Runnable installProcess = () -> sdkService.install(); Thread installProcessThread = new Thread(installProcess, "test-install-blocking-thread"); installProcessThread.start(); // do timed wait in case of test issues not to cause it to hang. waitForInstallToStart.await(100, TimeUnit.MILLISECONDS); installProcessThread.interrupt(); // finalize install() installProcessThread.join(); // since the write block was not available at the install, install() should never be called. verifyNoMoreInteractions(mockInstaller); } finally { CloudSdkServiceManager.getInstance().getSdkReadLock().unlock(); } }
when(mockManagedCloudSdk.newUpdater()).thenReturn(mockUpdater); CloudSdkServiceManager.getInstance().getSdkReadLock().lock(); try { CloudSdkServiceManager.getInstance().getSdkReadLock().unlock();
CloudSdkServiceManager.getInstance() .runWhenSdkReady( task.getProject(),