Skip to content

Commit 1269990

Browse files
committed
chore: handle eventLoop.inEventLoop() case of scheduleSendJobIfNeeded()
1 parent d9727e4 commit 1269990

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

src/main/java/io/lettuce/core/protocol/DefaultBatchFlushEndpoint.java

+14-12
Original file line numberDiff line numberDiff line change
@@ -601,15 +601,17 @@ private void scheduleSendJobOnConnected(final ContextualChannel chan) {
601601
LettuceAssert.assertState(chan.eventLoop().inEventLoop(), "must be called in event loop thread");
602602

603603
// Schedule directly
604-
if (chan.context.batchFlushEndPointContext.hasOngoingSendLoop.tryEnter()) {
605-
loopSend(chan);
606-
}
607-
// Otherwise:
608-
// someone will do the job for us
604+
loopSend(chan, false);
609605
}
610606

611607
private void scheduleSendJobIfNeeded(final ContextualChannel chan) {
612608
final EventLoop eventLoop = chan.eventLoop();
609+
if (eventLoop.inEventLoop()) {
610+
// Possible in reactive() mode.
611+
loopSend(chan, false);
612+
return;
613+
}
614+
613615
if (chan.context.batchFlushEndPointContext.hasOngoingSendLoop.tryEnter()) {
614616
// Benchmark result of using tryEnterSafeGetVolatile() or not (1 thread, async get):
615617
// 1. uses tryEnterSafeGetVolatile() to avoid unnecessary eventLoop.execute() calls
@@ -618,7 +620,7 @@ private void scheduleSendJobIfNeeded(final ContextualChannel chan) {
618620
// 2. uses eventLoop.execute() directly
619621
// Avg latency: 3.2677197021496998s
620622
// Avg QPS: 476925.0751855796/s
621-
eventLoop.execute(() -> loopSend(chan));
623+
eventLoop.execute(() -> loopSend(chan, true));
622624
}
623625

624626
// Otherwise:
@@ -629,19 +631,19 @@ private void scheduleSendJobIfNeeded(final ContextualChannel chan) {
629631
// second loopSend0(), which will call poll()
630632
}
631633

632-
private void loopSend(final ContextualChannel chan) {
634+
private void loopSend(final ContextualChannel chan, boolean entered) {
633635
final ConnectionContext connectionContext = chan.context;
634636
final BatchFlushEndPointContext batchFlushEndPointContext = connectionContext.batchFlushEndPointContext;
635637
if (connectionContext.isChannelInactiveEventFired() || batchFlushEndPointContext.hasRetryableFailedToSendTasks()) {
636638
return;
637639
}
638640

639641
LettuceAssert.assertState(channel == chan, "unexpected: channel not match but closeStatus == null");
640-
loopSend0(batchFlushEndPointContext, chan, writeSpinCount, false);
642+
loopSend0(batchFlushEndPointContext, chan, writeSpinCount, entered);
641643
}
642644

643645
private void loopSend0(final BatchFlushEndPointContext batchFlushEndPointContext, final ContextualChannel chan,
644-
int remainingSpinnCount, final boolean exited) {
646+
int remainingSpinnCount, final boolean entered) {
645647
do {
646648
final int count = pollBatch(batchFlushEndPointContext, chan);
647649
if (count < 0) {
@@ -655,16 +657,16 @@ private void loopSend0(final BatchFlushEndPointContext batchFlushEndPointContext
655657

656658
if (remainingSpinnCount <= 0) {
657659
// Don't need to exitUnsafe since we still have an ongoing consume tasks in this thread.
658-
chan.eventLoop().execute(() -> loopSend(chan));
660+
chan.eventLoop().execute(() -> loopSend(chan, entered));
659661
return;
660662
}
661663

662-
if (!exited) {
664+
if (entered) {
663665
// The send loop will be triggered later when a new task is added,
664666
// // Don't setUnsafe here because loopSend0() may result in a delayed loopSend() call.
665667
batchFlushEndPointContext.hasOngoingSendLoop.exit();
666668
// // Guarantee thread-safety: no dangling tasks in the queue.
667-
loopSend0(batchFlushEndPointContext, chan, remainingSpinnCount, true);
669+
loopSend0(batchFlushEndPointContext, chan, remainingSpinnCount, false);
668670
// chan.eventLoop().schedule(() -> loopSend0(batchFlushEndPointContext, chan, writeSpinCount, false), 100,
669671
// TimeUnit.NANOSECONDS);
670672
}

0 commit comments

Comments
 (0)