15
15
16
16
import java .util .concurrent .atomic .AtomicLong ;
17
17
18
+ /**
19
+ * Contract to determine when a subscription provides credits to get more messages.
20
+ *
21
+ * <p>The broker delivers "chunks" of messages to consumers. A chunk can contain from 1 to several
22
+ * thousands of messages. The broker send chunks as long as the subscription has <em>credits</em>. A
23
+ * client connection can provide credits for a given subscription and the broker will send the
24
+ * corresponding number of chunks (1 credit = 1 chunk).
25
+ *
26
+ * <p>This credit mechanism avoids overwhelming a consumer with messages. A consumer does not want
27
+ * to provide a credit only when it is done with messages of a chunk, because it will be idle
28
+ * between its credit request and the arrival of the next chunk. The idea is to keep consumers busy
29
+ * as much as possible, without accumulating an in-memory backlog on the client side. There is no
30
+ * ideal solution, it depends on the use cases and several parameters (processing time, network,
31
+ * etc).
32
+ *
33
+ * @since 0.12.0
34
+ * @see MessageHandler.Context#processed()
35
+ * @see ConsumerBuilder#flow()
36
+ */
18
37
public interface ConsumerFlowStrategy {
19
38
39
+ /**
40
+ * The initial number of credits for a subscription.
41
+ *
42
+ * <p>It must be greater than 0. Values are usually between 1 and 10.
43
+ *
44
+ * @return initial number of credits
45
+ */
20
46
int initialCredits ();
21
47
48
+ /**
49
+ * Return the behavior for {@link MessageHandler.Context#processed()} calls.
50
+ *
51
+ * <p>This method is called for each chunk of messages. Implementations return a callback that
52
+ * will be called when applications consider a message dealt with and call {@link
53
+ * MessageHandler.Context#processed()}. The callback can count messages and provide credits
54
+ * accordingly.
55
+ *
56
+ * @param context chunk context
57
+ * @return the message processed callback
58
+ */
22
59
MessageProcessedCallback start (Context context );
23
60
61
+ /** Chunk context. */
24
62
interface Context {
25
63
64
+ /**
65
+ * Provide credits for the subscription.
66
+ *
67
+ * <p>{@link ConsumerFlowStrategy} implementation should always provide 1 credit a given chunk.
68
+ *
69
+ * @param credits the number of credits provided, usually 1
70
+ */
26
71
void credits (int credits );
27
72
73
+ /**
74
+ * The number of messages in the chunk.
75
+ *
76
+ * @return number of messages in the chunk
77
+ */
28
78
long messageCount ();
29
79
}
30
80
81
+ /** Behavior for {@link MessageHandler.Context#processed()} calls. */
31
82
@ FunctionalInterface
32
83
interface MessageProcessedCallback {
33
84
85
+ /**
86
+ * Method called when {@link MessageHandler.Context#processed()} is called.
87
+ *
88
+ * <p>There is one instance of this class for a given chunk and it is called for the <code>
89
+ * processed()</code> calls of the message of this chunk.
90
+ *
91
+ * <p>Implementations can count messages and call {@link Context#credits(int)} when appropriate.
92
+ *
93
+ * <p>Note calls to {@link MessageHandler.Context#processed()} are not idempotent: an
94
+ * application can call the method several times for the same message and implementations must
95
+ * deal with these multiple calls if they impact their logic.
96
+ *
97
+ * @param messageContext context of the message
98
+ */
34
99
void processed (MessageHandler .Context messageContext );
35
100
}
36
101
102
+ /**
103
+ * Strategy that provides 1 initial credit and a credit on each new chunk.
104
+ *
105
+ * <p>Calls to {@link MessageHandler.Context#processed()} are ignored.
106
+ *
107
+ * @return flow strategy
108
+ */
37
109
static ConsumerFlowStrategy creditOnChunkArrival () {
38
110
return creditOnChunkArrival (1 );
39
111
}
40
112
113
+ /**
114
+ * Strategy that provides the specified number of initial credits and a credit on each new chunk.
115
+ *
116
+ * <p>Calls to {@link MessageHandler.Context#processed()} are ignored.
117
+ *
118
+ * @param initialCredits number of initial credits
119
+ * @return flow strategy
120
+ */
41
121
static ConsumerFlowStrategy creditOnChunkArrival (int initialCredits ) {
42
122
return new CreditOnChunkArrivalConsumerFlowStrategy (initialCredits );
43
123
}
44
124
125
+ /**
126
+ * Strategy that provides 1 initial credit and a credit when half of the chunk messages are
127
+ * processed.
128
+ *
129
+ * <p>Make sure to call {@link MessageHandler.Context#processed()} on every message when using
130
+ * this strategy, otherwise the broker may stop sending messages to the consumer.
131
+ *
132
+ * @return flow strategy
133
+ */
45
134
static ConsumerFlowStrategy creditWhenHalfMessagesProcessed () {
46
135
return creditOnProcessedMessageCount (1 , 0.5 );
47
136
}
48
137
138
+ /**
139
+ * Strategy that provides the specified number of initial credits and a credit when half of the
140
+ * chunk messages are processed.
141
+ *
142
+ * <p>Make sure to call {@link MessageHandler.Context#processed()} on every message when using
143
+ * this strategy, otherwise the broker may stop sending messages to the consumer.
144
+ *
145
+ * @param initialCredits number of initial credits
146
+ * @return flow strategy
147
+ */
49
148
static ConsumerFlowStrategy creditWhenHalfMessagesProcessed (int initialCredits ) {
50
149
return creditOnProcessedMessageCount (initialCredits , 0.5 );
51
150
}
52
151
152
+ /**
153
+ * Strategy that provides the specified number of initial credits and a credit when the specified
154
+ * ratio of the chunk messages are processed.
155
+ *
156
+ * <p>Make sure to call {@link MessageHandler.Context#processed()} on every message when using
157
+ * this strategy, otherwise the broker may stop sending messages to the consumer.
158
+ *
159
+ * @param initialCredits number of initial credits
160
+ * @return flow strategy
161
+ */
53
162
static ConsumerFlowStrategy creditOnProcessedMessageCount (int initialCredits , double ratio ) {
54
163
return new MessageCountConsumerFlowStrategy (initialCredits , ratio );
55
164
}
56
165
166
+ /**
167
+ * Strategy that provides the specified number of initial credits and a credit on each new chunk.
168
+ *
169
+ * <p>Calls to {@link MessageHandler.Context#processed()} are ignored.
170
+ */
57
171
class CreditOnChunkArrivalConsumerFlowStrategy implements ConsumerFlowStrategy {
58
172
59
173
private final int initialCredits ;
@@ -74,6 +188,13 @@ public MessageProcessedCallback start(Context context) {
74
188
}
75
189
}
76
190
191
+ /**
192
+ * Strategy that provides the specified number of initial credits and a credit when the specified
193
+ * ratio of the chunk messages are processed.
194
+ *
195
+ * <p>Make sure to call {@link MessageHandler.Context#processed()} on every message when using
196
+ * this strategy, otherwise the broker may stop sending messages to the consumer.
197
+ */
77
198
class MessageCountConsumerFlowStrategy implements ConsumerFlowStrategy {
78
199
79
200
private final int initialCredits ;
0 commit comments