enhance: カスタム絵文字の更新をサーバーに確認してクライアントキャッシュを更新するように#17758
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
📝 WalkthroughWalkthroughChangesカスタム絵文字同期
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant CustomEmojis
participant EmojisStatsAPI
participant EmojiStream
Client->>CustomEmojis: 絵文字同期を開始
CustomEmojis->>EmojisStatsAPI: emojis/stats を要求
EmojisStatsAPI-->>CustomEmojis: count / lastUpdatedAt
CustomEmojis->>EmojisStatsAPI: 絵文字一覧を取得
EmojiStream-->>CustomEmojis: 取得中の追加・更新・削除
CustomEmojis-->>Client: 最新一覧と更新を反映
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 ESLint
ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration. Comment |
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## develop #17758 +/- ##
===========================================
+ Coverage 26.16% 26.43% +0.26%
===========================================
Files 1182 1185 +3
Lines 40178 40418 +240
Branches 11106 11151 +45
===========================================
+ Hits 10513 10684 +171
- Misses 23794 23859 +65
- Partials 5871 5875 +4 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
このPRによるapi.jsonの差分 差分はこちら--- base
+++ head
@@ -43891,6 +43891,153 @@
}
}
},
+ "/emojis/stats": {
+ "post": {
+ "operationId": "post___emojis___stats",
+ "summary": "emojis/stats",
+ "description": "No description provided.\n\n**Credential required**: *No*",
+ "externalDocs": {
+ "description": "Source code",
+ "url": "https://github.com/misskey-dev/misskey/blob/develop/packages/backend/src/server/api/endpoints/emojis/stats.ts"
+ },
+ "tags": [
+ "meta"
+ ],
+ "responses": {
+ "200": {
+ "description": "OK (with results)",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "count": {
+ "type": "number"
+ },
+ "lastUpdatedAt": {
+ "type": [
+ "string",
+ "null"
+ ],
+ "format": "date-time"
+ }
+ },
+ "required": [
+ "count",
+ "lastUpdatedAt"
+ ]
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "Client error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INVALID_PARAM": {
+ "value": {
+ "error": {
+ "message": "Invalid param.",
+ "code": "INVALID_PARAM",
+ "id": "3d81ceae-475f-4600-b2a8-2bc116157532"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "401": {
+ "description": "Authentication error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "CREDENTIAL_REQUIRED": {
+ "value": {
+ "error": {
+ "message": "Credential required.",
+ "code": "CREDENTIAL_REQUIRED",
+ "id": "1384574d-a912-4b81-8601-c7b1c4085df1"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "403": {
+ "description": "Forbidden error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "AUTHENTICATION_FAILED": {
+ "value": {
+ "error": {
+ "message": "Authentication failed. Please ensure your token is correct.",
+ "code": "AUTHENTICATION_FAILED",
+ "id": "b0a7f5f8-dc2f-4171-b91f-de88ad238e14"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "418": {
+ "description": "I'm Ai",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "I_AM_AI": {
+ "value": {
+ "error": {
+ "message": "You sent a request to Ai-chan, Misskey's showgirl, instead of the server.",
+ "code": "I_AM_AI",
+ "id": "60c46cd1-f23a-46b1-bebe-5d2b73951a84"
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "500": {
+ "description": "Internal server error",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Error"
+ },
+ "examples": {
+ "INTERNAL_ERROR": {
+ "value": {
+ "error": {
+ "message": "Internal error occurred. Please contact us if the error persists.",
+ "code": "INTERNAL_ERROR",
+ "id": "5d37dbcb-891e-41ca-a3d6-e690c97775ac"
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ },
"/endpoint": {
"post": {
"operationId": "post___endpoint", |
📦 Frontend Bundle ReportChunk size diff (4 updated, 0 added, 0 removed)
Startup chunk size (1 updated, 0 added, 0 removed)
Startup chunks are the Vite entry for Bundle Stats
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@CHANGELOG.md`:
- Line 20: CHANGELOG.md の 2026.7.0 配下にあるカスタム絵文字キャッシュ修正の Fix 項目を、## Unreleased
配下の該当する ### General または ### Client
サブセクションへ移動してください。項目の内容は変更せず、リリース前のユーザー影響変更として1行の - Fix: 形式で保持してください。
In `@packages/backend/src/core/CustomEmojiService.ts`:
- Line 68: Invalidate localEmojisStatsCache after successful database updates in
add, update, every bulk update, and delete, alongside
localEmojisCache.refresh(). For multi-process deployments, use the existing
shared-cache or invalidation-notification mechanism so each process clears its
independent stats cache.
In `@packages/frontend/src/components/MkEmojiPicker.vue`:
- Around line 260-261: Update the watch source in
packages/frontend/src/components/MkEmojiPicker.vue lines 260-261 to include
customEmojis or customEmojisMap, ensuring existing query results are
recalculated when custom emojis change. Also update the reaction-list watch
source in packages/frontend/src/components/MkReactionsViewer.vue line 79 to
include customEmojisMap so the list is re-sorted based on current availability.
In `@packages/frontend/src/custom-emojis.ts`:
- Around line 58-66: Update fetchCustomEmojis so the emoji list and emojisStats
are committed only when they represent the same revision: either use an API
response contract that returns a revision shared by the stats and list requests,
or refetch and verify the stats remain unchanged after retrieving the list
before calling setCustomEmojis and set('emojisStats', ...). Prevent an older
list response from overwriting newer event-applied state.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 6b233b74-c0c1-468b-a816-eaee347590e8
📒 Files selected for processing (15)
CHANGELOG.mdpackages/backend/src/core/CustomEmojiService.tspackages/backend/src/server/api/endpoint-list.tspackages/backend/src/server/api/endpoints/emojis/stats.tspackages/frontend/src/boot/common.tspackages/frontend/src/components/MkEmojiPicker.vuepackages/frontend/src/components/MkReactionsViewer.reaction.vuepackages/frontend/src/components/MkReactionsViewer.vuepackages/frontend/src/components/global/MkCustomEmoji.vuepackages/frontend/src/custom-emojis.tspackages/misskey-js/etc/misskey-js.api.mdpackages/misskey-js/src/autogen/apiClientJSDoc.tspackages/misskey-js/src/autogen/endpoint.tspackages/misskey-js/src/autogen/entities.tspackages/misskey-js/src/autogen/types.ts
⚙️ Backend Diagnostics ReportMemory: After GC
V8 Heap Snapshot Statistics
|
There was a problem hiding this comment.
♻️ Duplicate comments (1)
packages/backend/src/core/CustomEmojiService.ts (1)
68-68:⚠️ Potential issue | 🟠 Major複数プロセス環境では統計キャッシュの無効化がまだ不十分です。
MemorySingleCacheはプロセス内メモリのみを無効化するため、更新を処理したプロセス以外では/emojis/statsが最大3分間、古いcount/lastUpdatedAtを返します。複数Backendプロセスをサポートする場合は、共有キャッシュまたはサーバー間の無効化通知を利用してください。単一プロセス運用が前提であれば、その制約を確認してください。Also applies to: 83-83, 101-101
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@packages/backend/src/core/CustomEmojiService.ts` at line 68, Replace the process-local localEmojisStatsCache used by CustomEmojiService with a shared cache or server-to-server invalidation mechanism. Ensure emoji updates invalidate the cached count and lastUpdatedAt across all backend processes, not only in the process handling the update. If the service intentionally supports only a single process, explicitly enforce or document that deployment constraint instead.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@packages/backend/src/core/CustomEmojiService.ts`:
- Line 68: Replace the process-local localEmojisStatsCache used by
CustomEmojiService with a shared cache or server-to-server invalidation
mechanism. Ensure emoji updates invalidate the cached count and lastUpdatedAt
across all backend processes, not only in the process handling the update. If
the service intentionally supports only a single process, explicitly enforce or
document that deployment constraint instead.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 37ac1b84-1d60-46ed-bd74-a36563bb3cf6
📒 Files selected for processing (1)
packages/backend/src/core/CustomEmojiService.ts
| lastUpdatedAt: raw?.lastUpdatedAt ?? null, | ||
| }; | ||
| }); | ||
| } |
There was a problem hiding this comment.
現状、件数と最終更新日時ベースでは絵文字削除が追えないかと思います(物理削除なので)。
「有効な絵文字一覧」としてのバージョンをmetaあたりに持っておくのが良いかと思います。
addやdelete/deleteBulkなどの1操作につき1回更新されるイメージの
There was a problem hiding this comment.
- カスタム絵文字削除した場合は件数が変わる→最終更新日時は変わらないけど件数が変わるのでキャッシュ更新
- 削除した分と同じだけカスタム絵文字を追加する→件数は変わる前と同じになるけど最終更新日時が変わるのでキャッシュ更新
で問題なく更新される説がある
There was a problem hiding this comment.
ありがとうございます。削除の追跡が漏れる懸念はなさそうです。
--
ただ、それでもやはり気になるのが、絵文字一覧の変更有無を表現するためだけに COUNT / MAX の集計を都度行っている点です。
- キャッシュの有効期間が3分と短く、絵文字の追加・削除・更新時にも無効化される
- 複数のHTTPプロセスを使っている環境ではプロセスごとに集計が走る
- キュープロセスなどの別プロセスで行われた変更はHTTPプロセス側のキャッシュを更新できず、最大3分古い値を返す可能性がある
- キャッシュミスが重なった場合、同一の集計クエリが並行して実行され得る
という点から、負荷と整合性の両面でウィークポイントになりやすいと考えています。
そのため再度、metaやRedisなどの共有領域に、集計不要な絵文字一覧のリビジョンを持たせ、論理的な変更操作ごとに更新する方式を提案させて頂きます
What
emojis/statsを追加customEmojisMapをリアクティブにして、カスタム絵文字の更新をバックグラウンドで行うように(初回は待たせる)Why
Fix #16624
Additional info (optional)
DBにインデックスを張るべきかどうかはわからなかったので詳しい方に聞く必要がある(メモリキャッシュは既に入れてあるが…)
Checklist