on master help sign in
Simplify server.knot: refactor GossipEventType parsing, compute touched pubkeys once, inline recordFailure predicate
d9f295aiko
server.knot+13−10
@@ -156,7 +156,11 @@ impl ToJSON GossipEventType where
156 GossipUnknown {} -> toJson {eventType: "unknown"}
156 GossipUnknown {} -> toJson {eventType: "unknown"}
157
157
158impl FromJSON GossipEventType where
158impl FromJSON GossipEventType where
159+ parseJson t =
160+ let raw = parseJson t : {eventType: Text, pubkey: PubkeyHex}
161+ if raw.eventType == "online" then GossipOnline {raw.pubkey}
159− parseJson t = (\raw -> if raw.eventType == "online" then GossipOnline {raw.pubkey} else if raw.eventType == "offline" then GossipOffline {raw.pubkey} else GossipUnknown {}) (parseJson t : {eventType: Text, pubkey: PubkeyHex})
162+ else if raw.eventType == "offline" then GossipOffline {raw.pubkey}
163+ else GossipUnknown {}
160
164
161-- /messages is all-or-nothing per call: either every message in the batch is
165-- /messages is all-or-nothing per call: either every message in the batch is
162-- enqueued (delivered, federated, or buffered for federation), or none are
166-- enqueued (delivered, federated, or buffered for federation), or none are
@@ -329,7 +333,7 @@ tooLong = \s maxLen -> count (chars s) > maxLen
329
333
330-- True when `s` is non-empty, even-length, and only lowercase hex digits.
334-- True when `s` is non-empty, even-length, and only lowercase hex digits.
331isValidHex : Text -> Bool
335isValidHex : Text -> Bool
332−isValidHex = \s ->
336+isValidHex = \s -> do
333 let cs = chars s
337 let cs = chars s
334 let n = count cs
338 let n = count cs
335 n > 0 && n / 2 * 2 == n && all (\c -> contains c "0123456789abcdef") cs
339 n > 0 && n / 2 * 2 == n && all (\c -> contains c "0123456789abcdef") cs
@@ -440,11 +444,10 @@ recordFailure = \server -> do
440 t <- now
444 t <- now
441 atomic (do
445 atomic (do
442 failures <- *forwardFailures
446 failures <- *forwardFailures
443− let same = \f -> f.server == server
447+ let new = case findFirst failures (\f -> f.server == server) of
444− let new = case findFirst failures same of
445 Just {value: f} -> {server, failedAt: t, failures: f.failures + 1, f.firstFailedAt}
448 Just {value: f} -> {server, failedAt: t, failures: f.failures + 1, f.firstFailedAt}
446 _ -> {server, failedAt: t, failures: 1, firstFailedAt: t}
449 _ -> {server, failedAt: t, failures: 1, firstFailedAt: t}
447− *forwardFailures = union (filter (\f -> not same f) failures) [new])
450+ *forwardFailures = union (filter (\f -> f.server != server) failures) [new])
448
451
449-- Drop the failure record for `server` (called after any successful peer call).
452-- Drop the failure record for `server` (called after any successful peer call).
450-- Single-success recovery — there is no half-open state.
453-- Single-success recovery — there is no half-open state.
@@ -838,14 +841,14 @@ handleRecvGossip = \events fromServer -> do
838 else do
841 else do
839 newlyOnline <- atomic (do
842 newlyOnline <- atomic (do
840 pres <- *presence
843 pres <- *presence
841− let touched = \pk -> any (\e -> case e of
844+ let touchedPubkeys = fold (\acc e -> case e of
842− GossipOnline {pubkey} -> pubkey == pk
845+ GossipOnline {pubkey} -> union acc [pubkey]
843− GossipOffline {pubkey} -> pubkey == pk
846+ GossipOffline {pubkey} -> union acc [pubkey]
844− _ -> False {}) events
847+ _ -> acc) [] events
845 let added = fold (\acc e -> case e of
848 let added = fold (\acc e -> case e of
846 GossipOnline {pubkey} -> union acc [{pubkey, server: fromServer, expiresAt: t + onlineGossipTtl}]
849 GossipOnline {pubkey} -> union acc [{pubkey, server: fromServer, expiresAt: t + onlineGossipTtl}]
847 _ -> acc) [] events
850 _ -> acc) [] events
848− let kept = filter (\p -> p.server != fromServer || not touched p.pubkey) pres
851+ let kept = filter (\p -> p.server != fromServer || not elem p.pubkey touchedPubkeys) pres
849 *presence = union kept added
852 *presence = union kept added
850 yield (filter (\pk -> not any (\p -> p.pubkey == pk && p.server == fromServer && p.expiresAt > t) pres) (map (\p -> p.pubkey) added)))
853 yield (filter (\pk -> not any (\p -> p.pubkey == pk && p.server == fromServer && p.expiresAt > t) pres) (map (\p -> p.pubkey) added)))
851 fork (forEach newlyOnline (\pk -> forwardQueuedToServer pk fromServer))
854 fork (forEach newlyOnline (\pk -> forwardQueuedToServer pk fromServer))