2424import java .util .Arrays ;
2525import java .util .Collection ;
2626import java .util .List ;
27- import java .util .concurrent .CompletableFuture ;
28- import java .util .concurrent .ConcurrentHashMap ;
29- import java .util .concurrent .TimeUnit ;
27+ import java .util .concurrent .*;
28+ import java .util .concurrent .atomic .AtomicReference ;
3029import java .util .concurrent .locks .ReentrantLock ;
3130
3231import static io .nats .client .support .ApiConstants .*;
@@ -50,19 +49,22 @@ public class Service {
5049 private final ConcurrentHashMap <String , EndpointContext > serviceContexts ;
5150 private final List <EndpointContext > discoveryContexts ;
5251 private final List <Dispatcher > dInternals ;
52+ private final AtomicReference <ZonedDateTime > startTimeRef ;
53+ private final CompletableFuture <Boolean > startedFuture ;
5354 private final PingResponse pingResponse ;
5455 private final InfoResponse infoResponse ;
5556
5657 private final ReentrantLock startStopLock ;
5758 private CompletableFuture <Boolean > runningIndicator ;
58- private ZonedDateTime started ;
5959
6060 Service (ServiceBuilder b ) {
6161 String id = new io .nats .client .NUID ().next ();
6262 conn = b .conn ;
6363 drainTimeout = b .drainTimeout ;
6464 dInternals = new ArrayList <>();
6565 startStopLock = new ReentrantLock ();
66+ startTimeRef = new AtomicReference <>(DateTimeUtils .DEFAULT_TIME );
67+ startedFuture = new CompletableFuture <>();
6668
6769 // build responses first. info needs to be available when adding service endpoints.
6870 pingResponse = new PingResponse (id , b .name , b .version , b .metadata );
@@ -189,7 +191,8 @@ public CompletableFuture<Boolean> startService() {
189191 for (EndpointContext ctx : discoveryContexts ) {
190192 ctx .start ();
191193 }
192- started = DateTimeUtils .gmtNow ();
194+ startTimeRef .set (DateTimeUtils .gmtNow ());
195+ startedFuture .complete (true );
193196 }
194197 return runningIndicator ;
195198 }
@@ -302,7 +305,10 @@ public void stop(boolean drain, Throwable t) {
302305 * Reset the statistics for the endpoints
303306 */
304307 public void reset () {
305- started = DateTimeUtils .gmtNow ();
308+ if (isStarted ()) {
309+ // has actually been started if the ref has been set
310+ startTimeRef .set (DateTimeUtils .gmtNow ());
311+ }
306312 for (EndpointContext c : discoveryContexts ) {
307313 c .reset ();
308314 }
@@ -343,6 +349,33 @@ public String getDescription() {
343349 return infoResponse .getDescription ();
344350 }
345351
352+ /**
353+ * Get whether the service has full started
354+ * @return true if started
355+ */
356+ public boolean isStarted () {
357+ return startedFuture .isDone ();
358+ }
359+
360+ /**
361+ * Get
362+ * @param timeout the maximum time to wait
363+ * @param unit the time unit of the timeout argument
364+ * @return true if started by the timeout
365+ */
366+ public boolean isStarted (long timeout , TimeUnit unit ) {
367+ try {
368+ return startedFuture .get (timeout , unit );
369+ }
370+ catch (InterruptedException e ) {
371+ Thread .currentThread ().interrupt ();
372+ return false ;
373+ }
374+ catch (ExecutionException | TimeoutException e ) {
375+ return false ;
376+ }
377+ }
378+
346379 /**
347380 * Get the drain timeout setting
348381 * @return the drain timeout setting
@@ -376,7 +409,8 @@ public StatsResponse getStatsResponse() {
376409 for (EndpointContext c : serviceContexts .values ()) {
377410 endpointStats .add (c .getEndpointStats ());
378411 }
379- return new StatsResponse (pingResponse , started , endpointStats );
412+ // StatsResponse handles a start time of DateTimeUtils.DEFAULT_TIME
413+ return new StatsResponse (pingResponse , startTimeRef .get (), endpointStats );
380414 }
381415
382416 /**
@@ -396,6 +430,7 @@ public String toString() {
396430 JsonUtils .addField (sb , NAME , infoResponse .getName ());
397431 JsonUtils .addField (sb , VERSION , infoResponse .getVersion ());
398432 JsonUtils .addField (sb , DESCRIPTION , infoResponse .getDescription ());
433+ JsonUtils .addField (sb , STARTED , startTimeRef .get ());
399434 return endJson (sb ).toString ();
400435 }
401436}
0 commit comments