diff --git a/dagger-producers/main/java/dagger/producers/internal/AbstractProducesMethodProducer.java b/dagger-producers/main/java/dagger/producers/internal/AbstractProducesMethodProducer.java index 95b8f8340da..7d13d9847d2 100644 --- a/dagger-producers/main/java/dagger/producers/internal/AbstractProducesMethodProducer.java +++ b/dagger-producers/main/java/dagger/producers/internal/AbstractProducesMethodProducer.java @@ -71,7 +71,13 @@ protected AbstractProducesMethodProducer( protected final ListenableFuture compute() { monitor = monitorProvider.get().producerMonitorFor(token); monitor.requested(); - ListenableFuture result = Futures.transformAsync(collectDependencies(), this, this); + ListenableFuture dependenciesFuture; + try { + dependenciesFuture = collectDependencies(); + } finally { + monitor.dependenciesRequested(); + } + ListenableFuture result = Futures.transformAsync(dependenciesFuture, this, this); monitor.addCallbackTo(result); return result; } diff --git a/dagger-producers/main/java/dagger/producers/monitoring/ProducerMonitor.java b/dagger-producers/main/java/dagger/producers/monitoring/ProducerMonitor.java index 2613e7b1fe0..4a7d21a9361 100644 --- a/dagger-producers/main/java/dagger/producers/monitoring/ProducerMonitor.java +++ b/dagger-producers/main/java/dagger/producers/monitoring/ProducerMonitor.java @@ -31,6 +31,8 @@ *

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

    *
  • {@link #requested()} + *
  • {@link #dependenciesRequested()} + *
  • {@link #ready()} *
  • {@link #methodStarting()} *
  • The method is called *
  • {@link #methodFinished()} @@ -58,6 +60,9 @@ *
  • A requested *
  • B requested *
  • C requested + *
  • C dependenciesRequested + *
  • B dependenciesRequested + *
  • A dependenciesRequested *
  • C methodStarting *
  • C methodFinished *
  • C succeeded @@ -102,6 +107,17 @@ public abstract class ProducerMonitor { */ public void requested() {} + /** + * Called when all of the producer's dependencies have been requested. This will be called from + * the same thread as {@link #requested()}. + * + *

    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 dependenciesRequested() {} + /** * 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 diff --git a/dagger-producers/main/java/dagger/producers/monitoring/internal/Monitors.java b/dagger-producers/main/java/dagger/producers/monitoring/internal/Monitors.java index 13b438ade46..2195196169d 100644 --- a/dagger-producers/main/java/dagger/producers/monitoring/internal/Monitors.java +++ b/dagger-producers/main/java/dagger/producers/monitoring/internal/Monitors.java @@ -135,6 +135,15 @@ public void requested() { } } + @Override + public void dependenciesRequested() { + try { + delegate.dependenciesRequested(); + } catch (RuntimeException e) { + logProducerMonitorMethodException(e, delegate, "dependenciesRequested"); + } + } + @Override public void ready() { try { @@ -270,6 +279,17 @@ public void requested() { } } + @Override + public void dependenciesRequested() { + for (ProducerMonitor delegate : delegates.reverse()) { + try { + delegate.dependenciesRequested(); + } catch (RuntimeException e) { + logProducerMonitorMethodException(e, delegate, "dependenciesRequested"); + } + } + } + @Override public void ready() { for (ProducerMonitor delegate : delegates) { diff --git a/javatests/dagger/functional/producers/monitoring/MonitoringTest.java b/javatests/dagger/functional/producers/monitoring/MonitoringTest.java index 4991e7e14df..8b7650c8ad7 100644 --- a/javatests/dagger/functional/producers/monitoring/MonitoringTest.java +++ b/javatests/dagger/functional/producers/monitoring/MonitoringTest.java @@ -88,13 +88,16 @@ public void basicMonitoring() throws Exception { inOrder.verify(callServer2Monitor).requested(); inOrder.verify(callServer1Monitor).requested(); inOrder.verify(requestDataMonitor).requested(); + inOrder.verify(requestDataMonitor).dependenciesRequested(); inOrder.verify(requestDataMonitor).ready(); inOrder.verify(requestDataMonitor).methodStarting(); inOrder.verify(requestDataMonitor).methodFinished(); inOrder.verify(requestDataMonitor).succeeded("Hello, World!"); + inOrder.verify(callServer1Monitor).dependenciesRequested(); inOrder.verify(callServer1Monitor).ready(); inOrder.verify(callServer1Monitor).methodStarting(); inOrder.verify(callServer1Monitor).methodFinished(); + inOrder.verify(callServer2Monitor).dependenciesRequested(); verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor); server1Future.set("server 1 response"); @@ -133,13 +136,16 @@ public void basicMonitoringWithFailure() throws Exception { inOrder.verify(callServer2Monitor).requested(); inOrder.verify(callServer1Monitor).requested(); inOrder.verify(requestDataMonitor).requested(); + inOrder.verify(requestDataMonitor).dependenciesRequested(); inOrder.verify(requestDataMonitor).ready(); inOrder.verify(requestDataMonitor).methodStarting(); inOrder.verify(requestDataMonitor).methodFinished(); inOrder.verify(requestDataMonitor).succeeded("Hello, World!"); + inOrder.verify(callServer1Monitor).dependenciesRequested(); inOrder.verify(callServer1Monitor).ready(); inOrder.verify(callServer1Monitor).methodStarting(); inOrder.verify(callServer1Monitor).methodFinished(); + inOrder.verify(callServer2Monitor).dependenciesRequested(); verifyNoMoreInteractions(requestDataMonitor, callServer1Monitor, callServer2Monitor); RuntimeException cause = new RuntimeException("monkey"); diff --git a/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java b/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java index 4cb9794a0ad..efa78c82ee8 100644 --- a/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java +++ b/javatests/dagger/producers/internal/AbstractProducesMethodProducerTest.java @@ -76,6 +76,7 @@ public void monitor_success() throws Exception { assertThat(future.isDone()).isFalse(); verify(monitor).ready(); verify(monitor).requested(); + verify(monitor).dependenciesRequested(); verify(monitor).addCallbackTo(anyListenableFuture()); verify(monitor).methodStarting(); verify(monitor).methodFinished(); @@ -94,6 +95,7 @@ public void monitor_failure() throws Exception { assertThat(future.isDone()).isFalse(); verify(monitor).ready(); verify(monitor).requested(); + verify(monitor).dependenciesRequested(); verify(monitor).addCallbackTo(anyListenableFuture()); verify(monitor).methodStarting(); verify(monitor).methodFinished(); diff --git a/javatests/dagger/producers/monitoring/internal/MonitorsTest.java b/javatests/dagger/producers/monitoring/internal/MonitorsTest.java index ada4e335b0d..efc21b1836b 100644 --- a/javatests/dagger/producers/monitoring/internal/MonitorsTest.java +++ b/javatests/dagger/producers/monitoring/internal/MonitorsTest.java @@ -124,12 +124,14 @@ public void singleMonitor_normalProducerMonitorSuccess() { monitor.producerMonitorFor(ProducerToken.create(Object.class)); Object o = new Object(); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.succeeded(o); InOrder order = inOrder(mockProducerMonitor); order.verify(mockProducerMonitor).requested(); + order.verify(mockProducerMonitor).dependenciesRequested(); order.verify(mockProducerMonitor).methodStarting(); order.verify(mockProducerMonitor).methodFinished(); order.verify(mockProducerMonitor).succeeded(o); @@ -147,12 +149,14 @@ public void singleMonitor_normalProducerMonitorFailure() { monitor.producerMonitorFor(ProducerToken.create(Object.class)); Throwable t = new RuntimeException("monkey"); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.failed(t); InOrder order = inOrder(mockProducerMonitor); order.verify(mockProducerMonitor).requested(); + order.verify(mockProducerMonitor).dependenciesRequested(); order.verify(mockProducerMonitor).methodStarting(); order.verify(mockProducerMonitor).methodFinished(); order.verify(mockProducerMonitor).failed(t); @@ -163,6 +167,7 @@ public void singleMonitor_normalProducerMonitorFailure() { public void singleMonitor_throwingProducerMonitorSuccess() { setUpNormalSingleMonitor(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).requested(); + doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).dependenciesRequested(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodStarting(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodFinished(); doThrow(new RuntimeException("monkey")) @@ -176,12 +181,14 @@ public void singleMonitor_throwingProducerMonitorSuccess() { monitor.producerMonitorFor(ProducerToken.create(Object.class)); Object o = new Object(); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.succeeded(o); InOrder order = inOrder(mockProducerMonitor); order.verify(mockProducerMonitor).requested(); + order.verify(mockProducerMonitor).dependenciesRequested(); order.verify(mockProducerMonitor).methodStarting(); order.verify(mockProducerMonitor).methodFinished(); order.verify(mockProducerMonitor).succeeded(o); @@ -192,6 +199,7 @@ public void singleMonitor_throwingProducerMonitorSuccess() { public void singleMonitor_throwingProducerMonitorFailure() { setUpNormalSingleMonitor(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).requested(); + doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).dependenciesRequested(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodStarting(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).methodFinished(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitor).failed(any(Throwable.class)); @@ -203,12 +211,14 @@ public void singleMonitor_throwingProducerMonitorFailure() { monitor.producerMonitorFor(ProducerToken.create(Object.class)); Throwable t = new RuntimeException("gorilla"); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.failed(t); InOrder order = inOrder(mockProducerMonitor); order.verify(mockProducerMonitor).requested(); + order.verify(mockProducerMonitor).dependenciesRequested(); order.verify(mockProducerMonitor).methodStarting(); order.verify(mockProducerMonitor).methodFinished(); order.verify(mockProducerMonitor).failed(t); @@ -269,12 +279,14 @@ public void multipleMonitors_someNullProductionComponentMonitors() { Object o = new Object(); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.succeeded(o); InOrder order = inOrder(mockProducerMonitorA); order.verify(mockProducerMonitorA).requested(); + order.verify(mockProducerMonitorA).dependenciesRequested(); order.verify(mockProducerMonitorA).methodStarting(); order.verify(mockProducerMonitorA).methodFinished(); order.verify(mockProducerMonitorA).succeeded(o); @@ -305,12 +317,14 @@ public void multipleMonitors_someThrowingProductionComponentMonitorFactories() { Object o = new Object(); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.succeeded(o); InOrder order = inOrder(mockProducerMonitorA); order.verify(mockProducerMonitorA).requested(); + order.verify(mockProducerMonitorA).dependenciesRequested(); order.verify(mockProducerMonitorA).methodStarting(); order.verify(mockProducerMonitorA).methodFinished(); order.verify(mockProducerMonitorA).succeeded(o); @@ -332,6 +346,7 @@ public void multipleMonitors_normalProductionComponentMonitorSuccess() { Object o = new Object(); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.succeeded(o); @@ -340,6 +355,9 @@ public void multipleMonitors_normalProductionComponentMonitorSuccess() { order.verify(mockProducerMonitorA).requested(); order.verify(mockProducerMonitorB).requested(); order.verify(mockProducerMonitorC).requested(); + order.verify(mockProducerMonitorC).dependenciesRequested(); + order.verify(mockProducerMonitorB).dependenciesRequested(); + order.verify(mockProducerMonitorA).dependenciesRequested(); order.verify(mockProducerMonitorA).methodStarting(); order.verify(mockProducerMonitorB).methodStarting(); order.verify(mockProducerMonitorC).methodStarting(); @@ -367,6 +385,7 @@ public void multipleMonitors_normalProductionComponentMonitorFailure() { Throwable t = new RuntimeException("chimpanzee"); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.failed(t); @@ -375,6 +394,9 @@ public void multipleMonitors_normalProductionComponentMonitorFailure() { order.verify(mockProducerMonitorA).requested(); order.verify(mockProducerMonitorB).requested(); order.verify(mockProducerMonitorC).requested(); + order.verify(mockProducerMonitorC).dependenciesRequested(); + order.verify(mockProducerMonitorB).dependenciesRequested(); + order.verify(mockProducerMonitorA).dependenciesRequested(); order.verify(mockProducerMonitorA).methodStarting(); order.verify(mockProducerMonitorB).methodStarting(); order.verify(mockProducerMonitorC).methodStarting(); @@ -391,6 +413,7 @@ public void multipleMonitors_normalProductionComponentMonitorFailure() { public void multipleMonitors_someThrowingProducerMonitorsSuccess() { setUpNormalMultipleMonitors(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).requested(); + doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).dependenciesRequested(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).methodStarting(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitorB).methodFinished(); doThrow(new RuntimeException("monkey")) @@ -408,6 +431,7 @@ public void multipleMonitors_someThrowingProducerMonitorsSuccess() { Object o = new Object(); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.succeeded(o); @@ -416,6 +440,9 @@ public void multipleMonitors_someThrowingProducerMonitorsSuccess() { order.verify(mockProducerMonitorA).requested(); order.verify(mockProducerMonitorB).requested(); order.verify(mockProducerMonitorC).requested(); + order.verify(mockProducerMonitorC).dependenciesRequested(); + order.verify(mockProducerMonitorB).dependenciesRequested(); + order.verify(mockProducerMonitorA).dependenciesRequested(); order.verify(mockProducerMonitorA).methodStarting(); order.verify(mockProducerMonitorB).methodStarting(); order.verify(mockProducerMonitorC).methodStarting(); @@ -432,6 +459,7 @@ public void multipleMonitors_someThrowingProducerMonitorsSuccess() { public void multipleMonitors_someThrowingProducerMonitorsFailure() { setUpNormalMultipleMonitors(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).requested(); + doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).dependenciesRequested(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitorA).methodStarting(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitorB).methodFinished(); doThrow(new RuntimeException("monkey")).when(mockProducerMonitorC).failed(any(Throwable.class)); @@ -447,6 +475,7 @@ public void multipleMonitors_someThrowingProducerMonitorsFailure() { Throwable t = new RuntimeException("chimpanzee"); producerMonitor.requested(); + producerMonitor.dependenciesRequested(); producerMonitor.methodStarting(); producerMonitor.methodFinished(); producerMonitor.failed(t); @@ -455,6 +484,9 @@ public void multipleMonitors_someThrowingProducerMonitorsFailure() { order.verify(mockProducerMonitorA).requested(); order.verify(mockProducerMonitorB).requested(); order.verify(mockProducerMonitorC).requested(); + order.verify(mockProducerMonitorC).dependenciesRequested(); + order.verify(mockProducerMonitorB).dependenciesRequested(); + order.verify(mockProducerMonitorA).dependenciesRequested(); order.verify(mockProducerMonitorA).methodStarting(); order.verify(mockProducerMonitorB).methodStarting(); order.verify(mockProducerMonitorC).methodStarting();