1111import java .text .ParseException ;
1212import java .text .SimpleDateFormat ;
1313import java .util .ArrayList ;
14+ import java .util .Date ;
1415import java .util .List ;
1516import java .util .Random ;
1617import java .util .concurrent .ArrayBlockingQueue ;
@@ -178,7 +179,6 @@ public String toString() { // for debugging only
178179 static final class EventDispatcher {
179180 private static final int MAX_FLUSH_THREADS = 5 ;
180181 private static final int MESSAGE_BATCH_SIZE = 50 ;
181- static final SimpleDateFormat HTTP_DATE_FORMAT = new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss zzz" );
182182
183183 private final LDConfig config ;
184184 private final List <SendEventsTask > flushWorkers ;
@@ -231,8 +231,8 @@ public void uncaughtException(Thread t, Throwable e) {
231231
232232 flushWorkers = new ArrayList <>();
233233 EventResponseListener listener = new EventResponseListener () {
234- public void handleResponse (Response response ) {
235- EventDispatcher .this .handleResponse (response );
234+ public void handleResponse (Response response , Date responseDate ) {
235+ EventDispatcher .this .handleResponse (response , responseDate );
236236 }
237237 };
238238 for (int i = 0 ; i < MAX_FLUSH_THREADS ; i ++) {
@@ -404,13 +404,9 @@ private void triggerFlush(EventBuffer outbox, BlockingQueue<FlushPayload> payloa
404404 }
405405 }
406406
407- private void handleResponse (Response response ) {
408- String dateStr = response .header ("Date" );
409- if (dateStr != null ) {
410- try {
411- lastKnownPastTime .set (HTTP_DATE_FORMAT .parse (dateStr ).getTime ());
412- } catch (ParseException e ) {
413- }
407+ private void handleResponse (Response response , Date responseDate ) {
408+ if (responseDate != null ) {
409+ lastKnownPastTime .set (responseDate .getTime ());
414410 }
415411 if (!isHttpErrorRecoverable (response .code ())) {
416412 disabled .set (true );
@@ -475,7 +471,7 @@ private static final class FlushPayload {
475471 }
476472
477473 private static interface EventResponseListener {
478- void handleResponse (Response response );
474+ void handleResponse (Response response , Date responseDate );
479475 }
480476
481477 private static final class SendEventsTask implements Runnable {
@@ -487,6 +483,7 @@ private static final class SendEventsTask implements Runnable {
487483 private final AtomicBoolean stopping ;
488484 private final EventOutput .Formatter formatter ;
489485 private final Thread thread ;
486+ private final SimpleDateFormat httpDateFormat = new SimpleDateFormat ("EEE, dd MMM yyyy HH:mm:ss zzz" ); // need one instance per task because the date parser isn't thread-safe
490487
491488 SendEventsTask (String sdkKey , LDConfig config , EventResponseListener responseListener ,
492489 BlockingQueue <FlushPayload > payloadQueue , AtomicInteger activeFlushWorkersCount ,
@@ -563,13 +560,25 @@ private void postEvents(List<EventOutput> eventsOut) {
563560 continue ;
564561 }
565562 }
566- responseListener .handleResponse (response );
563+ responseListener .handleResponse (response , getResponseDate ( response ) );
567564 break ;
568565 } catch (IOException e ) {
569566 logger .warn ("Unhandled exception in LaunchDarkly client when posting events to URL: " + request .url (), e );
570567 continue ;
571568 }
572569 }
573570 }
571+
572+ private Date getResponseDate (Response response ) {
573+ String dateStr = response .header ("Date" );
574+ if (dateStr != null ) {
575+ try {
576+ return httpDateFormat .parse (dateStr );
577+ } catch (ParseException e ) {
578+ logger .warn ("Received invalid Date header from events service" );
579+ }
580+ }
581+ return null ;
582+ }
574583 }
575584}
0 commit comments