Skip to content

feat: お知らせを特定日時で自動アーカイブできるようにする#17704

Open
samunohito wants to merge 11 commits into
misskey-dev:developfrom
samunohito:issue-17688-auto-archive-announcements
Open

feat: お知らせを特定日時で自動アーカイブできるようにする#17704
samunohito wants to merge 11 commits into
misskey-dev:developfrom
samunohito:issue-17688-auto-archive-announcements

Conversation

@samunohito

@samunohito samunohito commented Jul 13, 2026

Copy link
Copy Markdown
Member

What

アーカイブする日時を書き込むためのテキストボックスを生やしました

image

畳んだ時のリスト表示はこんな感じ

image

Why

fix #17688

Additional info (optional)

Checklist

  • Read the contribution guide
  • Test working in a local environment
  • (If needed) Add story of storybook
  • (If needed) Update CHANGELOG.md
  • (If possible) Add tests

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

このPRによるapi.jsonの差分

差分はこちら
--- base
+++ head
@@ -2481,6 +2481,13 @@
                     ],
                     "format": "misskey:id",
                     "default": null
+                  },
+                  "autoArchiveAt": {
+                    "type": [
+                      "integer",
+                      "null"
+                    ],
+                    "default": null
                   }
                 },
                 "required": [
@@ -2549,6 +2556,15 @@
                   "$ref": "#/components/schemas/Error"
                 },
                 "examples": {
+                  "INVALID_AUTO_ARCHIVE_AT": {
+                    "value": {
+                      "error": {
+                        "message": "Invalid auto archive date.",
+                        "code": "INVALID_AUTO_ARCHIVE_AT",
+                        "id": "2a892bd5-487d-46a2-a5fe-3d85ad51defe"
+                      }
+                    }
+                  },
                   "INVALID_PARAM": {
                     "value": {
                       "error": {
@@ -2923,6 +2939,13 @@
                       "isActive": {
                         "type": "boolean"
                       },
+                      "autoArchiveAt": {
+                        "type": [
+                          "string",
+                          "null"
+                        ],
+                        "format": "date-time"
+                      },
                       "forExistingUsers": {
                         "type": "boolean"
                       },
@@ -2957,6 +2980,7 @@
                       "icon",
                       "display",
                       "isActive",
+                      "autoArchiveAt",
                       "forExistingUsers",
                       "silence",
                       "needConfirmationToRead",
@@ -3148,6 +3172,12 @@
                   },
                   "isActive": {
                     "type": "boolean"
+                  },
+                  "autoArchiveAt": {
+                    "type": [
+                      "integer",
+                      "null"
+                    ]
                   }
                 },
                 "required": [
@@ -3178,6 +3208,15 @@
                       }
                     }
                   },
+                  "INVALID_AUTO_ARCHIVE_AT": {
+                    "value": {
+                      "error": {
+                        "message": "Invalid auto archive date.",
+                        "code": "INVALID_AUTO_ARCHIVE_AT",
+                        "id": "01b83d7b-2fd5-4d7c-86c4-d03144d16355"
+                      }
+                    }
+                  },
                   "INVALID_PARAM": {
                     "value": {
                       "error": {

Get diff files from Workflow Page

@codecov

codecov Bot commented Jul 13, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 45.12195% with 45 lines in your changes missing coverage. Please review.
✅ Project coverage is 26.26%. Comparing base (212fcaf) to head (54c1745).

Files with missing lines Patch % Lines
packages/backend/src/core/QueueService.ts 0.00% 11 Missing and 2 partials ⚠️
.../backend/src/server/api/endpoints/announcements.ts 0.00% 9 Missing and 1 partial ⚠️
...c/server/api/endpoints/admin/announcements/list.ts 0.00% 9 Missing ⚠️
.../processors/ArchiveAnnouncementProcessorService.ts 50.00% 5 Missing and 1 partial ⚠️
...server/api/endpoints/admin/announcements/create.ts 0.00% 1 Missing and 2 partials ⚠️
...server/api/endpoints/admin/announcements/update.ts 0.00% 1 Missing and 2 partials ⚠️
...ackages/backend/src/queue/QueueProcessorService.ts 50.00% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop   #17704      +/-   ##
===========================================
+ Coverage    25.90%   26.26%   +0.36%     
===========================================
  Files         1178     1181       +3     
  Lines        39984    40275     +291     
  Branches     11071    11133      +62     
===========================================
+ Hits         10358    10580     +222     
- Misses       23755    23815      +60     
- Partials      5871     5880       +9     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

📦 Frontend Bundle Report

Chunk size diff (3 updated, 0 added, 0 removed)
Chunk Before After Δ Δ (%)
(total) 5.9 MB 5.9 MB $\color{orange}{\text{+3.2 KB}}$ $\text{+0.1\%}$
src/pages/admin/announcements.vue ja-JP/aEA5QfpmU-Bv4mixBr.js → ja-JP/gmzNNAQH6-B-2xZzbL.js
7.5 KB 9.3 KB $\color{orange}{\text{+1.8 KB}}$ $\color{orange}{\text{+23.5\%}}$
src/components/MkUserAnnouncementEditDialog.vue ja-JP/aEA5QfpmU-CTmCYSwf2.js → ja-JP/gmzNNAQH6-qkng5Hsg2.js
3.6 KB 4.6 KB $\color{orange}{\text{+1.1 KB}}$ $\color{orange}{\text{+29.3\%}}$
i18n ja-JP/aEA5QfpmU-Pz5tairH.js → ja-JP/gmzNNAQH6-D5dfWNdM.js
216 KB 217 KB $\text{+370 B}$ $\color{orange}{\text{+0.2\%}}$
(other generated chunks) 2 MB 2 MB $\text{+36 B}$ $\text{+0\%}$
Startup chunk size (1 updated, 0 added, 0 removed)
Chunk Before After Δ Δ (%)
(total) 1 MB 1 MB $\text{+406 B}$ $\text{+0\%}$
i18n ja-JP/aEA5QfpmU-Pz5tairH.js → ja-JP/gmzNNAQH6-D5dfWNdM.js
216 KB 217 KB $\text{+370 B}$ $\color{orange}{\text{+0.2\%}}$
(other generated chunks) 753 KB 753 KB $\text{+36 B}$ $\text{+0\%}$
(other) 63 KB 63 KB 0 B 0%

Startup chunks are the Vite entry for src/_boot_.ts and its static imports.

Bundle Stats

Bundles Modules Entries Imports Size
Static Dynamic Rendered Gzip Brotli
Before 467 2,867 21 8,609 324 10 MB 2.8 MB 2.4 MB
After 467 2,868 21 8,613 324 10 MB 2.8 MB 2.4 MB
Δ 0 $\color{orange}{\text{+1}}$ 0 $\color{orange}{\text{+4}}$ 0 $\color{orange}{\text{+4.9 KB}}$ $\color{orange}{\text{+1.3 KB}}$ $\text{+977 B}$
Δ (%) 0% $\text{+0\%}$ 0% $\text{+0\%}$ 0% $\text{+0\%}$ $\text{+0\%}$ $\text{+0\%}$

Open treemap HTML

@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

⚙️ Backend Memory Usage Report

After GC

Metric Base Head Δ median Δ MAD Δ min Δ max
HeapUsed 72.1 MB
± 0 MB
72.1 MB
± 0 MB
$\text{-0 MB}$
$\text{-0\%}$
0 MB $\color{green}{\text{-0.3 MB}}$ $\text{+0 MB}$
PSS 279.7 MB
± 1.7 MB
269 MB
± 1 MB
$\color{green}{\text{-10.7 MB}}$
$\color{green}{\text{-3.8\%}}$
4.1 MB $\color{green}{\text{-14.9 MB}}$ $\color{green}{\text{-2.4 MB}}$
USS 260.8 MB
± 2 MB
250.1 MB
± 1 MB
$\color{green}{\text{-10.7 MB}}$
$\color{green}{\text{-4.1\%}}$
3.8 MB $\color{green}{\text{-15.3 MB}}$ $\color{green}{\text{-2.4 MB}}$
External 8.7 MB
± 0 MB
8.7 MB
± 0 MB
$\text{+0 MB}$
$\text{+0\%}$
0 MB $\text{+0 MB}$ $\text{+0 MB}$

V8 Heap Snapshot Statistics

Metric Base Head Δ median Δ MAD Δ min Δ max
$\color{gray}{\rule{8pt}{8pt}}$ Total 85 MB
± 952 B
85 MB
± 1.8 KB
$\text{-62 KB}$
$\text{-0.1\%}$
12 KB $\color{green}{\text{-258 KB}}$ $\text{-47 KB}$
$\color{orange}{\rule{8pt}{8pt}}$ Code28.8% → 28.8%
25 MB 25 MB $\text{+10 KB}$ 6.7 KB $\text{+688 B}$ $\text{+17 KB}$
$\color{red}{\rule{8pt}{8pt}}$ Strings34.9% → 35%
30 MB 30 MB $\text{+14 KB}$ 1.2 KB $\text{+9.5 KB}$ $\text{+15 KB}$
$\color{cyan}{\rule{8pt}{8pt}}$ JS arrays4.8% → 4.9%
4.1 MB 4.1 MB $\text{+392 B}$ 0 B $\text{+392 B}$ $\text{+392 B}$
$\color{green}{\rule{8pt}{8pt}}$ Typed arrays0.6% → 0.6%
533 KB 533 KB 0 B 0 B 0 B 0 B
$\color{yellow}{\rule{8pt}{8pt}}$ System objects2.6% → 2.6%
2.2 MB 2.2 MB $\text{+5.2 KB}$ 1.4 KB $\text{-376 B}$ $\text{+6.6 KB}$
$\color{violet}{\rule{8pt}{8pt}}$ Other JS objs28.2% → 28.1%
24 MB 24 MB $\text{-81 KB}$ 2.2 KB $\color{green}{\text{-291 KB}}$ $\text{-78 KB}$
$\color{pink}{\rule{8pt}{8pt}}$ Other non-JS objs0% → 0%
39 KB 39 KB 0 B 0 B 0 B 0 B
Head heap snapshot composition
%%{init: {"sankey":{"showValues":false,"linkColor":"target","labelStyle":"outlined","nodeAlignment":"center","nodePadding":10,"nodeColors":{"Head":"#888888","code":"#f28e2c","bytecode":"#f28e2c","Other":"#888888","strings":"#e15759","string":"#e15759","jsArrays":"#76b7b2","typedArrays":"#59a14f","systemObjects":"#edc949","otherJsObjects":"#af7aa1","otherNonJsObjects":"#ff9da7"}}}}%%
sankey-beta
"Head","Code",28.8
"Code","bytecode",9.58
"Code","Other",19.22
"Head","Strings",34.97
"Strings","string",34.23
"Strings","Other",0.74
"Head","JS arrays",4.85
"Head","Typed arrays",0.62
"Head","System objects",2.58
"Head","Other JS objs",28.13
"Head","Other non-JS objs",0.05
Loading

Download representative V8 heap snapshot (head)

Runtime Loaded JS Footprint

Click to show
Metric Base Head Δ Δ (%)
Loaded JS modules 230 230 0 0%
Loaded JS source 11 MB 11 MB $\color{orange}{\text{+4.3 KB}}$ $\color{orange}{\text{+0\%}}$
External packages loaded 31 31 0 0%
Native addon packages 2 2 0 0%

Largest Newly Loaded Modules

Module Package Loaded JS
packages/backend/built/ApNoteService-laPpvs1N.js backend 2.1 MB
packages/backend/built/ServerService-BM4UTyUF.js backend 977 KB
packages/backend/built/endpoints-e6kRDrZx.js backend 876 KB
packages/backend/built/QueueService-DnuUFxYu.js backend 874 KB
packages/backend/built/MetaEntityService-CoubOE_M.js backend 627 KB
packages/backend/built/ap-request-DUIUdGf0.js backend 237 KB
packages/backend/built/_-D5yjR5hE.js backend 81 KB
packages/backend/built/gen-spec-1g7fi2Mc.js backend 57 KB
packages/backend/built/GlobalModule-DOgh8nny.js backend 53 KB
packages/backend/built/ap-request-BojYXLjT.js backend 19 KB

@samunohito
samunohito marked this pull request as ready for review July 13, 2026 11:21
@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Jul 13, 2026
pattern: '*/5 * * * *',
}, {
name: 'checkExpiredAnnouncements',
pattern: '* * * * *',

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1分ごとに実行って結構高頻度な気がするけどそんなもんかしら

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ポーリングじゃなくてジョブの実行時間を直接していすれば済みそう

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed
f3fbc6d

@syuilo

syuilo commented Jul 15, 2026

Copy link
Copy Markdown
Member

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 15, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4cd75335-f4ed-486a-962d-5fae0bb96e97

📥 Commits

Reviewing files that changed from the base of the PR and between f3fbc6d and 8a9df02.

📒 Files selected for processing (2)
  • CHANGELOG.md
  • packages/backend/src/queue/QueueProcessorService.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • CHANGELOG.md
  • packages/backend/src/queue/QueueProcessorService.ts

📝 Walkthrough

Walkthrough

お知らせに任意の自動アーカイブ日時を設定できる機能を追加しました。日時に基づく状態判定、キューによる自動アーカイブ、API、管理画面、型定義、ローカライズ、テストが更新されています。

Changes

Announcement auto-archive

Layer / File(s) Summary
Auto-archive contracts and persistence
packages/backend/migration/..., packages/backend/src/models/Announcement.ts, packages/backend/src/queue/types.ts, packages/misskey-js/src/autogen/types.ts, locales/ja-JP.yml, packages/i18n/src/autogen/locale.ts
autoArchiveAt をデータベース、キュー payload、生成型、ローカライズ定義に追加しました。
Archive job scheduling and processing
packages/backend/src/core/QueueService.ts, packages/backend/src/queue/...
自動アーカイブ用ジョブの登録・削除・実行と、キュープロセッサの登録を追加しました。
Lifecycle rules and API filtering
packages/backend/src/core/AnnouncementService.ts, packages/backend/src/server/api/endpoints/..., packages/backend/test/{unit,e2e}/announcements*
作成・更新・削除・起動時のジョブ管理、期限に基づく一覧判定、入力検証、関連テストを追加しました。
Administrative announcement editing
packages/frontend/src/components/MkUserAnnouncementEditDialog.vue, packages/frontend/src/pages/admin/announcements.vue, CHANGELOG.md
管理画面で日時を入力・表示・送信できるようにし、変更履歴へ機能を記載しました。

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Admin
  participant AdminAnnouncementsAPI
  participant AnnouncementService
  participant QueueService
  participant ArchiveAnnouncementProcessorService
  Admin->>AdminAnnouncementsAPI: create or update autoArchiveAt
  AdminAnnouncementsAPI->>AnnouncementService: save announcement
  AnnouncementService->>QueueService: scheduleAnnouncementArchive
  QueueService->>ArchiveAnnouncementProcessorService: process archiveAnnouncement job
  ArchiveAnnouncementProcessorService->>AnnouncementService: archiveAnnouncement
Loading

Poem

ぴょんと日時をセットして
お知らせは時を待つ
キューが鐘を鳴らしたら
そっとアーカイブへ跳ねる
にんじん色の新機能!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: automatic archiving of announcements at a specified time.
Description check ✅ Passed The description follows the template with What, Why, and checklist sections and is sufficiently complete.
Linked Issues check ✅ Passed The changes implement optional auto-archive datetime support and preserve existing behavior when it is empty, matching #17688.
Out of Scope Changes check ✅ Passed The added migrations, API, UI, localization, queue, and tests all support the auto-archive feature and appear in scope.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/backend/src/server/api/endpoints/admin/announcements/create.ts (1)

26-59: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Response schema should include autoArchiveAt.

paramDef accepts autoArchiveAt, and the handler returns the packed announcement, but res.properties still omits the field. Add it here so AdminAnnouncementsCreateResponse stays aligned with the API payload.

🔧 Suggested fix
 			imageUrl: {
 				type: 'string',
 				optional: false, nullable: true,
 			},
+			autoArchiveAt: {
+				type: 'string',
+				optional: false, nullable: true,
+				format: 'date-time',
+			},
 		},
 	},
🤖 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/server/api/endpoints/admin/announcements/create.ts`
around lines 26 - 59, Update the response schema’s res.properties in the admin
announcements create endpoint to include autoArchiveAt, matching the field
accepted by paramDef and returned by the packed announcement so
AdminAnnouncementsCreateResponse reflects the complete API payload.
🤖 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 `@packages/backend/src/core/AnnouncementService.ts`:
- Around line 35-51: Update onModuleInit so a failure from scheduling one
announcement does not reject the entire initialization flow: isolate each
scheduleAnnouncementArchive call and handle its rejection per announcement,
while allowing the remaining announcements to be scheduled and bootstrap to
complete.

In `@packages/backend/src/core/QueueService.ts`:
- Around line 256-282: Update scheduleAnnouncementArchive to configure retries
in the options passed to systemQueue.add for archiveAnnouncement jobs. Set an
attempts value greater than one, preserving the existing job ID, delay, and
cleanup behavior.

---

Outside diff comments:
In `@packages/backend/src/server/api/endpoints/admin/announcements/create.ts`:
- Around line 26-59: Update the response schema’s res.properties in the admin
announcements create endpoint to include autoArchiveAt, matching the field
accepted by paramDef and returned by the packed announcement so
AdminAnnouncementsCreateResponse reflects the complete API payload.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 3c49b0d7-625d-4288-a1a1-f00885fc2a46

📥 Commits

Reviewing files that changed from the base of the PR and between f74b427 and f3fbc6d.

📒 Files selected for processing (20)
  • CHANGELOG.md
  • locales/ja-JP.yml
  • packages/backend/migration/1783913268595-AutoArchiveAnnouncements.js
  • packages/backend/src/core/AnnouncementService.ts
  • packages/backend/src/core/QueueService.ts
  • packages/backend/src/models/Announcement.ts
  • packages/backend/src/queue/QueueProcessorModule.ts
  • packages/backend/src/queue/QueueProcessorService.ts
  • packages/backend/src/queue/processors/ArchiveAnnouncementProcessorService.ts
  • packages/backend/src/queue/types.ts
  • packages/backend/src/server/api/endpoints/admin/announcements/create.ts
  • packages/backend/src/server/api/endpoints/admin/announcements/list.ts
  • packages/backend/src/server/api/endpoints/admin/announcements/update.ts
  • packages/backend/src/server/api/endpoints/announcements.ts
  • packages/backend/test/e2e/announcements.ts
  • packages/backend/test/unit/AnnouncementService.ts
  • packages/frontend/src/components/MkUserAnnouncementEditDialog.vue
  • packages/frontend/src/pages/admin/announcements.vue
  • packages/i18n/src/autogen/locale.ts
  • packages/misskey-js/src/autogen/types.ts

Comment on lines +35 to +51
private queueService: QueueService,
) {
}

@bindThis
public async onModuleInit(): Promise<void> {
// アップデート前に作成されたお知らせやRedisの再構築後にも予約を復元する
const announcements = await this.announcementsRepository.findBy({
isActive: true,
autoArchiveAt: Not(IsNull()),
});

await Promise.all(announcements.map(announcement =>
this.queueService.scheduleAnnouncementArchive(announcement.id, announcement.autoArchiveAt!),
));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Promise.all in onModuleInit can abort bootstrap on a single failure.

If scheduleAnnouncementArchive rejects for any one announcement (e.g. transient Redis issue), Promise.all rejects the whole batch, and since this runs in OnModuleInit, it can fail application bootstrap for an unrelated transient error, risking a crash-loop/outage on deploy or restart.

🔧 Suggested fix: isolate per-item failures
 		await Promise.all(announcements.map(announcement =>
-			this.queueService.scheduleAnnouncementArchive(announcement.id, announcement.autoArchiveAt!),
+			this.queueService.scheduleAnnouncementArchive(announcement.id, announcement.autoArchiveAt!).catch(err => {
+				// ログを出し、他の予約処理をブロックしないようにする
+				console.error(`Failed to reschedule archive for announcement ${announcement.id}`, err);
+			}),
 		));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
private queueService: QueueService,
) {
}
@bindThis
public async onModuleInit(): Promise<void> {
// アップデート前に作成されたお知らせやRedisの再構築後にも予約を復元する
const announcements = await this.announcementsRepository.findBy({
isActive: true,
autoArchiveAt: Not(IsNull()),
});
await Promise.all(announcements.map(announcement =>
this.queueService.scheduleAnnouncementArchive(announcement.id, announcement.autoArchiveAt!),
));
}
private queueService: QueueService,
) {
}
`@bindThis`
public async onModuleInit(): Promise<void> {
// アップデート前に作成されたお知らせやRedisの再構築後にも予約を復元する
const announcements = await this.announcementsRepository.findBy({
isActive: true,
autoArchiveAt: Not(IsNull()),
});
await Promise.all(announcements.map(announcement =>
this.queueService.scheduleAnnouncementArchive(announcement.id, announcement.autoArchiveAt!).catch(err => {
// ログを出し、他の予約処理をブロックしないようにする
console.error(`Failed to reschedule archive for announcement ${announcement.id}`, err);
}),
));
}
🤖 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/AnnouncementService.ts` around lines 35 - 51,
Update onModuleInit so a failure from scheduling one announcement does not
reject the entire initialization flow: isolate each scheduleAnnouncementArchive
call and handle its rejection per announcement, while allowing the remaining
announcements to be scheduled and bootstrap to complete.

Comment on lines +256 to +282
@bindThis
public async scheduleAnnouncementArchive(announcementId: MiAnnouncement['id'], autoArchiveAt: Date): Promise<void> {
const jobId = this.announcementArchiveJobId(announcementId, autoArchiveAt);
const existingJob = await this.systemQueue.getJob(jobId);
if (existingJob != null) {
const state = await existingJob.getState();
if (state !== 'completed' && state !== 'failed') return;
await this.systemQueue.remove(jobId);
}

const data: ArchiveAnnouncementJobData = {
announcementId,
autoArchiveAt: autoArchiveAt.getTime(),
};

await this.systemQueue.add('archiveAnnouncement', data, {
jobId,
delay: Math.max(0, autoArchiveAt.getTime() - Date.now()),
removeOnComplete: {
age: 3600 * 24 * 7, // keep up to 7 days
count: 30,
},
removeOnFail: {
age: 3600 * 24 * 7, // keep up to 7 days
count: 100,
},
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate system-queue defaults and archive processor behavior.
rg -n -C 4 'queue:system|defaultJobOptions|attempts:|archiveAnnouncement' packages/backend

# Locate coverage for scheduling and failed-job recovery.
rg -n -C 3 'scheduleAnnouncementArchive|ArchiveAnnouncement|autoArchiveAt' \
  packages/backend/test packages/backend/src

Repository: misskey-dev/misskey

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== QueueModule.ts outline ==\n'
ast-grep outline packages/backend/src/core/QueueModule.ts --view expanded || true

printf '\n== QueueModule.ts relevant lines ==\n'
sed -n '1,140p' packages/backend/src/core/QueueModule.ts | cat -n

printf '\n== search baseQueueOptions / defaultJobOptions ==\n'
rg -n -C 4 'function baseQueueOptions|const baseQueueOptions|defaultJobOptions|attempts' packages/backend/src/core packages/backend/src/queue

printf '\n== base queue helper file candidates ==\n'
fd -a 'QueueModule.ts|queue.*ts|baseQueueOptions' packages/backend/src | head -n 50

Repository: misskey-dev/misskey

Length of output: 17366


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== packages/backend/src/queue/const.ts ==\n'
sed -n '1,220p' packages/backend/src/queue/const.ts | cat -n

printf '\n== search for defaultJobOptions in repository ==\n'
rg -n -C 3 'defaultJobOptions|attempts\s*[:=]' packages/backend/src packages/backend/test

printf '\n== search for system queue add sites ==\n'
rg -n -C 2 "systemQueue\.add\(" packages/backend/src

Repository: misskey-dev/misskey

Length of output: 7389


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== QueueProcessorService worker setup ==\n'
sed -n '1,260p' packages/backend/src/queue/QueueProcessorService.ts | cat -n

printf '\n== search for Worker creation / retry-related options ==\n'
rg -n -C 4 'new Bull\.Worker|Worker\(|attempts|backoff|autorun|concurrency|useWorker' packages/backend/src/queue packages/backend/src/core

printf '\n== bullmq version and docs references in repo ==\n'
rg -n -C 2 'bullmq|retrying-failing-jobs|defaultJobOptions' package.json pnpm-lock.yaml packages/backend/package.json README.md packages/backend/src

Repository: misskey-dev/misskey

Length of output: 50375


🌐 Web query:

BullMQ default attempts value if attempts option is omitted retry failing jobs documentation

💡 Result:

In BullMQ, the default value for the attempts option is 1 [1][2][3]. This means that if the attempts option is omitted, the job will be executed once and will not be retried upon failure [4][3]. To enable automatic retries, you must explicitly set the attempts option to a value greater than 1 [4].

Citations:


Add retries for announcement archive jobs. BullMQ defaults attempts to 1, so a transient failure here won’t retry and the announcement can stay active until something else reschedules it.

🤖 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/QueueService.ts` around lines 256 - 282, Update
scheduleAnnouncementArchive to configure retries in the options passed to
systemQueue.add for archiveAnnouncement jobs. Set an attempts value greater than
one, preserving the existing job ID, delay, and cleanup behavior.

@github-actions

Copy link
Copy Markdown
Contributor

🖥 Frontend Browser Metrics

Only metrics showing significant changes are displayed.

Metric Base Head Δ median Δ MAD Δ min Δ max
Tab memory 9.2 MB 9.1 MB $\color{green}{\text{-30 KB}}$ 99 KB $\color{green}{\text{-144 KB}}$ $\color{orange}{\text{+69 KB}}$

View details

Requests by resource type
Type Requests Encoded bytes
Base Head Δ Base Head Δ
Document 2 2 0 33 KB 33 KB 0 B
Script 144 144 0 2.1 MB 2.1 MB $\color{orange}{\text{+72 B}}$
Stylesheet 58 58 0 288 KB 288 KB 0 B
Fetch 22 22 0 73 KB 73 KB 0 B
Image 11 11 0 254 KB 254 KB 0 B
Font 2 2 0 117 KB 117 KB 0 B
Other 9 9 0 421 KB 421 KB $\color{green}{\text{-16 B}}$
V8 heap snapshot statistics
Metric Base Head Δ median Δ MAD Δ min Δ max
$\color{gray}{\rule{8pt}{8pt}}$ Total 12 MB
± 11 KB
12 MB
± 6.9 KB
$\text{+1.1 KB}$
$\text{+0\%}$
18 KB $\text{-68 KB}$ $\text{+66 KB}$
$\color{orange}{\rule{8pt}{8pt}}$ Code25.1% → 25%
2.9 MB 2.9 MB $\text{-1 KB}$ 2.2 KB $\text{-10 KB}$ $\text{+1.1 KB}$
$\color{red}{\rule{8pt}{8pt}}$ Strings10.7% → 10.7%
1.2 MB 1.2 MB $\text{+116 B}$ 264 B $\text{-252 B}$ $\text{+540 B}$
$\color{cyan}{\rule{8pt}{8pt}}$ JS arrays1.1% → 1.1%
128 KB 128 KB $\text{+28 B}$ 0 B $\text{-28 B}$ $\text{+28 B}$
$\color{green}{\rule{8pt}{8pt}}$ Typed arrays0% → 0%
0 B 0 B 0 B 0 B 0 B 0 B
$\color{yellow}{\rule{8pt}{8pt}}$ System objects0% → 0%
0 B 0 B 0 B 0 B 0 B 0 B
$\color{violet}{\rule{8pt}{8pt}}$ Other JS objs18.4% → 18.5%
2.1 MB 2.1 MB $\text{+164 B}$ 52 B $\text{+36 B}$ $\text{+1.5 KB}$
$\color{pink}{\rule{8pt}{8pt}}$ Other non-JS objs44.6% → 44.7%
5.1 MB 5.1 MB $\text{+2.4 KB}$ 16 KB $\text{-58 KB}$ $\text{+66 KB}$
Head heap snapshot composition
%%{init: {"sankey":{"showValues":false,"linkColor":"target","labelStyle":"outlined","nodeAlignment":"center","nodePadding":10,"nodeColors":{"Head":"#888888","code":"#f28e2c","system / InstructionStream":"#f28e2c","Other":"#888888","strings":"#e15759","string":"#e15759","jsArrays":"#76b7b2","otherJsObjects":"#af7aa1","object shape":"#af7aa1","otherNonJsObjects":"#ff9da7","Extra native bytes":"#ff9da7","system / ExternalStringData":"#ff9da7"}}}}%%
sankey-beta
"Head","Code",25.04
"Code","system / InstructionStream",13.45
"Code","Other",11.59
"Head","Strings",10.71
"Strings","string",10.44
"Strings","Other",0.27
"Head","JS arrays",1.11
"Head","Other JS objs",18.47
"Other JS objs","object shape",5.73
"Other JS objs","Other",12.73
"Head","Other non-JS objs",44.68
"Other non-JS objs","Extra native bytes",18.17
"Other non-JS objs","system / ExternalStringData",14.24
"Other non-JS objs","Other",12.27
Loading

Download representative head heap snapshot

@syuilo

syuilo commented Jul 16, 2026

Copy link
Copy Markdown
Member

/preview

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

packages/backend:test packages/backend Server side specific issue/PR packages/frontend Client side specific issue/PR packages/misskey-js size:L This PR changes 100-499 lines, ignoring generated files.

Projects

Development

Successfully merging this pull request may close these issues.

指定した日時を過ぎたら自動的にアーカイブされるお知らせを作りたい

3 participants