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

com.oracle.tools.deferred.Supervised Maven / Gradle / Ivy

/*
 * File: Supervised.java
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * The contents of this file are subject to the terms and conditions of 
 * the Common Development and Distribution License 1.0 (the "License").
 *
 * You may not use this file except in compliance with the License.
 *
 * You can obtain a copy of the License by consulting the LICENSE.txt file
 * distributed with this file, or by consulting https://oss.oracle.com/licenses/CDDL
 *
 * 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 LICENSE.txt.
 *
 * 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]"
 */

package com.oracle.tools.deferred;

import java.util.concurrent.TimeUnit;

/**
 * A {@link Supervised} is a {@link Deferred} adapter that has
 * knowledge of the last known availability of an object, the purpose of which
 * is to ensure that the underlying object is protected from repeated and
 * perhaps continuously unrelenting requests by an application to access it,
 * when it simply may be unavailable for a long period of time.
 * 

* A program will use a {@link Supervised} object to avoid the situation when * multiple {@link Thread}s attempt to call {@link #get()} or a single * {@link Thread} calls {@link #get()} in a tight loop. It protects the adapted * {@link Deferred#get()} method from being called repeatedly, allowing the underlying * resource a chance to "recover" when required. *

* Copyright (c) 2012. All Rights Reserved. Oracle Corporation.
* Oracle is a registered trademark of Oracle Corporation and/or its affiliates. * * @author Brian Oliver */ public class Supervised implements Deferred { /** * The {@link Deferred} being adapted and protected by the * {@link Supervised}. */ private Deferred m_deferred; /** * The instant in time (since the epoc) when the last attempt to acquire * the object failed. */ private volatile long m_instantOfLastFailure; /** * The duration that must pass before attempting to acquire a object * (since the last failed attempt) */ private long m_retryDelayDuration; /** * The {@link TimeUnit} for the {@link #m_retryDelayDuration}. */ private TimeUnit m_retryDelayTimeUnit; /** * Constructor for a {@link Supervised}. * * @param deferred the {@link Deferred} to supervise */ public Supervised(Deferred deferred) { m_deferred = deferred; m_instantOfLastFailure = -1; m_retryDelayDuration = 250L; m_retryDelayTimeUnit = TimeUnit.MILLISECONDS; } /** * Obtains the adapted {@link Deferred}. * * @return the adapted {@link Deferred} */ public Deferred getDeferred() { return m_deferred; } /** * Determines a request to {@link #get()} the underlying object will fail * immediately. * * @return true the object is accessible, false if * a {@link #get()} request will fail immediately */ public boolean isAccessible() { return m_instantOfLastFailure < 0 || System.currentTimeMillis() > m_instantOfLastFailure + m_retryDelayTimeUnit.toMillis(m_retryDelayDuration); } /** * Applications should call this method when they determine, through some * external means, that the underlying object they have acquired from the * {@link Supervised} is no longer available. *

* This ensures that a {@link Supervised} can protect against * repeated requests for the object from parts of an application. */ public void resourceNoLongerAvailable() { m_instantOfLastFailure = System.currentTimeMillis(); } /** * {@inheritDoc} */ @Override public T get() throws UnresolvableInstanceException, InstanceUnavailableException { if (isAccessible()) { // we synchronize here to protect the underlying object, // that may not be able to cope with a lot of concurrent access synchronized (this) { // the current thread may have be held up for a while waiting, // so we check again if the object is still accessible if (isAccessible()) { try { // attempt to get the object return m_deferred.get(); } catch (UnresolvableInstanceException e) { // when a object is unavailable, we must re-throw it resourceNoLongerAvailable(); throw e; } catch (RuntimeException e) { // for runtime exceptions we re-throw them resourceNoLongerAvailable(); throw e; } } else { return null; } } } else { return null; } } /** * {@inheritDoc} */ @Override public Class getDeferredClass() { return m_deferred.getDeferredClass(); } /** * {@inheritDoc} */ @Override public String toString() { return String.format("Supervised<%s>{%s}", getDeferredClass(), getDeferred()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy