Build the rate limiter on the new CounterStore, so limits hold across server instances
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 3/5
- Thời gian dự kiến
- 1-2 ngày
- Mức phù hợp với người mới
- 83/100
- Loại issue
- Tính năng
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- node.js, typescript
Hướng nghiên cứu
Read packages/core/src/storage/types.ts for the CounterStore contract, then review packages/server/src/rate-limit.ts and its tests for existing behavior. Implement the algorithm in packages/core/src/limits/rate-limit.ts and add fake-clock and concurrency coverage in packages/core/tests/limits/rate-limit.test.ts, using the in-memory counter store. Done means the listed acceptance criteria pass and the core package exports the limiter with a minor changeset.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
The server's rate limiter keeps its counts in a Map in the process (packages/server/src/rate-limit.ts). On Vercel or Workers every instance has its own map, so a visitor spread over five instances gets five times the limit. It also needs a setInterval for cleanup (packages/server/src/handler.ts, line 35), and Workers don't allow timers at global scope.
@chatcops/core now has a CounterStore interface (packages/core/src/storage/types.ts): atomic counters that reset after a while, backed by Redis, Postgres and so on. This issue is the rate limit algorithm on top of it. Wiring it into the server comes in a later PR.
What to do
Create packages/core/src/limits/rate-limit.ts:
export interface RateLimitRule {
limit: number; // requests allowed per window
windowMs: number;
}
export interface RateLimitResult {
allowed: boolean;
/** Requests left in the current window, never below 0. */
remaining: number;
/** When denied: how long until a request would be allowed again. */
retryAfterMs?: number;
}
export function createRateLimiter(counters: CounterStore, rule: RateLimitRule, options?: { prefix?: string; now?: () => number }): {
check(key: string): Promise<RateLimitResult>;
};
Use a sliding window built from two fixed windows. It's smooth at window edges (no burst of 2x the limit at the boundary) and needs only two counters:
- The window index is
Math.floor(now / windowMs). Count this request withcounters.increment(${prefix}:${key}:${index}, 1, 2 * windowMs), and read the previous window's counter withget. - The estimated count is
previous * (1 - elapsedInWindow / windowMs) + current. Allow the request when it's at mostlimit. - Denied requests still count, so a client that keeps hammering stays limited.
retryAfterMsis an estimate: the time until the estimate drops back under the limit, at least 1 ms and at mostwindowMs. Explain the formula in a comment.prefixdefaults to'rl'. Validatelimit > 0andwindowMs > 0likeRateLimiterdoes.
Where to look
packages/server/src/rate-limit.ts(today's limiter and its tests inpackages/server/tests/rate-limit.test.ts)packages/core/src/storage/memory.ts(memoryStorage().counters, use it in the tests with a fakenow)- Cloudflare's write-up of the same sliding window idea
Acceptance criteria
- New
packages/core/src/limits/rate-limit.tsandpackages/core/tests/limits/rate-limit.test.ts, exported from@chatcops/core - Tests with a fake clock: the first
limitrequests pass and the next one doesn't; the count decays across the window boundary (half the previous window still counts at the midpoint); keys don't affect each other;retryAfterMsis set when denied and within bounds - A test with 30 concurrent
check()calls against a limit of 10 allows exactly 10 - Changeset for
@chatcops/core(minor) -
pnpm test:coverageandpnpm lintpass
Want to work on this? Comment below and I'll assign it to you. Please take one issue at a time, branch off dev, and open your PR against dev with Closes #<this issue number>. Setup notes (pnpm, build before test) are in CONTRIBUTING.md.
- Ngôn ngữ chính
- TypeScript
- Star
- 13
- Fork
- 7
- Merge trung bình
- 4 giờ 11 phút
- Pull request đã merge (30 ngày)
- 122
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của codercops/chatcops
-
enhancement hacktoberfest help wanted server
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Document the pre-chat formCó thể đã có người làm @masyarakatai đã nhận 5 ngày trước. Đang mởdocumentation good first issue hacktoberfest widget
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 88/100
codercops/chatcops#70 · 3 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement hacktoberfest help wanted server
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 25/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Create @chatcops/store-redis for Upstash and other Redis clientsCó thể đã có người làm @bhushan4work đã nhận 1 ngày trước. Đang mởenhancement hacktoberfest help wanted server
codercops/chatcops#248 · 2 bình luận · 1 người được giao ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Create @chatcops/store-sqlite, a store for single-server setupsCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởenhancement hacktoberfest help wanted server
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 35/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của codercops/chatcops
Issue tương tự
-
[BUG] rag: sentence content can cross the reported sentence boundariesCó thể đã có người làm @LJK-ikun đã nhận hôm nay. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug needs-triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
README: the Resource URI Schemas example's file://documents/* pattern only matches that literal URIĐang mở
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
platformatic/mcp#361 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
frontend
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Push: sem service worker ou sem VAPID, o interruptor de Notificações fica ligado sem avisar nadaĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 76/100
melgarafael/DeskcommCRM#3164 ·
Maintainer thường phản hồi trong vòng 1 ngày