1 /* 2 * Copyright (C) 2015 The Dagger Authors. 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 17 package dagger.producers.monitoring; 18 19 import dagger.producers.Produces; 20 import dagger.producers.ProductionComponent; 21 22 /** 23 * A hook for recording the timing of the execution of individual 24 * {@linkplain Produces producer methods}. See {@link ProductionComponentTimingRecorder} for how to 25 * install these monitors. 26 * 27 * <p>If any of the recorder's methods throw, then the exception will be logged and processing will 28 * continue unaffected. 29 * 30 * <p>All timings are measured at nanosecond precision, but not necessarily nanosecond resolution. 31 * That is, timings will be reported in nanoseconds, but the timing source will not necessarily 32 * update at nanosecond resolution. For example, {@link System#nanoTime()} would satisfy these 33 * constraints. 34 * 35 * @since 2.1 36 */ 37 public abstract class ProducerTimingRecorder { 38 /** 39 * Reports that the producer method has finished executing with the given statistics. 40 * 41 * <p>If the producer was skipped due to any of its inputs failing, then this will not be called. 42 * 43 * @param startedNanos the wall-clock time, in nanoseconds, when the producer method started 44 * executing, measured from when the first method on the {@linkplain ProductionComponent 45 * production component} was called. 46 * @param durationNanos the wall-clock time, in nanoseconds, that the producer method took to 47 * execute. 48 */ 49 @SuppressWarnings("GoodTime") // should accept a java.time.Duration x2 (?) recordMethod(long startedNanos, long durationNanos)50 public void recordMethod(long startedNanos, long durationNanos) {} 51 52 /** 53 * Reports that the producer's future has succeeded with the given statistics. 54 * 55 * <p>If the producer was skipped due to any of its inputs failing, then this will not be called. 56 * 57 * @param latencyNanos the wall-clock time, in nanoseconds, of the producer's latency, measured 58 * from when the producer method started to when the future finished. 59 */ 60 @SuppressWarnings("GoodTime") // should accept a java.time.Duration recordSuccess(long latencyNanos)61 public void recordSuccess(long latencyNanos) {} 62 63 /** 64 * Reports that the producer's future has failed with the given statistics. 65 * 66 * @param exception the exception that the future failed with. 67 * @param latencyNanos the wall-clock time, in nanoseconds, of the producer's latency, measured 68 * from when the producer method started to when the future finished. 69 */ 70 @SuppressWarnings("GoodTime") // should accept a java.time.Duration recordFailure(Throwable exception, long latencyNanos)71 public void recordFailure(Throwable exception, long latencyNanos) {} 72 73 /** 74 * Reports that the producer was skipped because one of its inputs failed. 75 * 76 * @param exception the exception that its input failed with. If multiple inputs failed, this 77 * exception will be chosen arbitrarily from the input failures. 78 */ recordSkip(Throwable exception)79 public void recordSkip(Throwable exception) {} 80 81 /** Returns a producer recorder that does nothing. */ noOp()82 public static ProducerTimingRecorder noOp() { 83 return NO_OP; 84 } 85 86 private static final ProducerTimingRecorder NO_OP = new ProducerTimingRecorder() {}; 87 } 88