PaPoo
cover
technews
Author
technews
世界の技術ニュースをリアルタイムでキャッチし、日本語でわかりやすく発信。AI・半導体・スタートアップから規制動向まで、グローバルテックシーンの「今」をお届けします。

SQLiteで「待ち受け通知」と「ジョブキュー」を実現する実験的プロジェクト honker を紹介

キーポイント

honker って何者?

honker は、一言でいうと SQLite に「通知」「キュー」「イベント配信」「定期実行」を足すための拡張です。

元記事の説明をざっくり言い換えると、

そんなときに、​SQLite の中だけで完結させようというプロジェクトです。

この発想、かなり好きです。
というのも、アプリを作っていると「本体のデータは SQLite なのに、通知やジョブだけ別システムに逃がす」ことがよくあります。すると、

みたいな“地味にしんどい問題”が増えるんですよね。
honker はそこを、​​「なら同じファイルに寄せよう」​という方向で殴りにいっています。かなり潔いです。

何ができるのか

元記事によると、honker でできることは主に次の通りです。

要するに、​​「SQLite をただの保存場所ではなく、イベント駆動の基盤として使う」​ための部品が揃っています。

どう動くのか:ポイントは「polling を減らす」こと

honker の説明で特に面白いのが、​アプリ側の polling を置き換えるという考え方です。

polling というのは、ざっくり言うと
「仕事が来たかな? 来たかな? 来たかな?」
と、一定間隔で何度も確認する方式です。

これはシンプルですが、

という弱点があります。

honker は PRAGMA data_version を使って、​データベースに更新があったかをかなり軽量に確認し、更新があれば起きるという仕組みを取っています。
元記事では、​単桁マイクロ秒レベルの読み取りを 1ms ごとに行い、​単桁ミリ秒の通知を目指していると説明されています。

ここは技術的にかなり野心的です。
もちろん、すべての環境で常にその通りになるとは限らないはずですが、少なくとも狙いとしては ​「DB を監視するための無駄を極小化する」​ 方向です。
個人的には、この設計思想がかなり好きです。派手な魔法ではなく、​SQLite の既存機能をうまく使って“通知っぽさ”を出しているのが渋い。

なぜ注目されるのか

1. SQLite だけで完結しやすい

SQLite は、今や「小さいアプリ用の簡易DB」というより、​実際に本番で動くストレージとしてかなり広く使われています。
特に、

では普通に主役です。

そこに「キューまで同居させる」というのは、かなり自然な進化に見えます。
DB が主役なら、​ジョブもその隣に置きたい。これはかなり筋が通っています。

2. 二重書き込み問題を避けやすい

元記事では、INSERT INTO ordersqueue.enqueue(...)同じ transaction で commit できることが強調されています。

これは重要です。
たとえば注文データは保存したのに、メール送信用ジョブの enqueue に失敗したら困りますよね。逆に、ジョブだけ入って注文が消えたらもっと困る。

同じ transaction に入れておけば、

のどちらかになるので、​中途半端な状態を作りにくいわけです。

これは現場ではかなり大きいです。
理屈よりも、障害対応のときに効いてきます。こういう“ズレない設計”は、あとからじわじわありがたみが出ます。

3. ただのキューではなく、通知やストリームもある

キューだけだと「非同期で処理する」止まりですが、honker は pub/sub や stream も扱います。
つまり、

まで視野に入っています。

これは「小さなジョブキュー」よりもだいぶ欲張りです。
でも、アプリ開発の実際を見ると、これらはけっこう同じ領域にあります。
“イベントが流れて、誰かが反応する” という意味では、わりと一体の問題なんですよね。

サンプルを見るとイメージしやすい

元記事には Python の例が載っています。

import honker

![image_0002.png](https://github.com/russellromney/honker/raw/main/assets/honker-logo.png)

db = honker.open("app.db")
emails = db.queue("emails")

emails.enqueue({"to": "alice@example.com"})

これは、emails というキューにメール送信用の仕事を積む例です。

ワーカー側ではこういう形になります。

async for job in emails.claim("worker-1"):
    send(job.payload)
    job.ack()

ここでの流れは、

  1. claim() で仕事を取る
  2. 処理する
  3. 成功したら ack() で「終わった」と伝える

というものです。

失敗したら retry することもできます。
こういう設計は、メッセージキューの世界ではおなじみですが、​SQLite の中だけでここまでやるのが honker の面白さです。

「queue を DB に置く」って、実はかなり現実的

元記事では、従来の「Redis + Celery」路線に対して、honker は別の考え方を示しています。

従来のつらさ

honker の考え方

これは小さく見えて、実はかなり大きな思想の違いです。
「何でも専用システムを足せばいい」という発想ではなく、​まず既存の土台を最大限に使う
個人的には、こういう設計のほうが好きです。特に、小〜中規模のプロダクトでは強いと思います。

ただし、Alpha software なので注意

ここは大事です。
honker は Alpha software と明記されています。
つまり、​まだ成熟しきってはいないということです。

なので、現時点では

というよりは、

くらいが現実的だと思います。

また、元記事でも「Postgres がすでにあるなら、pg_notify / pg-boss / Oban などを使うべき」という趣旨が書かれています。
これはかなり誠実です。
つまり honker は「Postgres を置き換える魔法」ではなく、​SQLite を主役にする世界での強力な選択肢なんですね。

対応言語が広いのも魅力

honker は Rust の crate として中核があり、その上に

などの bindings があるとのことです。

ここは実用上かなり嬉しいポイントです。
データの配置や動作の核が Rust 側で定義されていて、各言語は薄いラッパーになっている、というのも好印象です。
“言語ごとに微妙に意味が違う”地獄を避けやすそうだからです。

どんな人に刺さりそうか

honker は、次のような人に刺さりそうです。

逆に、次のようなケースでは慎重になったほうがよさそうです。

元記事でも、​task pipelines/chains/groups/chords や DAG ベースの workflow orchestration は意図的に作っていないとあります。
つまり、これは「何でもできる万能基盤」ではなく、​SQLite に自然に馴染む範囲を強くする道具です。

個人的な感想

率直に言うと、honker はかなり面白いです。
「SQLite は軽量DB」という見方を超えて、​アプリの実行基盤に近づけようとしている感じがするからです。

もちろん、何でも SQLite でやるのが正解、という話ではありません。
でも、現実には「そこまで大きくない」「運用を増やしたくない」「でも非同期処理は必要」というケースが多い。
その隙間を埋める発想として、honker はかなり筋がいいと思います。

特に、​同じファイルにデータとキューを置くという思想は、地味だけど強いです。
派手さはないけど、運用のしんどさを減らす方向に効く。こういうプロジェクトは、使う側の気持ちをよくわかっているな、と思います。

一方で、Alpha である以上、まだ“夢の完成形”ではありません。
だからこそ、今は ​「面白い実験であり、実用の可能性もある」​ という距離感で見るのがちょうどいいのではないでしょうか。


参考: GitHub - russellromney/honker: SQLite extension + bindings for Postgres NOTIFY/LISTEN semantics with durable queues, streams, pub/sub, and scheduler

同じ著者の記事