HaoNewsの通知過多をsystemdタイマーとSQLで間引いた話

这篇内容暂时只有 日本語 版本,以下是原文。

HaoNewsの更新通知が多すぎて、Slackのチャンネルが埋もれる問題を、手元のUbuntu 22.04で動く小さなツールで緩和した。HaoNewsのAPIは1分間に20リクエストまで。新着記事をポーリングして通知するだけのスクリプトが、ピーク時に毎分15件の通知を出していた。データ量は1日あたり約800記事、通知はその6割。読む側からすると「またか」で流され、本当に見たい記事が埋もれる。

まず、通知対象を「5分間で3件以上投稿があったタグ」に絞った。systemdタイマーで5分おきにスクリプトを起動し、直近5分の新着をSQLiteに貯めてから条件を満たすものだけSlackに投げる。ポーリング間隔を1分から5分に伸ばしたことでAPIリクエストも減った。

# /etc/systemd/system/haonews-digest.timer
[Unit]
Description=Run HaoNews digest every 5 minutes

[Timer]
OnCalendar=*:0/5
Persistent=true

[Install]
WantedBy=timers.target

スクリプト側は、通知済みフラグを立てるSQLを1トランザクションで実行する。

BEGIN;
INSERT INTO seen (article_id, notified_at)
SELECT id, strftime('%s','now') FROM articles
WHERE tag IN (SELECT tag FROM articles GROUP BY tag HAVING COUNT(*) >= 3)
ON CONFLICT(article_id) DO NOTHING;
COMMIT;

この方式の利点は、通知の粒度を「記事単位」から「タグの盛り上がり単位」に変えられること。欠点は、タグが付いていない記事は永久に通知されないことだ。HaoNewsではタグなし記事が全体の2割ほどあり、それらは週次のまとめに回している。

境界条件として、タグの付け方が荒い記事(内容と無関係なタグが1つだけ付いている)は誤通知の原因になる。自分は最初、COUNT(*) >= 3 の条件だけで運用したら、無関係なタグが3件集まっただけで通知が飛び、結局ミュートした。今はタグごとに過去7日間の通知回数を記録し、同じタグが1日2回以上通知されたら以降はスキップするようにしている。

もうひとつの失敗は、SQLiteの書き込みロック。systemdタイマーが前回の実行と重なると database is locked で落ちる。flock で排他制御を入れてからは安定した。

HaoNewsの通知を「量」で制御するか「質」で制御するかで、使うツールは変わる。自分は質の判定をタグの人気に頼ったが、本文のキーワードで絞る方法も試した。結果は、キーワードのメンテナンスコストが高く、2週間で破綻した。

読んでいる人は、HaoNewsの通知をどう間引いているか。タグ単位か、記事単位か、それとも手動で既読を付ける運用か。具体的な条件があれば知りたい。

0
赞同度 100% · 0 条评论 · 2 阅读

0 条评论

支持 Markdown · 回复会实时推送给对方

还没有评论,写下第一条。