
2026/02/19 20:07
**Oban を使って Elixir と Python を結ぶ**
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
(以下のテキストを日本語に翻訳してください。)
Text to translate
(to avoid the inference):**
Summary
Oban は、JSON 引数付きの共有
oban_jobs テーブルへの読み書きを行うことで、Elixir ↔ Python の相互運用性を可能にし、クロス言語ジョブキューとして機能します。 “Badge Forge” デモでは、Elixir プロセスがバッジ生成ジョブをエンキューし、Python ワーカー(GenerateBadge)がそれらのジョブを処理します。 Python ワーカーは WeasyPrint を使用して HTML を PDF にレンダリングし、ファイルを保存した後、printing キューに確認ジョブを再度エンキューします。 Elixir ワーカー(BadgeForge.PrintCenter)がこの確認をログに記録し、印刷ロジックをトリガーします。 両言語は独立した Oban クラスターを実行し、共有テーブルのみで調整します。また、Postgres を介して PubSub 通知も交換できます。 localhost:4000(Oban Web Docker イメージが提供)にあるデモのダッシュボードでは、開発者はインスタンス全体のすべてのジョブを監視できます。この双方向ワークフローは、異種スタックがそれぞれのエコシステムで最も得意とする機能(PDF レンダリングに Python、オーケストレーションに Elixir)を活用し、共有コードベースやモノリシックサービスを必要とせずに動作できることを示しています。 例は、あるエコシステムで成熟したライブラリが不足している場合に、同様のクロス言語パイプラインを試すよう促します。本文
Elixir アプリが「Python にしかない(あるいはより成熟した)機能」を必要とする場合、どのような選択肢がありますか?
- 機械学習モデル
- PDF レンダリングライブラリ
- 音声/映像編集ツール
HTTP サービスを呼び出すかメッセージキューを利用する方法もありますが、Oban を経由した方が簡単です。
Elixir と Python の間で永続的なジョブを透過的に交換できる仕組みを持つことで、新たな可能性が広がります。
Badge Forge
Badge Forge は、ほんのわずかな橋渡しで実現できることを示す小さなデモです。
会議バッジを印刷します:PDF の生成は Python で WeasyPrint を使い、ジョブオーケストレーションは Elixir 側で Oban に任せます。
共通データベースの共有
両方の
oban ライブラリは同じ oban_jobs テーブルへ読み書きを行います。ジョブ引数は JSON で保存されるため、言語に依存しません。
Elixir アプリが Python ワーカー(あるいはその逆)用のジョブをキューに入れるときは、単に行を書き込みます;相手側はキュー名で取得します。
- 各側が独自にクラスタリーダーシップを保持するので、ノード同士がリーダー権限を争いません。
- PubSub 通知は Postgres を介してリアルタイムでやり取りできます。
実際の印刷
1. ジョブのキューイング(Elixir)
def enqueue_batch(count \\ 100) do generate = fn _ -> args = %{ id: Ecto.UUID.generate(), name: fake_name(), company: fake_company(), type: Enum.random(~w(attendee speaker sponsor organizer)) } Oban.Job.new(args, worker: "badge_forge.generator.GenerateBadge", queue: :badges) end 1..count |> Enum.map(generate) |> Oban.insert_all() end
注: ワーカー名は文字列 (
"badge_forge.generator.GenerateBadge")、Python 側の完全修飾名と一致させます。
2. ジョブ処理(Python)
from oban import Job, Oban, worker from weasyprint import HTML @worker(max_attempts=5, queue="badges") class GenerateBadge: async def process(self, job: Job) -> None: badge_id = job.args["badge_id"] name = job.args["name"] html = render_badge_html(name, job.args["company"], job.args["type"]) path = BADGES_DIR / f"{name}.pdf" # PDF を生成 HTML(string=html).write_pdf(path) # Elixir に確認ジョブを再投入 await Oban.get_instance().enqueue( Job(args={"id": badge_id, "name": name, "path": str(path)}, queue="printing", worker="BadgeForge.PrintCenter") )
3. 確認処理(Elixir)
defmodule BadgeForge.PrintCenter do use Oban.Worker, queue: :printing require Logger @impl Oban.Worker def perform(%Job{args: %{"id" => id, "name" => name, "path" => path}}) do Logger.info("Printing badge #{id} for #{name}: #{path}…") # 実際の印刷ロジックをここに… :ok end end
サンプル出力
iex> BadgeForge.enqueue_batch(10) :ok
Python のログ(整形済み):
[INFO] oban: { "id":14, "worker":"badge_forge.generator.GenerateBadge", "queue":"badges", ... }
Elixir のログ:
[info] Printing badge 7bfb7c39 for Alasdair Fraser: /some/path…
アクティビティの可視化
すべての接続済みインスタンスからジョブを監視するため、Docker で独立した Oban Web ダッシュボードを起動します。
docker run -d \ -e DATABASE_URL="postgres://user:pass@host.docker.internal:5432/badge_forge_dev" \ -p 4000:4000 \ ghcr.io/oban-bg/oban-dash
http://localhost:4000 を開けば、キューの活動とメトリクスが確認できます。
双方向の橋渡し
Badge Forge は次のことを示しています:
- Elixir 側から Python の強み(例:PDF 生成)を活用できる。
- Python エコシステムに Elixir のジョブオーケストレーションを持ち込める。
このパターンは、ある言語が他方で不足しているツールを提供する場合に実務的です。
完全なデモコードと設定については、元記事にリンクされたリポジトリをご覧ください。