11import std/ [times, locks, tables, sets, options]
22import chronos, results, chronicles
3- import sds/ [message , protobuf, sds_utils, rolling_bloom_filter]
3+ import sds/ [types , protobuf, sds_utils, rolling_bloom_filter]
44
5- export message , protobuf, sds_utils, rolling_bloom_filter
5+ export types , protobuf, sds_utils, rolling_bloom_filter
66
77proc newReliabilityManager * (
88 config: ReliabilityConfig = defaultConfig ()
99): Result [ReliabilityManager , ReliabilityError ] =
1010 # # Creates a new multi-channel ReliabilityManager.
11- # #
12- # # Parameters:
13- # # - config: Configuration options for the ReliabilityManager. If not provided, default configuration is used.
14- # #
15- # # Returns:
16- # # A Result containing either a new ReliabilityManager instance or an error.
1711 try :
18- let rm = ReliabilityManager (
19- channels: initTable [SdsChannelID , ChannelContext ](), config: config
20- )
21- initLock (rm.lock)
12+ let rm = ReliabilityManager .new (config)
2213 return ok (rm)
2314 except Exception :
2415 error " Failed to create ReliabilityManager" , msg = getCurrentExceptionMsg ()
@@ -38,22 +29,17 @@ proc isAcknowledged*(
3829 false
3930
4031proc reviewAckStatus (rm: ReliabilityManager , msg: SdsMessage ) {.gcsafe .} =
41- # Parse bloom filter
4232 var rbf: Option [RollingBloomFilter ]
4333 if msg.bloomFilter.len > 0 :
4434 let bfResult = deserializeBloomFilter (msg.bloomFilter)
4535 if bfResult.isOk ():
36+ let bf = bfResult.get ()
4637 rbf = some (
47- RollingBloomFilter (
48- filter: bfResult.get (),
49- capacity: bfResult.get ().capacity,
50- minCapacity: (
51- bfResult.get ().capacity.float * (100 - CapacityFlexPercent ).float / 100.0
52- ).int ,
53- maxCapacity: (
54- bfResult.get ().capacity.float * (100 + CapacityFlexPercent ).float / 100.0
55- ).int ,
56- messages: @ [],
38+ RollingBloomFilter .init (
39+ filter = bf,
40+ capacity = bf.capacity,
41+ minCapacity = (bf.capacity.float * (100 - CapacityFlexPercent ).float / 100.0 ).int ,
42+ maxCapacity = (bf.capacity.float * (100 + CapacityFlexPercent ).float / 100.0 ).int ,
5743 )
5844 )
5945 else :
@@ -66,7 +52,6 @@ proc reviewAckStatus(rm: ReliabilityManager, msg: SdsMessage) {.gcsafe.} =
6652 return
6753
6854 let channel = rm.channels[msg.channelId]
69- # Keep track of indices to delete
7055 var toDelete: seq [int ] = @ []
7156 var i = 0
7257
@@ -78,7 +63,7 @@ proc reviewAckStatus(rm: ReliabilityManager, msg: SdsMessage) {.gcsafe.} =
7863 toDelete.add (i)
7964 inc i
8065
81- for i in countdown (toDelete.high, 0 ): # Delete in reverse order to maintain indices
66+ for i in countdown (toDelete.high, 0 ):
8267 channel.outgoingBuffer.delete (toDelete[i])
8368
8469proc wrapOutgoingMessage * (
@@ -88,14 +73,6 @@ proc wrapOutgoingMessage*(
8873 channelId: SdsChannelID ,
8974): Result [seq [byte ], ReliabilityError ] =
9075 # # Wraps an outgoing message with reliability metadata.
91- # #
92- # # Parameters:
93- # # - message: The content of the message to be sent.
94- # # - messageId: Unique identifier for the message
95- # # - channelId: Identifier for the channel this message belongs to.
96- # #
97- # # Returns:
98- # # A Result containing either wrapped message bytes or an error.
9976 if message.len == 0 :
10077 return err (ReliabilityError .reInvalidArgument)
10178 if message.len > MaxMessageSize :
@@ -111,20 +88,19 @@ proc wrapOutgoingMessage*(
11188 error " Failed to serialize bloom filter" , channelId = channelId
11289 return err (ReliabilityError .reSerializationError)
11390
114- let msg = SdsMessage (
115- messageId: messageId,
116- lamportTimestamp: channel.lamportTimestamp,
117- causalHistory: rm.getRecentHistoryEntries (rm.config.maxCausalHistory, channelId),
118- channelId: channelId,
119- content: message,
120- bloomFilter: bfResult.get (),
91+ let msg = SdsMessage . init (
92+ messageId = messageId,
93+ lamportTimestamp = channel.lamportTimestamp,
94+ causalHistory = rm.getRecentHistoryEntries (rm.config.maxCausalHistory, channelId),
95+ channelId = channelId,
96+ content = message,
97+ bloomFilter = bfResult.get (),
12198 )
12299
123100 channel.outgoingBuffer.add (
124- UnacknowledgedMessage (message: msg, sendTime: getTime (), resendAttempts: 0 )
101+ UnacknowledgedMessage . init (message = msg, sendTime = getTime (), resendAttempts = 0 )
125102 )
126103
127- # Add to causal history and bloom filter
128104 channel.bloomFilter.add (msg.messageId)
129105 rm.addToHistory (msg.messageId, channelId)
130106
@@ -147,7 +123,6 @@ proc processIncomingBuffer(rm: ReliabilityManager, channelId: SdsChannelID) {.gc
147123 var processed = initHashSet [SdsMessageID ]()
148124 var readyToProcess = newSeq [SdsMessageID ]()
149125
150- # Find initially ready messages
151126 for msgId, entry in channel.incomingBuffer:
152127 if entry.missingDeps.len == 0 :
153128 readyToProcess.add (msgId)
@@ -163,15 +138,13 @@ proc processIncomingBuffer(rm: ReliabilityManager, channelId: SdsChannelID) {.gc
163138 rm.onMessageReady (msgId, channelId)
164139 processed.incl (msgId)
165140
166- # Update dependencies for remaining messages
167141 for remainingId, entry in channel.incomingBuffer:
168142 if remainingId notin processed:
169143 if msgId in entry.missingDeps:
170144 channel.incomingBuffer[remainingId].missingDeps.excl (msgId)
171145 if channel.incomingBuffer[remainingId].missingDeps.len == 0 :
172146 readyToProcess.add (remainingId)
173147
174- # Remove processed messages
175148 for msgId in processed:
176149 channel.incomingBuffer.del (msgId)
177150
@@ -182,12 +155,6 @@ proc unwrapReceivedMessage*(
182155 ReliabilityError ,
183156] =
184157 # # Unwraps a received message and processes its reliability metadata.
185- # #
186- # # Parameters:
187- # # - message: The received message bytes
188- # #
189- # # Returns:
190- # # A Result containing either tuple of (processed message, missing dependencies, channel ID) or an error.
191158 try :
192159 let channelId = extractChannelId (message).valueOr:
193160 return err (ReliabilityError .reDeserializationError)
@@ -203,7 +170,6 @@ proc unwrapReceivedMessage*(
203170 channel.bloomFilter.add (msg.messageId)
204171
205172 rm.updateLamportTimestamp (msg.lamportTimestamp, channelId)
206- # Review ACK status for outgoing messages
207173 rm.reviewAckStatus (msg)
208174
209175 var missingDeps = rm.checkDependencies (msg.causalHistory, channelId)
@@ -214,19 +180,20 @@ proc unwrapReceivedMessage*(
214180 if msgId in msg.causalHistory.getMessageIds ():
215181 depsInBuffer = true
216182 break
217- # Check if any dependencies are still in incoming buffer
218183 if depsInBuffer:
219184 channel.incomingBuffer[msg.messageId] =
220- IncomingMessage (message: msg, missingDeps: initHashSet [SdsMessageID ]())
185+ IncomingMessage . init (message = msg, missingDeps = initHashSet [SdsMessageID ]())
221186 else :
222- # All dependencies met, add to history
223187 rm.addToHistory (msg.messageId, channelId)
224188 rm.processIncomingBuffer (channelId)
225189 if not rm.onMessageReady.isNil ():
226190 rm.onMessageReady (msg.messageId, channelId)
227191 else :
228192 channel.incomingBuffer[msg.messageId] =
229- IncomingMessage (message: msg, missingDeps: missingDeps.getMessageIds ().toHashSet ())
193+ IncomingMessage .init (
194+ message = msg,
195+ missingDeps = missingDeps.getMessageIds ().toHashSet (),
196+ )
230197 if not rm.onMissingDependencies.isNil ():
231198 rm.onMissingDependencies (msg.messageId, missingDeps, channelId)
232199
@@ -239,13 +206,6 @@ proc markDependenciesMet*(
239206 rm: ReliabilityManager , messageIds: seq [SdsMessageID ], channelId: SdsChannelID
240207): Result [void , ReliabilityError ] =
241208 # # Marks the specified message dependencies as met.
242- # #
243- # # Parameters:
244- # # - messageIds: A sequence of message IDs to mark as met.
245- # # - channelId: Identifier for the channel.
246- # #
247- # # Returns:
248- # # A Result indicating success or an error.
249209 try :
250210 if channelId notin rm.channels:
251211 return err (ReliabilityError .reInvalidArgument)
@@ -273,16 +233,9 @@ proc setCallbacks*(
273233 onMessageSent: MessageSentCallback ,
274234 onMissingDependencies: MissingDependenciesCallback ,
275235 onPeriodicSync: PeriodicSyncCallback = nil ,
276- onRetrievalHint: RetrievalHintProvider = nil
236+ onRetrievalHint: RetrievalHintProvider = nil ,
277237) =
278238 # # Sets the callback functions for various events in the ReliabilityManager.
279- # #
280- # # Parameters:
281- # # - onMessageReady: Callback function called when a message is ready to be processed.
282- # # - onMessageSent: Callback function called when a message is confirmed as sent.
283- # # - onMissingDependencies: Callback function called when a message has missing dependencies.
284- # # - onPeriodicSync: Callback function called to notify about periodic sync
285- # # - onRetrievalHint: Callback function called to get a retrieval hint for a message ID.
286239 withLock rm.lock:
287240 rm.onMessageReady = onMessageReady
288241 rm.onMessageSent = onMessageSent
@@ -293,7 +246,6 @@ proc setCallbacks*(
293246proc checkUnacknowledgedMessages (
294247 rm: ReliabilityManager , channelId: SdsChannelID
295248) {.gcsafe .} =
296- # # Checks and processes unacknowledged messages in the outgoing buffer.
297249 withLock rm.lock:
298250 if channelId notin rm.channels:
299251 error " Channel does not exist" , channelId = channelId
@@ -322,7 +274,6 @@ proc checkUnacknowledgedMessages(
322274proc periodicBufferSweep (
323275 rm: ReliabilityManager
324276) {.async : (raises: [CancelledError ]), gcsafe .} =
325- # # Periodically sweeps the buffer to clean up and check unacknowledged messages.
326277 while true :
327278 try :
328279 for channelId, channel in rm.channels:
@@ -340,7 +291,6 @@ proc periodicBufferSweep(
340291proc periodicSyncMessage (
341292 rm: ReliabilityManager
342293) {.async : (raises: [CancelledError ]), gcsafe .} =
343- # # Periodically notifies to send a sync message to maintain connectivity.
344294 while true :
345295 try :
346296 if not rm.onPeriodicSync.isNil ():
@@ -351,25 +301,20 @@ proc periodicSyncMessage(
351301
352302proc startPeriodicTasks * (rm: ReliabilityManager ) =
353303 # # Starts the periodic tasks for buffer sweeping and sync message sending.
354- # #
355- # # This procedure should be called after creating a ReliabilityManager to enable automatic maintenance.
356304 asyncSpawn rm.periodicBufferSweep ()
357305 asyncSpawn rm.periodicSyncMessage ()
358306
359307proc resetReliabilityManager * (rm: ReliabilityManager ): Result [void , ReliabilityError ] =
360308 # # Resets the ReliabilityManager to its initial state.
361- # #
362- # # This procedure clears all buffers and resets the Lamport timestamp.
363309 withLock rm.lock:
364310 try :
365311 for channelId, channel in rm.channels:
366312 channel.lamportTimestamp = 0
367313 channel.messageHistory.setLen (0 )
368314 channel.outgoingBuffer.setLen (0 )
369315 channel.incomingBuffer.clear ()
370- channel.bloomFilter = newRollingBloomFilter (
371- rm.config.bloomFilterCapacity, rm.config.bloomFilterErrorRate
372- )
316+ channel.bloomFilter =
317+ RollingBloomFilter .init (rm.config.bloomFilterCapacity, rm.config.bloomFilterErrorRate)
373318 rm.channels.clear ()
374319 return ok ()
375320 except Exception :
0 commit comments