/******************************************************************************* * Copyright (c) 2015 GoPivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * GoPivotal, Inc. - initial API and implementation *******************************************************************************/ package org.springframework.ide.eclipse.boot.dash.util; import javax.inject.Provider; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.Job; import org.springframework.ide.eclipse.boot.launch.util.SpringApplicationLifeCycleClientManager; import org.springframework.ide.eclipse.boot.launch.util.SpringApplicationLifecycleClient; import org.springsource.ide.eclipse.commons.livexp.core.LiveExpression; import org.springsource.ide.eclipse.commons.livexp.core.LiveVariable; /** * An instance of this class starts checking a spring application's lifecyle using * a JMX bean protocol. Checks are performed repeatedly with a short delay between * polls. This continues until either the SpringApplicationReadyStateMonitor is disposed, * or the application enters the 'ready' state. * <p> * When the application reaches ready state then its 'ready' LiveExp will change value from * false to true. Clients who wish to respond to this 'event' can attach a listener to * the livexp. * * @author Kris De Volder */ public class SpringApplicationReadyStateMonitor implements ReadyStateMonitor { ////////////////////////////////////////////////////////////////////////// // public API public static final long POLLING_INTERVAL = 500/*ms*/; private SpringApplicationLifeCycleClientManager clientManager; public SpringApplicationReadyStateMonitor(Provider<Integer> jmxPort) { this.clientManager = new SpringApplicationLifeCycleClientManager(jmxPort); this.job = new Job("Ready state poller") { protected IStatus run(IProgressMonitor monitor) { LiveVariable<Boolean> r = ready; if (r!=null) { //null means disposed. Job may be lagging behind r.setValue(checkReady()); if (!r.getValue()) { this.schedule(POLLING_INTERVAL); } else { // don't reschedule } } return Status.OK_STATUS; } }; job.setSystem(true); job.schedule(); } public LiveExpression<Boolean> getReady() { return ready; } public void dispose() { clientManager.disposeClient(); if (job!=null) { job.cancel(); job = null; } ready = null; } ///////////////////////////////////////////////////////////////////////// // implementation private Job job; private LiveVariable<Boolean> ready = new LiveVariable<>(false); private boolean checkReady() { try { SpringApplicationLifecycleClient client = clientManager.getLifeCycleClient(); if (client!=null) { return client.isReady(); } } catch (Exception e) { //Something went wrong asking client for ready state. // most likely process died. clientManager.disposeClient(); } return false; } }