@@ -356,8 +356,8 @@ evictOldestAckedIds = \items n ->
356 in diff items toEvict
356 in diff items toEvict
358safeCompareLoop = \s1 s2 n result ->
358safeCompareLoop = \s1 s2 n result ->
359− if n <= 0 && s1 == "" && s2 == ""
359+ if n <= 0
360− then result
360+ then result + (if s1 == s2 then 0 else 1)
361 else safeCompareLoop (drop 1 s1) (drop 1 s2) (n - 1) (result + (if take 1 s1 == take 1 s2 then 0 else 1))
361 else safeCompareLoop (drop 1 s1) (drop 1 s2) (n - 1) (result + (if take 1 s1 == take 1 s2 then 0 else 1))
363safeCompare = \a b ->
363safeCompare = \a b ->
@@ -474,7 +474,12 @@ retryPendingForwards = \pending ->
474 toKey: f.toKey, fromKey: f.fromKey, encryptedBlob: f.encryptedBlob,
474 toKey: f.toKey, fromKey: f.fromKey, encryptedBlob: f.encryptedBlob,
475 timestamp: f.timestamp, originServer: serverHostN, messageId: f.messageId,
475 timestamp: f.timestamp, originServer: serverHostN, messageId: f.messageId,
476 authorization: "Bearer " ++ federationSecret})
476 authorization: "Bearer " ++ federationSecret})
478+ forwards <- *forwards
481+ where not (x.messageId == f.messageId && x.toServer == f.toServer)
477− yield {}) (\err ->
482+ yield x) (\err ->
478 println ("prune: retry forward to " ++ f.toServer ++ " failed: " ++ show err))
483 println ("prune: retry forward to " ++ f.toServer ++ " failed: " ++ show err))
479 retryPendingForwards rest
484 retryPendingForwards rest
@@ -825,23 +830,30 @@ serve = \req -> case req of
825 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
830 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
826 sendAcksAndClean pendingAcks originServers
831 sendAcksAndClean pendingAcks originServers
827 else yield {}
832 else yield {}
833+ let evictedToRetry = do
828− if count result.evictedEntries > 0 && not (federationSecret == "")
834+ a <- result.evictedEntries
835+ where count (do m <- fedMessages; where m.messageId == a.messageId; where m.toKey == a.toKey; yield m) == 0
837+ if count evictedToRetry > 0 && not (federationSecret == "")
830 let evictedOriginServers = fold (\acc a ->
839 let evictedOriginServers = fold (\acc a ->
831 if count (do s <- acc; where s == a.originServer; yield s) > 0 then acc
840 if count (do s <- acc; where s == a.originServer; yield s) > 0 then acc
832− else union acc [a.originServer]) [] result.evictedEntries
841+ else union acc [a.originServer]) [] evictedToRetry
833 sendToEach evictedOriginServers (\server ->
842 sendToEach evictedOriginServers (\server ->
834 catch (do
843 catch (do
835 fetch (federationScheme ++ server) (FederationAck {
844 fetch (federationScheme ++ server) (FederationAck {
836 authorization: "Bearer " ++ federationSecret,
845 authorization: "Bearer " ++ federationSecret,
837− messageIds: (do a <- result.evictedEntries; where a.originServer == server; yield a.messageId),
846+ messageIds: (do a <- evictedToRetry; where a.originServer == server; yield a.messageId),
838 originServer: server, fromServer: serverHostN})
847 originServer: server, fromServer: serverHostN})
839 yield {}) (\err -> do
848 yield {}) (\err -> do
840 println ("federation: error sending evicted ack to " ++ server ++ ": " ++ show err)
849 println ("federation: error sending evicted ack to " ++ server ++ ": " ++ show err)
841 atomic do
850 atomic do
842 ackedIds <- *ackedIds
851 ackedIds <- *ackedIds
843− let reinsert = do a <- result.evictedEntries; where a.originServer == server; yield a
852+ let reinsert = do a <- evictedToRetry; where a.originServer == server; yield a
853+ 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
844− set *ackedIds = union ackedIds reinsert))
856+ set *ackedIds = union ackedIds limitedReinsert))
845 else yield {}
857 else yield {}
846 broadcastOfflineGossip t result.peerServers result.expiredLocal
858 broadcastOfflineGossip t result.peerServers result.expiredLocal
@@ -990,7 +1002,7 @@ serve = \req -> case req of
990 o <- trustedOffline
1002 o <- trustedOffline
991 where o.pubkey == k.pubkey
1003 where o.pubkey == k.pubkey
992 where o.server == k.server
1004 where o.server == k.server
993− where o.timestamp >= p.timestamp
1005+ where o.timestamp > p.timestamp
994 yield o) > 0
1006 yield o) > 0
995 yield p) > 0
1007 yield p) > 0
996 yield {pubkey: k.pubkey, server: k.server}
1008 yield {pubkey: k.pubkey, server: k.server}
@@ -1003,7 +1015,7 @@ serve = \req -> case req of
1003 o <- trustedOffline
1015 o <- trustedOffline
1004 where o.pubkey == k.pubkey
1016 where o.pubkey == k.pubkey
1005 where o.server == k.server
1017 where o.server == k.server
1006− where o.timestamp >= p.timestamp
1018+ where o.timestamp > p.timestamp
1007 yield o) > 0
1019 yield o) > 0
1008 yield p)
1020 yield p)
1009 let withinCapacity = count afterOffline <= maxPresenceEntries
1021 let withinCapacity = count afterOffline <= maxPresenceEntries
@@ -1034,7 +1046,7 @@ serve = \req -> case req of
1034 o <- trustedOffline
1046 o <- trustedOffline
1035 where o.pubkey == k.pubkey
1047 where o.pubkey == k.pubkey
1036 where o.server == k.server
1048 where o.server == k.server
1037− where o.timestamp >= p.timestamp
1049+ where o.timestamp > p.timestamp
1038 yield o) > 0
1050 yield o) > 0
1039 yield p)
1051 yield p)
1040 let reclaimCapacity = if withinCapacity then 0 else maxPresenceEntries - count updatesOnlyAfterOffline
1052 let reclaimCapacity = if withinCapacity then 0 else maxPresenceEntries - count updatesOnlyAfterOffline