mirror of
https://github.com/logos-messaging/nim-sds.git
synced 2026-01-04 15:13:08 +00:00
96 lines
3.2 KiB
Nim
96 lines
3.2 KiB
Nim
import std/[times, locks]
|
|
import ./[rolling_bloom_filter, message]
|
|
|
|
type
|
|
PeriodicSyncCallback* = proc() {.gcsafe, raises: [].}
|
|
|
|
ReliabilityConfig* = object
|
|
bloomFilterCapacity*: int
|
|
bloomFilterErrorRate*: float
|
|
maxMessageHistory*: int
|
|
maxCausalHistory*: int
|
|
resendInterval*: times.Duration
|
|
maxResendAttempts*: int
|
|
syncMessageInterval*: times.Duration
|
|
bufferSweepInterval*: times.Duration
|
|
|
|
ReliabilityManager* = ref object
|
|
lamportTimestamp*: int64
|
|
messageHistory*: seq[MessageID]
|
|
bloomFilter*: RollingBloomFilter
|
|
outgoingBuffer*: seq[UnacknowledgedMessage]
|
|
incomingBuffer*: seq[Message]
|
|
channelId*: string
|
|
config*: ReliabilityConfig
|
|
lock*: Lock
|
|
onMessageReady*: proc(messageId: MessageID) {.gcsafe.}
|
|
onMessageSent*: proc(messageId: MessageID) {.gcsafe.}
|
|
onMissingDependencies*: proc(messageId: MessageID, missingDeps: seq[MessageID]) {.gcsafe.}
|
|
onPeriodicSync*: PeriodicSyncCallback
|
|
|
|
ReliabilityError* {.pure.} = enum
|
|
reInvalidArgument
|
|
reOutOfMemory
|
|
reInternalError
|
|
reSerializationError
|
|
reDeserializationError
|
|
reMessageTooLarge
|
|
|
|
proc defaultConfig*(): ReliabilityConfig =
|
|
## Creates a default configuration for the ReliabilityManager.
|
|
##
|
|
## Returns:
|
|
## A ReliabilityConfig object with default values.
|
|
ReliabilityConfig(
|
|
bloomFilterCapacity: DefaultBloomFilterCapacity,
|
|
bloomFilterErrorRate: DefaultBloomFilterErrorRate,
|
|
maxMessageHistory: DefaultMaxMessageHistory,
|
|
maxCausalHistory: DefaultMaxCausalHistory,
|
|
resendInterval: DefaultResendInterval,
|
|
maxResendAttempts: DefaultMaxResendAttempts,
|
|
syncMessageInterval: DefaultSyncMessageInterval,
|
|
bufferSweepInterval: DefaultBufferSweepInterval
|
|
)
|
|
|
|
proc cleanup*(rm: ReliabilityManager) {.raises: [].} =
|
|
if not rm.isNil():
|
|
{.gcsafe.}:
|
|
try:
|
|
withLock rm.lock:
|
|
rm.outgoingBuffer.setLen(0)
|
|
rm.incomingBuffer.setLen(0)
|
|
rm.messageHistory.setLen(0)
|
|
except ValueError as e:
|
|
logError("Error during cleanup: " & e.msg)
|
|
except Exception:
|
|
logError("Error during cleanup: " & getCurrentExceptionMsg())
|
|
|
|
proc cleanBloomFilter*(rm: ReliabilityManager) {.gcsafe, raises: [].} =
|
|
withLock rm.lock:
|
|
try:
|
|
rm.bloomFilter.clean()
|
|
except Exception:
|
|
logError("Failed to clean ReliabilityManager bloom filter: " & getCurrentExceptionMsg())
|
|
|
|
proc addToHistory*(rm: ReliabilityManager, msgId: MessageID) {.gcsafe, raises: [].} =
|
|
rm.messageHistory.add(msgId)
|
|
if rm.messageHistory.len > rm.config.maxMessageHistory:
|
|
rm.messageHistory.delete(0)
|
|
|
|
proc updateLamportTimestamp*(rm: ReliabilityManager, msgTs: int64) {.gcsafe, raises: [].} =
|
|
rm.lamportTimestamp = max(msgTs, rm.lamportTimestamp) + 1
|
|
|
|
proc getRecentMessageIDs*(rm: ReliabilityManager, n: int): seq[MessageID] =
|
|
result = rm.messageHistory[max(0, rm.messageHistory.len - n) .. ^1]
|
|
|
|
proc getMessageHistory*(rm: ReliabilityManager): seq[MessageID] =
|
|
withLock rm.lock:
|
|
result = rm.messageHistory
|
|
|
|
proc getOutgoingBuffer*(rm: ReliabilityManager): seq[UnacknowledgedMessage] =
|
|
withLock rm.lock:
|
|
result = rm.outgoingBuffer
|
|
|
|
proc getIncomingBuffer*(rm: ReliabilityManager): seq[Message] =
|
|
withLock rm.lock:
|
|
result = rm.incomingBuffer |