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

dagger.producers.monitoring.ProducerMonitor Maven / Gradle / Ivy

There is a newer version: 2.52
Show newest version
/*
 * Copyright (C) 2015 The Dagger Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dagger.producers.monitoring;

import static com.google.common.util.concurrent.Futures.addCallback;
import static com.google.common.util.concurrent.MoreExecutors.directExecutor;

import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.ListenableFuture;
import dagger.producers.Producer;
import dagger.producers.Produces;

/**
 * A hook for monitoring the execution of individual {@linkplain Produces producer methods}. See
 * {@link ProductionComponentMonitor} for how to install these monitors.
 *
 * 

The lifecycle of the monitor, under normal conditions, is: *

    *
  • {@link #requested()} *
  • {@link #methodStarting()} *
  • The method is called *
  • {@link #methodFinished()} *
  • If the method returns a value, then: *
      *
    • {@link #succeeded(Object)} if the method returned normally; or *
    • {@link #failed(Throwable)} if the method threw an exception. *
    *
  • If the method returns a future, then: *
      *
    • {@link #succeeded(Object)} if the method returned normally, and the future succeeded; or *
    • {@link #failed(Throwable)} if the method threw an exception, or returned normally and the * future failed. *
    *
* *

If any input to the monitored producer fails, {@link #failed(Throwable)} will be called * immediately with the failed input's exception. If more than one input fails, an arbitrary failed * input's exception is used. * *

For example, given an entry point A that depends on B, which depends on C, when the entry * point A is called, this will trigger the following sequence of events, assuming all methods and * futures complete successfully: *

    *
  • A requested *
  • B requested *
  • C requested *
  • C methodStarting *
  • C methodFinished *
  • C succeeded *
  • B methodStarting *
  • B methodFinished *
  • B succeeded *
  • A methodStarting *
  • A methodFinished *
  • A succeeded *
* *

If any of the monitor's methods throw, then the exception will be logged and processing will * continue unaffected. * * @since 2.1 */ public abstract class ProducerMonitor { /** * Called when the producer's output is requested; that is, when the first method is called that * requires the production of this producer's output. * *

Note that if a method depends on {@code Producer}, then this does not count as requesting * {@code T}; that is only triggered by calling {@link Producer#get()}. * *

Depending on how this producer is requested, the following threading constraints are * guaranteed: * *

    *
  1. If the producer is requested directly by a method on a component, then {@code requested} * will be called on the same thread as the component method call. *
  2. If the producer is requested by value from another producer (i.e., injected as {@code T} * or {@code Produced}), then {@code requested} will be called from the same thread as * the other producer's {@code requested}. *
  3. If the producer is requested by calling {@link Producer#get()}, then {@code requested} * will be called from the same thread as that {@code get()} call. *
* *

When multiple monitors are installed, the order that each monitor will call this method is * unspecified, but will remain consistent throughout the course of the execution of a component. * *

This implementation is a no-op. */ public void requested() {} /** * Called when all of the producer's inputs are available. This is called regardless of whether * the inputs have succeeded or not; when the inputs have succeeded, this is called prior to * scheduling the method on the executor, and if an input has failed and the producer will be * skipped, this method will be called before {@link #failed(Throwable)} is called. * *

When multiple monitors are installed, the order that each monitor will call this method is * unspecified, but will remain consistent throughout the course of the execution of a component. * *

This implementation is a no-op. */ public void ready() {} /** * Called when the producer method is about to start executing. This will be called from the same * thread as the producer method itself. * *

When multiple monitors are installed, calls to this method will be in the reverse order from * calls to {@link #requested()}. * *

This implementation is a no-op. */ public void methodStarting() {} /** * Called when the producer method has finished executing. This will be called from the same * thread as {@link #methodStarting()} and the producer method itself. * *

When multiple monitors are installed, calls to this method will be in the reverse order from * calls to {@link #requested()}. * *

This implementation is a no-op. */ public void methodFinished() {} /** * Called when the producer’s future has completed successfully with a value. * *

When multiple monitors are installed, calls to this method will be in the reverse order from * calls to {@link #requested()}. * *

This implementation is a no-op. */ public void succeeded(@SuppressWarnings("unused") Object value) {} /** * Called when the producer's future has failed with an exception. * *

When multiple monitors are installed, calls to this method will be in the reverse order from * calls to {@link #requested()}. * *

This implementation is a no-op. */ public void failed(@SuppressWarnings("unused") Throwable t) {} /** * Adds this monitor's completion methods as a callback to the future. This is only intended to be * overridden in the framework! */ public void addCallbackTo(ListenableFuture future) { addCallback( future, new FutureCallback() { @Override public void onSuccess(T value) { succeeded(value); } @Override public void onFailure(Throwable t) { failed(t); } }, directExecutor()); } private static final ProducerMonitor NO_OP = new ProducerMonitor() { @Override public void addCallbackTo(ListenableFuture future) { // overridden to avoid adding a do-nothing callback } }; /** Returns a monitor that does no monitoring. */ public static ProducerMonitor noOp() { return NO_OP; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy