9
9
import io .scalecube .cluster2 .MemberCodec ;
10
10
import io .scalecube .cluster2 .sbe .GossipMessageDecoder ;
11
11
import io .scalecube .cluster2 .sbe .GossipRequestDecoder ;
12
- import io .scalecube .cluster2 .sbe .GossipRequestDecoder .GossipsDecoder ;
13
12
import io .scalecube .cluster2 .sbe .MembershipEventDecoder ;
14
13
import io .scalecube .cluster2 .sbe .MembershipEventType ;
15
14
import io .scalecube .cluster2 .sbe .MessageHeaderDecoder ;
@@ -36,7 +35,8 @@ public class GossipProtocol extends AbstractAgent {
36
35
private final GossipMessageDecoder gossipMessageDecoder = new GossipMessageDecoder ();
37
36
private final GossipRequestDecoder gossipRequestDecoder = new GossipRequestDecoder ();
38
37
private final MembershipEventDecoder membershipEventDecoder = new MembershipEventDecoder ();
39
- private final GossipCodec codec = new GossipCodec ();
38
+ private final GossipRequestCodec gossipRequestCodec = new GossipRequestCodec ();
39
+ private final GossipCodec gossipCodec = new GossipCodec ();
40
40
private final MemberCodec memberCodec = new MemberCodec ();
41
41
private final UnsafeBuffer unsafeBuffer = new UnsafeBuffer ();
42
42
private final String roleName ;
@@ -46,6 +46,7 @@ public class GossipProtocol extends AbstractAgent {
46
46
private final Map <String , GossipState > gossips = new Object2ObjectHashMap <>();
47
47
private final List <Member > remoteMembers = new ArrayList <>();
48
48
private final List <Member > gossipMembers = new ArrayList <>();
49
+ private final List <Gossip > gossipsToSend = new ArrayList <>();
49
50
private final List <String > gossipsToRemove = new ArrayList <>();
50
51
51
52
public GossipProtocol (
@@ -86,7 +87,7 @@ protected void onTick() {
86
87
nextGossipMembers ();
87
88
88
89
for (int i = 0 , n = gossipMembers .size (); i < n ; i ++) {
89
- spreadGossipsTo (period , gossipMembers .get (i ));
90
+ spreadGossips (period , gossipMembers .get (i ));
90
91
}
91
92
92
93
// Sweep gossips
@@ -142,6 +143,33 @@ private void checkGossipSegmentation() {
142
143
}
143
144
}
144
145
146
+ private void spreadGossips (long period , Member member ) {
147
+ nextGossipsToSend (period , member );
148
+
149
+ final String address = member .address ();
150
+ final UUID from = localMember .id ();
151
+
152
+ for (int i = 0 , n = gossipsToSend .size (); i < n ; i ++) {
153
+ final Gossip gossip = gossipsToSend .get (i );
154
+ transport .send (
155
+ address , gossipRequestCodec .encode (from , gossip ), 0 , gossipRequestCodec .encodedLength ());
156
+ }
157
+ }
158
+
159
+ private void nextGossipsToSend (long period , Member member ) {
160
+ gossipsToSend .clear ();
161
+
162
+ final int periodsToSpread =
163
+ ClusterMath .gossipPeriodsToSpread (config .gossipRepeatMult (), remoteMembers .size () + 1 );
164
+
165
+ for (final GossipState gossipState : gossips .values ()) {
166
+ if (gossipState .infectionPeriod () + periodsToSpread >= period
167
+ && !gossipState .isInfected (member .id ())) {
168
+ gossipsToSend .add (gossipState .gossip ());
169
+ }
170
+ }
171
+ }
172
+
145
173
@ Override
146
174
public void onMessage (int msgTypeId , MutableDirectBuffer buffer , int index , int length ) {
147
175
headerDecoder .wrap (buffer , index );
@@ -180,20 +208,20 @@ private void onGossipRequest(GossipRequestDecoder decoder) {
180
208
final long period = currentPeriod ;
181
209
final UUID from = uuid (decoder .from ());
182
210
183
- for (GossipsDecoder gossipsDecoder : decoder .gossips ()) {
184
- final Gossip gossip = codec .gossip (gossipsDecoder ::wrapGossip );
185
- GossipState gossipState = gossips .get (gossip .gossipId ());
186
- if (ensureSequence (gossip .gossiperId ()).add (gossip .sequenceId ())) {
187
- if (gossipState == null ) { // new gossip
188
- gossipState = new GossipState (gossip , period );
189
- gossips .put (gossip .gossipId (), gossipState );
190
- emitGossipMessage (gossip .message ());
191
- }
192
- }
193
- if (gossipState != null ) {
194
- gossipState .addToInfected (from );
211
+ final Gossip gossip = gossipCodec .gossip (decoder ::wrapGossip );
212
+ GossipState gossipState = gossips .get (gossip .gossipId ());
213
+
214
+ if (ensureSequence (gossip .gossiperId ()).add (gossip .sequenceId ())) {
215
+ if (gossipState == null ) { // new gossip
216
+ gossipState = new GossipState (gossip , period );
217
+ gossips .put (gossip .gossipId (), gossipState );
218
+ emitGossipMessage (gossip .message ());
195
219
}
196
220
}
221
+
222
+ if (gossipState != null ) {
223
+ gossipState .addToInfected (from );
224
+ }
197
225
}
198
226
199
227
private void emitGossipMessage (byte [] message ) {
0 commit comments