Skip to content

Commit 08cefe0

Browse files
committed
prioritization
Signed-off-by: Oleh Dokuka <[email protected]>
1 parent 4e96685 commit 08cefe0

File tree

5 files changed

+529
-8
lines changed

5 files changed

+529
-8
lines changed

rsocket-core/src/main/java/io/rsocket/RSocketRequester.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ class RSocketRequester implements RSocket {
124124
new ClientKeepAliveSupport(allocator, keepAliveTickPeriod, keepAliveAckTimeout);
125125
this.keepAliveFramesAcceptor =
126126
keepAliveHandler.start(
127-
keepAliveSupport, sendProcessor::onNext, this::tryTerminateOnKeepAlive);
127+
keepAliveSupport, sendProcessor::onNextPrioritized, this::tryTerminateOnKeepAlive);
128128
} else {
129129
keepAliveFramesAcceptor = null;
130130
}

rsocket-core/src/main/java/io/rsocket/internal/UnboundedProcessor.java

Lines changed: 57 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import io.netty.util.ReferenceCounted;
2020
import io.rsocket.internal.jctools.queues.MpscUnboundedArrayQueue;
21+
import io.rsocket.internal.jctools.queues.SpscUnboundedArrayQueue;
2122
import java.util.Objects;
2223
import java.util.Queue;
2324
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
@@ -56,6 +57,7 @@ public final class UnboundedProcessor<T> extends FluxProcessor<T, T>
5657
AtomicLongFieldUpdater.newUpdater(UnboundedProcessor.class, "requested");
5758

5859
final Queue<T> queue;
60+
final Queue<T> priorityQueue;
5961
volatile boolean done;
6062
Throwable error;
6163
volatile CoreSubscriber<? super T> actual;
@@ -67,6 +69,7 @@ public final class UnboundedProcessor<T> extends FluxProcessor<T, T>
6769

6870
public UnboundedProcessor() {
6971
this.queue = new MpscUnboundedArrayQueue<>(Queues.SMALL_BUFFER_SIZE);
72+
this.priorityQueue = new SpscUnboundedArrayQueue<>(Queues.SMALL_BUFFER_SIZE);
7073
}
7174

7275
@Override
@@ -84,6 +87,7 @@ void drainRegular(Subscriber<? super T> a) {
8487
int missed = 1;
8588

8689
final Queue<T> q = queue;
90+
final Queue<T> pq = priorityQueue;
8791

8892
for (; ; ) {
8993

@@ -93,10 +97,18 @@ void drainRegular(Subscriber<? super T> a) {
9397
while (r != e) {
9498
boolean d = done;
9599

96-
T t = q.poll();
97-
boolean empty = t == null;
100+
T t;
101+
boolean empty;
102+
103+
if (!pq.isEmpty()) {
104+
t = pq.poll();
105+
empty = false;
106+
} else {
107+
t = q.poll();
108+
empty = t == null;
109+
}
98110

99-
if (checkTerminated(d, empty, a, q)) {
111+
if (checkTerminated(d, empty, a, q, pq)) {
100112
return;
101113
}
102114

@@ -110,7 +122,7 @@ void drainRegular(Subscriber<? super T> a) {
110122
}
111123

112124
if (r == e) {
113-
if (checkTerminated(done, q.isEmpty(), a, q)) {
125+
if (checkTerminated(done, q.isEmpty() && pq.isEmpty(), a, q, pq)) {
114126
return;
115127
}
116128
}
@@ -130,11 +142,13 @@ void drainFused(Subscriber<? super T> a) {
130142
int missed = 1;
131143

132144
final Queue<T> q = queue;
145+
final Queue<T> pq = priorityQueue;
133146

134147
for (; ; ) {
135148

136149
if (cancelled) {
137150
q.clear();
151+
pq.clear();
138152
actual = null;
139153
return;
140154
}
@@ -188,14 +202,21 @@ public void drain() {
188202
}
189203
}
190204

191-
boolean checkTerminated(boolean d, boolean empty, Subscriber<? super T> a, Queue<T> q) {
205+
boolean checkTerminated(
206+
boolean d, boolean empty, Subscriber<? super T> a, Queue<T> q, Queue<T> pq) {
192207
if (cancelled) {
193208
while (!q.isEmpty()) {
194209
T t = q.poll();
195210
if (t != null) {
196211
release(t);
197212
}
198213
}
214+
while (!pq.isEmpty()) {
215+
T t = pq.poll();
216+
if (t != null) {
217+
release(t);
218+
}
219+
}
199220
actual = null;
200221
return true;
201222
}
@@ -237,6 +258,23 @@ public Context currentContext() {
237258
return actual != null ? actual.currentContext() : Context.empty();
238259
}
239260

261+
public void onNextPrioritized(T t) {
262+
if (done || cancelled) {
263+
Operators.onNextDropped(t, currentContext());
264+
release(t);
265+
return;
266+
}
267+
268+
if (!priorityQueue.offer(t)) {
269+
Throwable ex =
270+
Operators.onOperatorError(null, Exceptions.failWithOverflow(), t, currentContext());
271+
onError(Operators.onOperatorError(null, ex, t, currentContext()));
272+
release(t);
273+
return;
274+
}
275+
drain();
276+
}
277+
240278
@Override
241279
public void onNext(T t) {
242280
if (done || cancelled) {
@@ -321,23 +359,29 @@ public void cancel() {
321359

322360
@Override
323361
public T peek() {
362+
if (!priorityQueue.isEmpty()) {
363+
return priorityQueue.peek();
364+
}
324365
return queue.peek();
325366
}
326367

327368
@Override
328369
@Nullable
329370
public T poll() {
371+
if (!priorityQueue.isEmpty()) {
372+
return priorityQueue.poll();
373+
}
330374
return queue.poll();
331375
}
332376

333377
@Override
334378
public int size() {
335-
return queue.size();
379+
return priorityQueue.size() + queue.size();
336380
}
337381

338382
@Override
339383
public boolean isEmpty() {
340-
return queue.isEmpty();
384+
return priorityQueue.isEmpty() && queue.isEmpty();
341385
}
342386

343387
@Override
@@ -348,6 +392,12 @@ public void clear() {
348392
release(t);
349393
}
350394
}
395+
while (!priorityQueue.isEmpty()) {
396+
T t = priorityQueue.poll();
397+
if (t != null) {
398+
release(t);
399+
}
400+
}
351401
}
352402

353403
@Override

0 commit comments

Comments
 (0)