Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Overview deadline flushes a fast key before its settle window

Closed Beginner friendly
#1,463 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
react, typescript
Domain
frontend

Research direction

Start with web/src/useKbEvents.ts, especially the overview timer and the shared invalidation coalescer described in the issue. Trace how fast keys and the overview key are queued, then check the related tests if available. Done means an overview deadline no longer invalidates fast keys before their 300 ms settle period, while explicit unmount and reconnect flushes still work.

Written by the indexing model from the issue text.

Description

  • Repository: deeplethe/utopia
  • Target commit: fa77a956797e86fc0465971d890c59b85ee971ec
  • File: web/src/useKbEvents.ts:6-31

Summary

overview deadline flushes a fast key before its settle window.

Root cause

The overview timer uses the shared coalescer and forces a global flush instead of invalidating only the overview key.

Affected code

web/src/useKbEvents.ts:

    1  // KB 事件流订阅:收到事件只做 react-query 失效重取(事件不带业务数据,天然幂等)。
    2  // EventSource 断线自动重连,重连成功后补刷漏掉的变化;替代 Library/Review 的轮询。
    3  // 告警也从这条流来:一页只占一条通知用的连接(见 `eventStream`)。
    4  //
    5  // **失效是合并着做的。** 一篇文档抽取时每落一条事实就发一个 graph 事件,
    6  // 从前每个事件各失效一次,图谱页在那几秒里把 overview 重取了十几遍——
    7  // 每次都是同一张图,最后一次才算数。所以事件只把 key 记下来,停顿一小会
    8  // 再一次性失效:一阵事件只换来一次重取,最后那次一定包含之前所有的变化。
    9  // 幂等性没变,只是把「每条都刷」变成「刷最后一条」。
   10  //
   11  // 失效不看 staleTime:这里失效的键在 queryDefaults.ts 里放到了 30 秒,靠的就是
   12  // 这一层把当前库的变化即时推到页面上。
   13  import { useEffect } from "react";
   14  import { partialMatchKey, useQueryClient, type QueryKey } from "@tanstack/react-query";
   15  import { subscribeEvents } from "./eventStream";
   16  import { STREAM_KEYS } from "./queryDefaults";
   17  
   18  /** 一阵事件之间的静默期。抽取落事实的间隔远小于它,人眼看不出这点延迟 */
   19  export const SETTLE_MS = 300;
   20  
   21  /** 全图 overview 要数遍整个库:推送期间几秒重数一次就够了(#1296) */
   22  export const OVERVIEW_SETTLE_MS = 3_000;
   23  
   24  /**
   25   * 把一阵失效合并成一次:`push` 只记键,静默 `settleMs` 后一起交给 `invalidate`,
   26   * 同一个键及其前缀只失效一次;`flush` 给卸载与重连用,攒着的刷掉而不是丢掉。
   27   * 抽成纯函数是为了能测;订阅那层只是把事件名映射到键。
   28   */
   29  export function createInvalidationCoalescer(
   30    invalidate: (key: QueryKey) => void,
   31    settleMs: number,
   32  ) {
   33    const pending = new Map<string, QueryKey>();
   34    let timer: ReturnType<typeof setTimeout> | null = null;
   35    const flush = () => {
   36      if (timer !== null) {
   37        clearTimeout(timer);
   38        timer = null;
   39      }
   40      const keys = [...pending.values()];
   41      pending.clear();
   42      for (const key of keys) {
   43        // 正常 graph 事件可能已排了 ["graph", kbId, "neighborhood"],重连又补上 ["graph", kbId]:
   44        // 前缀已经覆盖后者,不能取消刚开始的请求再重取一遍。
   45        if (keys.some((prefix) => prefix.length < key.length && partialMatchKey(key, prefix))) continue;
   46        invalidate(key);
   47      }
   48    };
   49    const push = (...keys: QueryKey[]) => {
   50      for (const key of keys) pending.set(JSON.stringify(key), key);
   51      if (timer === null) timer = setTimeout(flush, settleMs);
   52    };
   53    return { push, flush };
   54  }
   55  
   56  export function useKbEvents(kbId: string | undefined) {

Expected behavior

Fast coalescer pending keys must wait for SETTLE_MS or an explicit unmount/reconnect flush; an overview deadline must not flush unrelated fast pending keys early.

Actual behavior

In web/src/useKbEvents.ts lines 65-68, the overview timer calls push(key); flush(); when it fires, causing all pending fast keys to be invalidated immediately before the fast SETTLE_MS quiet period.

Steps to reproduce

  1. Arm the overview deadline and enqueue a fast key shortly before it fires.
  2. Measure the time between the fast event and its invalidation.
  3. Compare with a fast event with no overview deadline.

Suggested fix

Give the overview key its own coalescer (or a key-scoped flush) so fast keys keep their settle window.

Impact

Fast keys are invalidated early, causing extra refetches and inconsistent batching.

Dominant language
Rust
Stars
8.1k
Forks
1.1k
Avg merge
21h 30m
Merged PRs (30d)
251

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from deeplethe/utopia

All issues in deeplethe/utopia

Similar issues

More Rust issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.