@@ -356,8 +356,8 @@ evictOldestAckedIds = \items n ->
356356 in diff items toEvict
357357
358358safeCompareLoop = \s1 s2 n result ->
359− if n <= 0
360− then result + (if s1 == s2 then 0 else 1)
359+ if n <= 0 && s1 == "" && s2 == ""
360+ then result
361361 else safeCompareLoop (drop 1 s1) (drop 1 s2) (n - 1) (result + (if take 1 s1 == take 1 s2 then 0 else 1))
362362
363363safeCompare = \a b ->
@@ -759,11 +759,17 @@ serve = \req -> case req of
759759 let finalStatus = if result.status == "federated" && (federationSecret == "" || result.forwardsAtCapacity) then "queued" else result.status
760760 respond {status: finalStatus, messageId: (if result.status == "unauthorized" then "" else if result.status == "invalid" then "" else if result.status == "rejected" then "" else msgId)}
761761 if count result.remoteServers > 0 && not (result.status == "unauthorized") && not (result.status == "invalid") && not (result.status == "rejected") && not (federationSecret == "")
762− then sendToEach result.remoteServers (\server ->
762+ then sendToEach result.remoteServers (\server -> do
763763 fetch (federationScheme ++ server) (ForwardMessage {
764764 toKey: to, fromKey: result.fromKey, encryptedBlob: encryptedBlob,
765765 timestamp: clampedTs, originServer: serverHostN, messageId: msgId,
766− authorization: "Bearer " ++ federationSecret}))
766+ authorization: "Bearer " ++ federationSecret})
767+ atomic do
768+ forwards <- *forwards
769+ set *forwards = do
770+ x <- forwards
771+ where not (x.messageId == msgId && x.toServer == server)
772+ yield x)
767773 else yield {}
768774 if result.forwardsAtCapacity && count result.remoteServers > 0 && not (result.status == "unauthorized") && not (result.status == "invalid") && not (result.status == "rejected")
769775 then println ("sendMessage: forwards at capacity (" ++ show maxForwardsEntries ++ "), skipping forward tracking")
@@ -851,9 +857,10 @@ serve = \req -> case req of
851857 ackedIds <- *ackedIds
852858 let reinsert = do a <- evictedToRetry; where a.originServer == server; yield a
853859 let available = maxAckedIds - count ackedIds
854− let limitedReinsert = if available >= count reinsert then reinsert
855− else fold (\acc x -> if count acc >= available then acc else union acc [x]) [] reinsert
856− set *ackedIds = union ackedIds limitedReinsert))
860+ let needed = count reinsert - available
861+ let afterEvict = if needed <= 0 then ackedIds
862+ else evictOldestAckedIds ackedIds needed
863+ set *ackedIds = union afterEvict reinsert))
857864 else yield {}
858865 broadcastOfflineGossip t result.peerServers result.expiredLocal
859866