on master help sign in
Simplify server: replace fold-based minBy/maxBy with sortBy, extract emptyPollResp and sendErrResp helpers to collapse 2000-char response literals
697a16ciko
server.knot+19−16
@@ -488,23 +488,26 @@ headOf = \items -> fold (\acc x -> case acc of
488 Nothing {} -> Just {value: x}
488 Nothing {} -> Just {value: x}
489 _ -> acc) Nothing {} items
489 _ -> acc) Nothing {} items
490
490
491+-- Sort then take head: O(n log n) but no fold-with-Maybe boilerplate.
491−minBy = \items getKey -> fold (\acc x -> case acc of
492+minBy = \items getKey -> headOf (sortBy getKey items)
492− Nothing {} -> Just {value: x}
493− Just {value: v} -> if getKey x < getKey v then Just {value: x} else acc) Nothing {} items
494−
495−maxBy = \items getKey -> fold (\acc x -> case acc of
493+maxBy = \items getKey -> headOf (sortBy (\x -> 0 - getKey x) items)
496− Nothing {} -> Just {value: x}
497− Just {value: v} -> if getKey x > getKey v then Just {value: x} else acc) Nothing {} items
498
494
499-- Drop entries with the oldest key (LRU-style eviction; ties drop together)
495-- Drop entries with the oldest key (LRU-style eviction; ties drop together)
500evictOldest = \items getKey ->
496evictOldest = \items getKey ->
501 case minBy items getKey of
497 case minBy items getKey of
502 Nothing {} -> items
498 Nothing {} -> items
503− Just {value: oldest} -> do x <- items; where getKey x != getKey oldest; yield x
499+ Just {value: oldest} -> filter items (\x -> getKey x != getKey oldest)
504
500
505capList = \items maxN getKey ->
501capList = \items maxN getKey ->
506 if count items > maxN then evictOldest items getKey else items
502 if count items > maxN then evictOldest items getKey else items
507
503
504+-- Shared empty/error shape for /poll. Only a few fields ever vary.
505+emptyPollResp = \cursor authorized rateLimited draining gen retryAfterMs cursorWasReset ->
506+ {events: [], cursor: cursor, authorized: authorized, rateLimited: rateLimited, draining: draining, generation: gen, presenceUpdates: [], heartbeat: False {}, retryAfterMs: retryAfterMs, cursorReset: cursorWasReset, hasMore: False {}, cursorStale: False {}, messageExpirations: [], messageDeliveries: [], droppedDeliveryReceipts: 0, droppedExpirationNotifs: 0, loadPct: 0, messageCancellations: []}
507+
508+-- Shared error shape for /messages send.
509+sendErrResp = \status err -> {status: status, messageId: "", retryAfterMs: 0, error: err, loadPct: 0}
510+
508-- Sequence an IO action over each unique item (dedup by getKey).
511-- Sequence an IO action over each unique item (dedup by getKey).
509forEach = \items getKey action -> case headOf items of
512forEach = \items getKey action -> case headOf items of
510 Nothing {} -> yield {}
513 Nothing {} -> yield {}
@@ -1111,12 +1114,12 @@ handlePoll = \cursor generation watchKeys authorization clientIp respond -> do
1111 let cursorWasReset = generationMismatch && cursor > 0
1114 let cursorWasReset = generationMismatch && cursor > 0
1112 let cappedWatchKeys = takeRelation maxWatchKeys watchKeys
1115 let cappedWatchKeys = takeRelation maxWatchKeys watchKeys
1113 dp <- *drainPhase
1116 dp <- *drainPhase
1114− if dp >= 2 then yield (respond {events: [], cursor: 0, authorized: True {}, rateLimited: False {}, draining: True {}, generation: serverGen, presenceUpdates: [], heartbeat: False {}, retryAfterMs: 0, cursorReset: cursorWasReset, hasMore: False {}, cursorStale: False {}, messageExpirations: [], messageDeliveries: [], droppedDeliveryReceipts: 0, droppedExpirationNotifs: 0, loadPct: 0, messageCancellations: []})
1117+ if dp >= 2 then yield (respond (emptyPollResp 0 (True {}) (False {}) (True {}) serverGen 0 cursorWasReset))
1115 else do
1118 else do
1116 g <- checkGlobalRate t
1119 g <- checkGlobalRate t
1117− if g then yield (respond {events: [], cursor: 0, authorized: False {}, rateLimited: True {}, draining: False {}, generation: serverGen, presenceUpdates: [], heartbeat: False {}, retryAfterMs: globalRateWindowMs, cursorReset: cursorWasReset, hasMore: False {}, cursorStale: False {}, messageExpirations: [], messageDeliveries: [], droppedDeliveryReceipts: 0, droppedExpirationNotifs: 0, loadPct: 0, messageCancellations: []})
1120+ if g then yield (respond (emptyPollResp 0 (False {}) (True {}) (False {}) serverGen globalRateWindowMs cursorWasReset))
1118 else case extractToken authorization of
1121 else case extractToken authorization of
1119− Nothing {} -> yield (respond {events: [], cursor: 0, authorized: False {}, rateLimited: False {}, draining: False {}, generation: serverGen, presenceUpdates: [], heartbeat: False {}, retryAfterMs: 0, cursorReset: cursorWasReset, hasMore: False {}, cursorStale: False {}, messageExpirations: [], messageDeliveries: [], droppedDeliveryReceipts: 0, droppedExpirationNotifs: 0, loadPct: 0, messageCancellations: []})
1122+ Nothing {} -> yield (respond (emptyPollResp 0 (False {}) (False {}) (False {}) serverGen 0 cursorWasReset))
1120 Just {value: token} -> pollOnce token effectiveCursor cursorWasReset cappedWatchKeys clientIp serverGen respond t
1123 Just {value: token} -> pollOnce token effectiveCursor cursorWasReset cappedWatchKeys clientIp serverGen respond t
1121
1124
1122pollOnce = \token cursor cursorWasReset watchKeys clientIp serverGen respond t -> do
1125pollOnce = \token cursor cursorWasReset watchKeys clientIp serverGen respond t -> do
@@ -1132,7 +1135,7 @@ pollOnce = \token cursor cursorWasReset watchKeys clientIp serverGen respond t -
1132 startWakeup <- *pollWakeup
1135 startWakeup <- *pollWakeup
1133 yield (Just {value: {pubkey: pubkey, clampedCursor: clampedCursor, startWakeup: startWakeup, pendingAcks: ackResult.pendingAcks}})
1136 yield (Just {value: {pubkey: pubkey, clampedCursor: clampedCursor, startWakeup: startWakeup, pendingAcks: ackResult.pendingAcks}})
1134 case setup of
1137 case setup of
1135− Nothing {} -> yield (respond {events: [], cursor: 0, authorized: False {}, rateLimited: False {}, draining: False {}, generation: serverGen, presenceUpdates: [], heartbeat: False {}, retryAfterMs: 0, cursorReset: cursorWasReset, hasMore: False {}, cursorStale: False {}, messageExpirations: [], messageDeliveries: [], droppedDeliveryReceipts: 0, droppedExpirationNotifs: 0, loadPct: 0, messageCancellations: []})
1138+ Nothing {} -> yield (respond (emptyPollResp 0 (False {}) (False {}) (False {}) serverGen 0 cursorWasReset))
1136 Just {value: s} -> do
1139 Just {value: s} -> do
1137 acquired <- atomic do
1140 acquired <- atomic do
1138 aps <- *activePolls
1141 aps <- *activePolls
@@ -1141,7 +1144,7 @@ pollOnce = \token cursor cursorWasReset watchKeys clientIp serverGen respond t -
1141 appendCapped activePolls [{pubkey: s.pubkey, startedAt: t}] maxActivePolls (\p -> p.startedAt)
1144 appendCapped activePolls [{pubkey: s.pubkey, startedAt: t}] maxActivePolls (\p -> p.startedAt)
1142 yield True
1145 yield True
1143 if not acquired
1146 if not acquired
1144− then yield (respond {events: [], cursor: cursor, authorized: True {}, rateLimited: True {}, draining: False {}, generation: serverGen, presenceUpdates: [], heartbeat: False {}, retryAfterMs: pollTimeoutMs, cursorReset: cursorWasReset, hasMore: False {}, cursorStale: False {}, messageExpirations: [], messageDeliveries: [], droppedDeliveryReceipts: 0, droppedExpirationNotifs: 0, loadPct: 0, messageCancellations: []})
1147+ then yield (respond (emptyPollResp cursor (True {}) (True {}) (False {}) serverGen pollTimeoutMs cursorWasReset))
1145 else do
1148 else do
1146 pollResult <- doPoll s t
1149 pollResult <- doPoll s t
1147 atomic (pruneRef activePolls (\p -> p.pubkey != s.pubkey))
1150 atomic (pruneRef activePolls (\p -> p.pubkey != s.pubkey))
@@ -1209,14 +1212,14 @@ handleSendMessage = \to encryptedBlob timestamp messageId expiresInMs priority a
1209 let clampedPriority = clamp 0 maxMessagePriority priority
1212 let clampedPriority = clamp 0 maxMessagePriority priority
1210 t <- now
1213 t <- now
1211 dp <- *drainPhase
1214 dp <- *drainPhase
1212− if dp >= 2 then yield (respond {status: MsDraining {}, messageId: "", retryAfterMs: 0, error: "draining", loadPct: 0})
1215+ if dp >= 2 then yield (respond (sendErrResp (MsDraining {}) "draining"))
1213 else do
1216 else do
1214 g <- checkGlobalRate t
1217 g <- checkGlobalRate t
1215− if g then yield (respond {status: MsRateLimited {}, messageId: "", retryAfterMs: 0, error: "rate_limited", loadPct: 0})
1218+ if g then yield (respond (sendErrResp (MsRateLimited {}) "rate_limited"))
1216 else do
1219 else do
1217 effMsgId <- if messageId != "" then yield messageId else genToken
1220 effMsgId <- if messageId != "" then yield messageId else genToken
1218 if t - timestamp > messageMaxAge
1221 if t - timestamp > messageMaxAge
1219− then yield (respond {status: MsRejected {}, messageId: "", retryAfterMs: 0, error: "stale_timestamp", loadPct: 0})
1222+ then yield (respond (sendErrResp (MsRejected {}) "stale_timestamp"))
1220 else do
1223 else do
1221 let clampedTs = clampTimestamp timestamp t
1224 let clampedTs = clampTimestamp timestamp t
1222 result <- atomic do
1225 result <- atomic do