44import io .sentry .DataCategory ;
55import io .sentry .ISentryClient ;
66import io .sentry .ISentryExecutorService ;
7- import io .sentry .ISentryLifecycleToken ;
87import io .sentry .SentryExecutorService ;
98import io .sentry .SentryLevel ;
109import io .sentry .SentryLogEvent ;
1110import io .sentry .SentryLogEvents ;
1211import io .sentry .SentryOptions ;
1312import io .sentry .clientreport .DiscardReason ;
1413import io .sentry .transport .ReusableCountLatch ;
15- import io .sentry .util .AutoClosableReentrantLock ;
1614import io .sentry .util .JsonSerializationUtils ;
1715import java .util .ArrayList ;
1816import java .util .List ;
1917import java .util .Queue ;
2018import java .util .concurrent .ConcurrentLinkedQueue ;
21- import java .util .concurrent .Future ;
2219import java .util .concurrent .RejectedExecutionException ;
2320import java .util .concurrent .TimeUnit ;
21+ import java .util .concurrent .atomic .AtomicBoolean ;
2422import org .jetbrains .annotations .ApiStatus ;
2523import org .jetbrains .annotations .NotNull ;
2624import org .jetbrains .annotations .Nullable ;
@@ -37,9 +35,7 @@ public class LoggerBatchProcessor implements ILoggerBatchProcessor {
3735 private final @ NotNull ISentryClient client ;
3836 private final @ NotNull Queue <SentryLogEvent > queue ;
3937 private final @ NotNull ISentryExecutorService executorService ;
40- private volatile @ Nullable Future <?> scheduledFlush ;
41- private final @ NotNull AutoClosableReentrantLock scheduleLock = new AutoClosableReentrantLock ();
42- private volatile boolean hasScheduled = false ;
38+ private final @ NotNull AtomicBoolean hasScheduled = new AtomicBoolean (false );
4339 private volatile boolean isShuttingDown = false ;
4440
4541 private final @ NotNull ReusableCountLatch pendingCount = new ReusableCountLatch ();
@@ -79,15 +75,15 @@ public void add(final @NotNull SentryLogEvent logEvent) {
7975 }
8076 pendingCount .increment ();
8177 queue .offer (logEvent );
82- maybeSchedule (false , false );
78+ maybeSchedule (false );
8379 }
8480
8581 @ SuppressWarnings ("FutureReturnValueIgnored" )
8682 @ Override
8783 public void close (final boolean isRestarting ) {
8884 isShuttingDown = true ;
8985 if (isRestarting ) {
90- maybeSchedule (true , true );
86+ maybeSchedule (true );
9187 executorService .submit (() -> executorService .close (options .getShutdownTimeoutMillis ()));
9288 } else {
9389 executorService .close (options .getShutdownTimeoutMillis ());
@@ -97,33 +93,28 @@ public void close(final boolean isRestarting) {
9793 }
9894 }
9995
100- private void maybeSchedule (boolean forceSchedule , boolean immediately ) {
101- if (hasScheduled && !forceSchedule ) {
96+ @ SuppressWarnings ("FutureReturnValueIgnored" )
97+ private void maybeSchedule (boolean immediately ) {
98+ if (immediately ) {
99+ // any already scheduled task may be far in the future, we want to schedule something that
100+ // runs right away
101+ hasScheduled .set (true );
102+ } else if (!hasScheduled .compareAndSet (false , true )) {
103+ // was already true, no need to schedule again
102104 return ;
103105 }
104- try (final @ NotNull ISentryLifecycleToken ignored = scheduleLock .acquire ()) {
105- final @ Nullable Future <?> latestScheduledFlush = scheduledFlush ;
106- if (forceSchedule
107- || latestScheduledFlush == null
108- || latestScheduledFlush .isDone ()
109- || latestScheduledFlush .isCancelled ()) {
110- hasScheduled = true ;
111- final int flushAfterMs = immediately ? 0 : FLUSH_AFTER_MS ;
112- try {
113- scheduledFlush = executorService .schedule (new BatchRunnable (), flushAfterMs );
114- } catch (RejectedExecutionException e ) {
115- hasScheduled = false ;
116- options
117- .getLogger ()
118- .log (SentryLevel .WARNING , "Logs batch processor flush task rejected" , e );
119- }
120- }
106+ final int flushAfterMs = immediately ? 0 : FLUSH_AFTER_MS ;
107+ try {
108+ executorService .schedule (new BatchRunnable (), flushAfterMs );
109+ } catch (RejectedExecutionException e ) {
110+ hasScheduled .set (false );
111+ options .getLogger ().log (SentryLevel .WARNING , "Logs batch processor flush task rejected" , e );
121112 }
122113 }
123114
124115 @ Override
125116 public void flush (long timeoutMillis ) {
126- maybeSchedule (true , true );
117+ maybeSchedule (true );
127118 try {
128119 pendingCount .waitTillZero (timeoutMillis , TimeUnit .MILLISECONDS );
129120 } catch (InterruptedException e ) {
@@ -134,12 +125,9 @@ public void flush(long timeoutMillis) {
134125
135126 private void flush () {
136127 flushInternal ();
137- try (final @ NotNull ISentryLifecycleToken ignored = scheduleLock .acquire ()) {
138- if (!queue .isEmpty ()) {
139- maybeSchedule (true , false );
140- } else {
141- hasScheduled = false ;
142- }
128+ hasScheduled .set (false );
129+ if (!queue .isEmpty ()) {
130+ maybeSchedule (false );
143131 }
144132 }
145133
0 commit comments