All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jvnet.hk2.component.AsyncWaiter Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2007-2011 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */
package org.jvnet.hk2.component;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.Logger;

import org.glassfish.hk2.AsyncPostConstruct;

/**
 * Helper class that will manage all {@link AsyncPostConstruct} services
 * and Futures for completion.
 *
 * 

* Once a service or Future is found to be completed, it is dropped. * * @author Jeff Trent */ public class AsyncWaiter { private static Logger logger = Logger.getLogger(AsyncWaiter.class.getName()); private static Level LEVEL = Level.FINE; private Collection watches; private AsyncPostConstruct workingOn; /** * Clear the collection of watches, regardless of state. */ public synchronized void clear() { watches = null; workingOn = null; } /** * Watches an inhabitant if the service implements {@link AsyncPostConstruct}. */ public synchronized void watchIfNecessary(Inhabitant i) { Object service = i.get(); if (AsyncPostConstruct.class.isInstance(service)) { if (!AsyncPostConstruct.class.cast(service).isDone()) { if (null == watches) { watches = new ArrayList(); } AsyncInhabitant watch = new AsyncInhabitant(i); logger.log(LEVEL, "Adding watch on {0}", watch); logger.log(LEVEL, " watch done = {0}", watch.isDone()); watches.add(watch); } } } /** * Watches a Future for completion. */ public synchronized void watchIfNecessary(Future f) { if (!f.isDone()) { if (null == watches) { watches = new ArrayList(); } AsyncFuture watch = new AsyncFuture(f); logger.log(LEVEL, "Adding watch on {0}", watch); watches.add(watch); } } /** * Waits for all watches to be done. This might be a blocking operation. */ public synchronized void waitForDone() throws ExecutionException, TimeoutException, InterruptedException { if (null != watches) { Iterator iter = watches.iterator(); while (iter.hasNext()) { workingOn = iter.next(); workingOn.waitForDone(); iter.remove(); } } workingOn = null; } /** * Wait's for all inhabitants being watched to be done, giving each up * to timeout/unit's to be done. If there are any {@link TimeoutException}s * the result will be false. */ public boolean waitForDone(long timeout, TimeUnit unit) throws ExecutionException, TimeoutException, InterruptedException { long start = System.currentTimeMillis(); logger.log(LEVEL, "entering; watches = {0}", (null == watches ? -1 : watches.size())); boolean done = true; if (null != watches) { Iterator iter = watches.iterator(); while (iter.hasNext()) { workingOn = iter.next(); if (workingOn.waitForDone(timeout, unit)) { iter.remove(); } else { logger.log(LEVEL, "gave up waiting on {0}", workingOn); done = false; } } } workingOn = null; logger.log(LEVEL, "exiting - {0} ms", System.currentTimeMillis()-start); logger.log(LEVEL, " watches = {0}", (null == watches ? -1 : watches.size())); logger.log(LEVEL, " done is {0}", done); return done; } public synchronized int getWatches() { return (null == watches) ? 0 : watches.size(); } /** * A non-blocking call that returns true when we are done waiting. */ public synchronized boolean isDone() { boolean done = true; if (null != watches) { Iterator iter = watches.iterator(); while (iter.hasNext()) { workingOn = iter.next(); if (workingOn.isDone()) { iter.remove(); } } workingOn = null; done = watches.isEmpty(); } return done; } /** * Returns the last Inhabitant that was working on, provided that we are not in a "done" state. */ public synchronized Inhabitant getLastInhabitantWorkingOn() { return AsyncInhabitant.class.isInstance(workingOn) ? AsyncInhabitant.class.cast(workingOn).inhabitant : null; } private static class AsyncFuture implements AsyncPostConstruct { private final Future future; private AsyncFuture(Future future) { this.future = future; } @Override public void postConstruct() { } @Override public boolean isDone() { return future.isDone(); } @Override public void waitForDone() throws ExecutionException, InterruptedException{ future.get(); } @Override public boolean waitForDone(long timeout, TimeUnit unit) throws ExecutionException, InterruptedException { try { future.get(timeout, unit); return true; } catch (TimeoutException e) { return false; } } } private static class AsyncInhabitant implements AsyncPostConstruct { private final Inhabitant inhabitant; private final AsyncPostConstruct service; private AsyncInhabitant(Inhabitant inhabitant) { this.inhabitant = inhabitant; this.service = (AsyncPostConstruct) inhabitant.get(); } @Override public void postConstruct() { } @Override public boolean isDone() { return service.isDone(); } @Override public void waitForDone() throws ExecutionException, TimeoutException, InterruptedException { service.waitForDone(); } @Override public boolean waitForDone(long timeout, TimeUnit unit) throws ExecutionException, InterruptedException { return service.waitForDone(timeout, unit); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy