• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package dagger.producers.monitoring;
17 
18 import com.google.common.util.concurrent.FutureCallback;
19 import com.google.common.util.concurrent.Futures;
20 import com.google.common.util.concurrent.ListenableFuture;
21 import dagger.producers.Produces;
22 
23 /**
24  * A hook for monitoring the execution of individual {@linkplain Produces producer methods}. See
25  * {@link ProductionComponentMonitor} for how to install these monitors.
26  *
27  * <p>The lifecycle of the monitor, under normal conditions, is:
28  * <ul>
29  *   <li>{@link #methodStarting()}
30  *   <li>The method is called
31  *   <li>{@link #methodFinished()}
32  *   <li>If the method returns a value, then:
33  *   <ul>
34  *     <li>{@link #succeeded(Object)} if the method returned normally; or
35  *     <li>{@link #failed(Throwable)} if the method threw an exception.
36  *   </ul>
37  *   <li>If the method returns a future, then:
38  *   <ul>
39  *     <li>{@link #succeeded(Object)} if the method returned normally, and the future succeeded; or
40  *     <li>{@link #failed(Throwable)} if the method threw an exception, or returned normally and the
41  *         future failed.
42  *   </ul>
43  * </ul>
44  *
45  * <p>If any input to the monitored producer fails, {@link #failed(Throwable)} will be called
46  * immediately with the failed input's exception. If more than one input fails, an arbitrary failed
47  * input's exception is used.
48  *
49  * <p>If any of the monitor's methods throw, then the exception will be logged and processing will
50  * continue unaffected.
51  *
52  * @author Jesse Beder
53  */
54 public abstract class ProducerMonitor {
55   /**
56    * Called when the producer method is about to start executing.
57    *
58    * <p>When multiple monitors are installed, the order that each monitor will call this method is
59    * unspecified, but will remain consistent throughout the course of the execution of a component.
60    */
methodStarting()61   public void methodStarting() {}
62 
63   /**
64    * Called when the producer method has finished executing.
65    *
66    * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
67    * calls to {@link #methodStarting()}.
68    */
methodFinished()69   public void methodFinished() {}
70 
71   /**
72    * Called when the producer’s future has completed successfully with a value.
73    *
74    * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
75    * calls to {@link #methodStarting()}.
76    */
succeeded(Object o)77   public void succeeded(Object o) {}
78 
79   /**
80    * Called when the producer's future has failed with an exception.
81    *
82    * <p>When multiple monitors are installed, calls to this method will be in the reverse order from
83    * calls to {@link #methodStarting()}.
84    */
failed(Throwable t)85   public void failed(Throwable t) {}
86 
87   /**
88    * Adds this monitor's completion methods as a callback to the future. This is only intended to be
89    * overridden in the framework!
90    */
addCallbackTo(ListenableFuture<T> future)91   public <T> void addCallbackTo(ListenableFuture<T> future) {
92     Futures.addCallback(
93         future,
94         new FutureCallback<T>() {
95           @Override
96           public void onSuccess(T value) {
97             succeeded(value);
98           }
99 
100           @Override
101           public void onFailure(Throwable t) {
102             failed(t);
103           }
104         });
105   }
106 }
107