on master help sign in
Simplify code: combine where clauses, factor broadcastOfflineGossip, parameterize sendBatchedGossip hops, optimize eviction
6357861iko
client/ApiClient.fs+2−1
@@ -96,8 +96,9 @@ module ApiClient =
96
96
97 match doc.RootElement.TryGetProperty("error") with
97 match doc.RootElement.TryGetProperty("error") with
98 | true, err ->
98 | true, err ->
99+ let msg = err.GetString()
99 doc.Dispose()
100 doc.Dispose()
100− return failwith $"{url}: {err.GetString()}"
101+ return failwith $"{url}: {msg}"
101 | _ -> return doc
102 | _ -> return doc
102 }
103 }
103
104
client/App.fs+19−23
@@ -111,10 +111,9 @@ module App =
111 else contacts @ [ contact ]
111 else contacts @ [ contact ]
112
112
113 let private upsertContact (contact: Contact) (contacts: Contact list) =
113 let private upsertContact (contact: Contact) (contacts: Contact list) =
114− if contacts |> List.exists (fun c -> c.Pubkey = contact.Pubkey) then
114+ match contacts |> List.tryFindIndex (fun c -> c.Pubkey = contact.Pubkey) with
115− contacts |> List.map (fun c -> if c.Pubkey = contact.Pubkey then contact else c)
115+ | Some i -> contacts |> List.updateAt i contact
116− else
117− contacts @ [ contact ]
116+ | None -> contacts @ [ contact ]
118
117
119 let private pubKeyHex model =
118 let private pubKeyHex model =
120 match model.Auth with
119 match model.Auth with
@@ -202,11 +201,11 @@ module App =
202 model', CmdSend(session, pk, compose, id) :: saveCmd model'
201 model', CmdSend(session, pk, compose, id) :: saveCmd model'
203 | _ -> model, []
202 | _ -> model, []
204
203
205− | Sent(Ok result) ->
204+ | Sent(Ok { Status = ApiClient.Rejected }) ->
206− match result.Status with
207− | ApiClient.Rejected -> { model with Error = Some "Message rejected by server" }, []
205+ { model with Error = Some "Message rejected by server" }, []
206+ | Sent(Ok { Status = ApiClient.Unauthorized }) ->
208− | ApiClient.Unauthorized -> { model with Error = Some "Not authorized to deliver message" }, []
207+ { model with Error = Some "Not authorized to deliver message" }, []
209− | _ -> model, []
208+ | Sent(Ok _) -> model, []
210 | Sent(Error err) -> { model with Error = Some $"Send failed: {err}" }, []
209 | Sent(Error err) -> { model with Error = Some $"Send failed: {err}" }, []
211
210
212 | PollResult(incoming, status, newCursor) ->
211 | PollResult(incoming, status, newCursor) ->
@@ -219,12 +218,11 @@ module App =
219 Messages = m.Messages |> appendMessage fromPubkey chatMsg })
218 Messages = m.Messages |> appendMessage fromPubkey chatMsg })
220 { model with PollStatus = status; PollCursor = newCursor }
219 { model with PollStatus = status; PollCursor = newCursor }
221
220
222− let cmds =
221+ model',
223− match trySession model' with
222+ [ match trySession model' with
224− | Some session -> [ CmdPoll(session, model'.PollCursor) ]
223+ | Some session -> CmdPoll(session, model'.PollCursor)
225− | None -> []
224+ | None -> ()
226−
227− model', cmds @ (if incoming.IsEmpty then [] else saveCmd model')
225+ if not incoming.IsEmpty then yield! saveCmd model' ]
228
226
229 | SetNewPubkey pk ->
227 | SetNewPubkey pk ->
230 match model.Page with
228 match model.Page with
@@ -289,14 +287,14 @@ module App =
289 | Some(plaintext, senderHex) ->
287 | Some(plaintext, senderHex) ->
290 let envelope = JsonSerializer.Deserialize<TextEnvelope>(plaintext)
288 let envelope = JsonSerializer.Deserialize<TextEnvelope>(plaintext)
291
289
292− if envelope.Type = "text" then
290+ match envelope.Type with
291+ | "text" ->
293 Ok(senderHex,
292 Ok(senderHex,
294 { Id = envelope.Id
293 { Id = envelope.Id
295 Body = envelope.Body
294 Body = envelope.Body
296 Timestamp = DateTimeOffset.FromUnixTimeSeconds(payload.Timestamp)
295 Timestamp = DateTimeOffset.FromUnixTimeSeconds(payload.Timestamp)
297 IsOutgoing = false })
296 IsOutgoing = false })
298− else
299− Error "unknown type"
297+ | t -> Error $"unknown type: {t}"
300 | None -> Error "decrypt failed"
298 | None -> Error "decrypt failed"
301 with ex ->
299 with ex ->
302 Error $"parse: {ex.Message}"
300 Error $"parse: {ex.Message}"
@@ -459,7 +457,7 @@ module App =
459 |> String.concat ", "
457 |> String.concat ", "
460
458
461 let totalMsgs =
459 let totalMsgs =
462− model.Messages |> Map.fold (fun acc _ msgs -> acc + List.length msgs) 0
460+ model.Messages |> Map.values |> Seq.sumBy List.length
463
461
464 ContentPage(
462 ContentPage(
465 ScrollView(
463 ScrollView(
@@ -491,16 +489,14 @@ module App =
491 .textColor(Colors.Gray)
489 .textColor(Colors.Gray)
492
490
493 for c in model.Contacts do
491 for c in model.Contacts do
494− let lastMsg =
492+ let preview =
495 model.Messages
493 model.Messages
496 |> Map.tryFind c.Pubkey
494 |> Map.tryFind c.Pubkey
497 |> Option.bind List.tryLast
495 |> Option.bind List.tryLast
498 |> Option.map _.Body
496 |> Option.map _.Body
497+ |> Option.map (fun b -> if b.Length > 40 then b.[..39] + "..." else b)
499 |> Option.defaultValue ""
498 |> Option.defaultValue ""
500
499
501− let preview =
502− if lastMsg.Length > 40 then lastMsg.[..39] + "..." else lastMsg
503−
504 Button($"{c.Nickname}\n{preview}", Nav(Chat(c.Pubkey, "")))
500 Button($"{c.Nickname}\n{preview}", Nav(Chat(c.Pubkey, "")))
505 })
501 })
506 .padding(20.)
502 .padding(20.)
client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.app/_CodeSignature/CodeResources+4−4
@@ -166,11 +166,11 @@
166 </data>
166 </data>
167 <key>Skrepka.dll</key>
167 <key>Skrepka.dll</key>
168 <data>
168 <data>
169− 5V7ZArTTdWWdtF2EQw4DfWAWqsI=
169+ lezBPlMGgvvXPLrij5BGxw+mSWU=
170 </data>
170 </data>
171 <key>Skrepka.pdb</key>
171 <key>Skrepka.pdb</key>
172 <data>
172 <data>
173− SsPgpZXl35VDuHCOYCegZuLqIVg=
173+ GEoIFmupvmKvjt37aNX0Nqhf4Mw=
174 </data>
174 </data>
175 <key>Sodium.Core.dll</key>
175 <key>Sodium.Core.dll</key>
176 <data>
176 <data>
@@ -1393,14 +1393,14 @@
1393 <dict>
1393 <dict>
1394 <key>hash2</key>
1394 <key>hash2</key>
1395 <data>
1395 <data>
1396− EjrAHE9wqEvTYF+Siheu21r0UjeHDIZTT38w82FXRYU=
1396+ lOwwpy7OvL/VnkdUcEg8WtWpvQYej7RHx+vgMXJ9cIk=
1397 </data>
1397 </data>
1398 </dict>
1398 </dict>
1399 <key>Skrepka.pdb</key>
1399 <key>Skrepka.pdb</key>
1400 <dict>
1400 <dict>
1401 <key>hash2</key>
1401 <key>hash2</key>
1402 <data>
1402 <data>
1403− cqhfrvM9zLFFTemz+KoZd7JckLQGVacy+ANck7D2x18=
1403+ jNIcynqsu5mNKMdxE4ue6lbnHnYvri+aDBLPMWQYh38=
1404 </data>
1404 </data>
1405 </dict>
1405 </dict>
1406 <key>Sodium.Core.dll</key>
1406 <key>Sodium.Core.dll</key>
client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-ios/iossimulator-arm64/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/MonoBundle/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/MonoBundle/Skrepka.pdb

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.app/Contents/_CodeSignature/CodeResources+2−2
@@ -251,14 +251,14 @@
251 <dict>
251 <dict>
252 <key>hash2</key>
252 <key>hash2</key>
253 <data>
253 <data>
254− fVOogHexeXD8oGEEo57l14SmUBycR/4qC7AH6BhBs7k=
254+ BX5Ln9e/MG90UXlzW6/mp4ZMKIk3SNBv7i3Ncys57PE=
255 </data>
255 </data>
256 </dict>
256 </dict>
257 <key>MonoBundle/Skrepka.pdb</key>
257 <key>MonoBundle/Skrepka.pdb</key>
258 <dict>
258 <dict>
259 <key>hash2</key>
259 <key>hash2</key>
260 <data>
260 <data>
261− ZOxyEQ1fCheg8RSrL3C6orb8q4+ouFNQ6lWNgWyrhPo=
261+ BFNi5ZeloXd05sYpCvJxbfM96QQYZ1yINRFxIEAItGE=
262 </data>
262 </data>
263 </dict>
263 </dict>
264 <key>MonoBundle/Sodium.Core.dll</key>
264 <key>MonoBundle/Sodium.Core.dll</key>
client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.dll

Binary file not shown.

client/bin/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.AssemblyInfo.fs+1−1
@@ -10,7 +10,7 @@ open System.Reflection
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
13−[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+01f5f207fb604677f732e61a361f792f91a2b5c4")>]
13+[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+5c34fab63923cdb1b780a7e5a5ce5fae72adf78e")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.AssemblyInfoInputs.cache+1−1
@@ -1 +1 @@
1−e0e8e8e8cd6c9e5da1d472b9aaaa2bf913ad3f59c98c11e0e07666057c474551
1+5ce28345d4f1ab17ca4f1637108170a533a9e7a3ae603bd386f96f4a7115bf28
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.fsproj.FileListAbsolute.txt−23
@@ -334,26 +334,3 @@
334/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.genruntimeconfig.cache
334/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.genruntimeconfig.cache
335/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll
335/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll
336/Users/iko/Developer/skrepka/client/bin/Debug/net10.0-ios/iossimulator-arm64/LiteDB.dll
336/Users/iko/Developer/skrepka/client/bin/Debug/net10.0-ios/iossimulator-arm64/LiteDB.dll
337−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Fabulous.stamp
338−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Fabulous.MauiControls.stamp
339−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/FSharp.Core.stamp
340−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/LiteDB.stamp
341−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Configuration.Abstractions.stamp
342−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Configuration.stamp
343−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.DependencyInjection.Abstractions.stamp
344−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.DependencyInjection.stamp
345−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Diagnostics.Abstractions.stamp
346−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.FileProviders.Abstractions.stamp
347−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Hosting.Abstractions.stamp
348−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Logging.Abstractions.stamp
349−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Logging.stamp
350−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Options.stamp
351−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Extensions.Primitives.stamp
352−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.Compatibility.stamp
353−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.stamp
354−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Controls.Xaml.stamp
355−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.stamp
356−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Essentials.stamp
357−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Microsoft.Maui.Graphics.stamp
358−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/resourcestamps/Sodium.Core.stamp
359−/Users/iko/Developer/skrepka/client/obj/Debug/net10.0-ios/iossimulator-arm64/unpack/Microsoft.Maui.Essentials/BundleResource/xml/microsoft_maui_essentials_fileprovider_file_paths.xml
client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/Skrepka.sourcelink.json+1−1
@@ -1 +1 @@
1−{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/01f5f207fb604677f732e61a361f792f91a2b5c4/*"}}
1+{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/5c34fab63923cdb1b780a7e5a5ce5fae72adf78e/*"}}
client/obj/Debug/net10.0-ios/iossimulator-arm64/ref/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-ios/iossimulator-arm64/refint/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.AssemblyInfo.fs+1−1
@@ -10,7 +10,7 @@ open System.Reflection
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
10[<assembly: System.Reflection.AssemblyCompanyAttribute("Skrepka")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
11[<assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
12[<assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")>]
13−[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+01f5f207fb604677f732e61a361f792f91a2b5c4")>]
13+[<assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0+5c34fab63923cdb1b780a7e5a5ce5fae72adf78e")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
14[<assembly: System.Reflection.AssemblyProductAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
15[<assembly: System.Reflection.AssemblyTitleAttribute("Skrepka")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
16[<assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")>]
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.AssemblyInfoInputs.cache+1−1
@@ -1 +1 @@
1−b4711a8c2112127a9d16499cf889271fa4c029a6ea108d24c78bcc77f6729544
1+619a20356f5e49038371f33a93f265cb66ee99cf70d2100710b5c8d26eea4f99
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.pdb

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/Skrepka.sourcelink.json+1−1
@@ -1 +1 @@
1−{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/01f5f207fb604677f732e61a361f792f91a2b5c4/*"}}
1+{"documents":{"/Users/iko/Developer/skrepka/*":"https://raw.githubusercontent.com/ilyakooo0/skrepka/5c34fab63923cdb1b780a7e5a5ce5fae72adf78e/*"}}
client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/ref/Skrepka.dll

Binary file not shown.

client/obj/Debug/net10.0-maccatalyst/maccatalyst-arm64/refint/Skrepka.dll

Binary file not shown.

server.knot+28−35
@@ -555,8 +555,7 @@ pruneExpired = \t -> do
555 yield a
555 yield a
556 yield {expiredLocal: (do
556 yield {expiredLocal: (do
557 p <- presenceBefore
557 p <- presenceBefore
558− where p.expiresAt <= t
558+ where p.expiresAt <= t && p.server == serverHostN
559− where p.server == serverHostN
560 where none presenceAfter (\q -> q.pubkey == p.pubkey && q.server == serverHostN)
559 where none presenceAfter (\q -> q.pubkey == p.pubkey && q.server == serverHostN)
561 yield p), peerServers: peerServersBefore}
560 yield p), peerServers: peerServersBefore}
562
561
@@ -576,17 +575,17 @@ forEachBatch = \items batchSize process ->
576 process batch
575 process batch
577 forEachBatch rest batchSize process
576 forEachBatch rest batchSize process
578
577
579−sendBatchedGossipToServer : Text -> [GossipEvent] -> IO {network} {}
578+sendBatchedGossipToServer : Text -> [GossipEvent] -> Int -> IO {network} {}
580−sendBatchedGossipToServer = \server allEvents ->
579+sendBatchedGossipToServer = \server allEvents hops ->
581 forEachBatch allEvents maxGossipEvents (\batch -> do
580 forEachBatch allEvents maxGossipEvents (\batch -> do
582 _ <- fetch (federationScheme ++ server) (RecvGossip {
581 _ <- fetch (federationScheme ++ server) (RecvGossip {
583 authorization: "Bearer " ++ federationSecret,
582 authorization: "Bearer " ++ federationSecret,
584− events: batch, hopsRemaining: 2, fromServer: serverHostN})
583+ events: batch, hopsRemaining: hops, fromServer: serverHostN})
585 yield {})
584 yield {})
586
585
587−sendBatchedGossip : [Text] -> [GossipEvent] -> IO {network} {}
586+sendBatchedGossip : [Text] -> [GossipEvent] -> Int -> IO {network} {}
588−sendBatchedGossip = \peerServers allEvents ->
587+sendBatchedGossip = \peerServers allEvents hops ->
589− sendToEach peerServers (\server -> sendBatchedGossipToServer server allEvents)
588+ sendToEach peerServers (\server -> sendBatchedGossipToServer server allEvents hops)
590
589
591broadcastOfflineGossip = \t peerServers expiredLocal ->
590broadcastOfflineGossip = \t peerServers expiredLocal ->
592 when (federationEnabled && count peerServers > 0 && count expiredLocal > 0) (do
591 when (federationEnabled && count peerServers > 0 && count expiredLocal > 0) (do
@@ -597,7 +596,7 @@ broadcastOfflineGossip = \t peerServers expiredLocal ->
597 let gossipEvents = do
596 let gossipEvents = do
598 e <- expiredEntries
597 e <- expiredEntries
599 yield {eventType: "offline", pubkey: e.pubkey, server: serverHostN, timestamp: e.expiresAt, ttl: e.ttl}
598 yield {eventType: "offline", pubkey: e.pubkey, server: serverHostN, timestamp: e.expiresAt, ttl: e.ttl}
600− sendBatchedGossip peerServers gossipEvents)
599+ sendBatchedGossip peerServers gossipEvents 2)
601
600
602forkBroadcastOffline = \t result ->
601forkBroadcastOffline = \t result ->
603 fork (broadcastOfflineGossip t result.peerServers result.expiredLocal)
602 fork (broadcastOfflineGossip t result.peerServers result.expiredLocal)
@@ -765,18 +764,20 @@ serve = \req -> case req of
765 then collectPeerServers updatedPresence (\p -> p.server)
764 then collectPeerServers updatedPresence (\p -> p.server)
766 else []
765 else []
767 yield {pr: pr, verify: VerifyOk {peerServers: peerServers}}
766 yield {pr: pr, verify: VerifyOk {peerServers: peerServers}}
767+ let expiredLocal = case result.verify of
768+ VerifyOk _ -> do p <- result.pr.expiredLocal; where not (p.pubkey == pubkey); yield p
769+ _ -> result.pr.expiredLocal
770+ fork (do
768− fork (case result.verify of
771+ case result.verify of
769− VerifyOk {peerServers} -> do
772+ VerifyOk {peerServers} ->
770− when federationEnabled
773+ when federationEnabled
771− (sendToEach peerServers (\server -> do
774+ (sendToEach peerServers (\server -> do
772− _ <- fetch (federationScheme ++ server) (RecvGossip {
775+ _ <- fetch (federationScheme ++ server) (RecvGossip {
773− authorization: "Bearer " ++ federationSecret,
776+ authorization: "Bearer " ++ federationSecret,
774− events: [{eventType: "online", pubkey: pubkey, server: serverHostN, timestamp: t, ttl: onlineGossipTtl}], hopsRemaining: 2, fromServer: serverHostN})
777+ events: [{eventType: "online", pubkey: pubkey, server: serverHostN, timestamp: t, ttl: onlineGossipTtl}], hopsRemaining: 2, fromServer: serverHostN})
775− yield {}))
778+ yield {}))
776− broadcastOfflineGossip t result.pr.peerServers
779+ _ -> yield {}
777− (do p <- result.pr.expiredLocal; where not (p.pubkey == pubkey); yield p)
778− _ ->
779− broadcastOfflineGossip t result.pr.peerServers result.pr.expiredLocal)
780+ broadcastOfflineGossip t result.pr.peerServers expiredLocal)
780 yield (case result.verify of
781 yield (case result.verify of
781 VerifyFailed _ -> respond {token: "", expiresAt: 0}
782 VerifyFailed _ -> respond {token: "", expiresAt: 0}
782 VerifyOk _ -> respond {token: token, expiresAt: expiry})
783 VerifyOk _ -> respond {token: token, expiresAt: expiry})
@@ -867,8 +868,7 @@ serve = \req -> case req of
867 let ackedMessages = do
868 let ackedMessages = do
868 m <- messages
869 m <- messages
869 mid <- dedupedIds
870 mid <- dedupedIds
870− where m.messageId == mid
871+ where m.messageId == mid && m.toKey == pubkey
871− where m.toKey == pubkey
872 yield m
872 yield m
873 set *messages = diff messages ackedMessages
873 set *messages = diff messages ackedMessages
874 let ackedFederated = do
874 let ackedFederated = do
@@ -877,12 +877,9 @@ serve = \req -> case req of
877 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
877 yield {messageId: m.messageId, toKey: m.toKey, ackedAt: t, originServer: m.originServer}
878 ackedIds <- *ackedIds
878 ackedIds <- *ackedIds
879 let combinedAckedIds = union ackedIds ackedFederated
879 let combinedAckedIds = union ackedIds ackedFederated
880− let excessCount = count combinedAckedIds - maxAckedIds
880+ let evictedEntries = let excessCount = count combinedAckedIds - maxAckedIds in
881− let afterEviction = if excessCount <= 0 then combinedAckedIds
881+ if excessCount <= 0 then [] else boundedSmallest combinedAckedIds excessCount (\a -> a.ackedAt)
882− else evictOldestAckedIds combinedAckedIds excessCount
882+ set *ackedIds = diff combinedAckedIds evictedEntries
883− let evictedEntries = if excessCount <= 0 then []
884− else diff combinedAckedIds afterEviction
885− set *ackedIds = afterEviction
886 yield {pr: pr, ack: AckDone {pendingAcks: ackedFederated, evictedEntries: evictedEntries}}
883 yield {pr: pr, ack: AckDone {pendingAcks: ackedFederated, evictedEntries: evictedEntries}}
887 fork (do
884 fork (do
888 case result.ack of
885 case result.ack of
@@ -1021,16 +1018,12 @@ serve = \req -> case req of
1021 when (not gossipResult.withinCapacity)
1018 when (not gossipResult.withinCapacity)
1022 (println ("gossip: presence at capacity (" ++ show maxPresenceEntries ++ "), limiting new entries from " ++ fromServer))
1019 (println ("gossip: presence at capacity (" ++ show maxPresenceEntries ++ "), limiting new entries from " ++ fromServer))
1023 fork (do
1020 fork (do
1024− when (cappedHops > 1 && federationEnabled && count effectiveEvents > 0) (do
1021+ when (cappedHops > 1 && federationEnabled && count effectiveEvents > 0) (
1025 let targets = do
1022 let targets = do
1026 s <- gossipResult.gossipPeerServers
1023 s <- gossipResult.gossipPeerServers
1027 where not (s == fromServer)
1024 where not (s == fromServer)
1028 yield s
1025 yield s
1029− sendToEach targets (\server -> do
1030− _ <- fetch (federationScheme ++ server) (RecvGossip {
1031− authorization: "Bearer " ++ federationSecret,
1032− events: effectiveEvents, hopsRemaining: cappedHops - 1, fromServer: serverHostN})
1026+ in sendBatchedGossip targets effectiveEvents (cappedHops - 1))
1033− yield {}))
1034 let pr = gossipResult.pr
1027 let pr = gossipResult.pr
1035 broadcastOfflineGossip t pr.peerServers pr.expiredLocal)
1028 broadcastOfflineGossip t pr.peerServers pr.expiredLocal)
1036 yield (respond {ok: True {}})
1029 yield (respond {ok: True {}})