**オベリスク 0.32:**  
- **キャンセル機能**  
- **WebAPI**  
- **PostgreSQL(Postgres)**

2025/12/30 4:58

**オベリスク 0.32:** - **キャンセル機能** - **WebAPI** - **PostgreSQL(Postgres)**

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

概要
Obelisk 0.32 は、ワークフローエンジンをより柔軟で堅牢にするための複数の新機能を導入します。

  1. 協調的キャンセル(Cooperative cancellation): ワークフローとアクティビティが親からキャンセルされた際に、タスクをきれいに停止できるようになり、分散サガで自然な補償操作を実現します。
  2. 多形式 WebAPI (プレーンテキストおよび JSON): gRPC だけでなく、HTTP 上のテキストも扱えるようになり、サーバーは gRPC / gRPC‑Web に加えてポート 5005 でテキスト通信を受け付けます。
  3. PostgreSQL サポート: マルチノードデプロイメントに対応し、高可用性構成が可能となります。これにより、単一障害点を排除し、仮想マシン間でスケールアップが容易になります。
  4. 新しいプレーンテキスト HTTP ポート (5005) が外部アクセスと設定を簡素化します。

主な詳細

  • キャンセルは gRPC または WebAPI を通じて行われますが、対象は 葉アクティビティ と遅延リクエストのみです。ワークフロー全体のキャンセルはできません。
  • アプリ起動時のワークフロー例では「すべてか無い」(all‑or‑nothing) のセマンティクスが示され、子プロセスの失敗がトップレベルでクリーニングをトリガーします。これにより協調的キャンセルの実際の動作が確認できます。
  • PostgreSQL の設定は
    obelisk.toml
    に記述し、その利用により WASM コンポーネントを VM 間で分散させ、負荷に応じて動的にスケールアウトできるようになります。

これらの拡張機能は、SQLite + Litestream バックアップと gRPC のみのキャンセルという以前の制限を克服し、Obelisk をより堅牢でスケーラブルなデプロイメントへと位置づけます。

本文

2025‑12‑29 – Obelisk 0.32

Obelisk 0.32 では、ワークフローとアクティビティの協調的なキャンセル機能、新しい WebAPI(複数フォーマットに対応)、およびマルチノード展開・高可用性を実現する PostgreSQL サポートが追加されました。


キャンセル

前回の発表で述べたように、Obelisk が呼び出す関数(ワークフローもアクティビティも)は 失敗し得る 必要があります。
v0.29.0 以降では永続的なスリープも含まれます。

これにより以下が可能になります:

  • アクティビティと遅延要求のキャンセル
  • ワークフロー内でのキャンセル処理をきれいに行う
workflow_support::sleep(ScheduleAt::In(SchedulingDuration::Seconds(10)))
    .map_err(|()| MyWorkflowError::Cancelled)?;

some_activity::send_request()
    .map_err(|()| MyWorkflowError::Cancelled)?; // キャンセルとリトライの失敗を処理

キャンセルは gRPC または WebAPI(以下参照)で実行されます。
ワークフローをキャンセルする唯一の方法は、その ― アクティビティおよび遅延要求 ― をキャンセルすることです。

一部エンジンではワークフロー自体のキャンセルがサポートされていますが、次ステップで停止させると分散サガに必要なクリーンアップ/補償処理が行えません。
Obelisk は 協調的 なキャンセルをサポートし、補償処理を書きやすくします。

fn app_init(
    org_slug: String,
    app_name: String,
    obelisk_config: ObeliskConfig,
    init_config: AppInitConfig,
) -> Result<(), AppInitError> {
    // import を使ってサブワークフローを起動。
    // いずれかのエラー(トラップ/パニック含む)でアプリ全体を削除。
    workflow_import::prepare_volume(...)
        .map_err(|err| cleanup(...))?;

    workflow_import::wait_for_secrets(...)
        .map_err(|err| cleanup(...))?;

    workflow_import::start_final_vm(...)
        .map_err(|err| cleanup(...))?;

    workflow_import::wait_for_health_check(...)
        .map_err(|err | cleanup(...))?;

    Ok(())
}

app-init
ワークフローは複数の子ワークフローを呼び、各々が HTTP アクティビティまたはスリープを実行します。
子ワークフローや基盤となるアクティビティが失敗(要求拒否・パニック・キャンセル)した場合、エラーは上位に伝播し、トップレベルのワークフローは
cleanup
を呼び出してすべてをロールバックします。


WebAPI

Obelisk サーバーは現在 5005 ポート でリッスンしています(以前は gRPC / gRPC‑Web のみ)。
v0.31.0 以降、このポートはテキストベースの HTTP も提供します。

curl 127.0.1:5005/v1/executions

サンプルレスポンス:

E_01KDJH6F811F2E0Q7AC4PDR9WE `Finished(ok)` obelisk-flyio:workflow/workflow@1.0.0-beta.app-init `23 hours ago`
E_01KDG3JFCGDEM4E6MKD3M8QCS8 `Finished(execution completed with an error)` obelisk-flyio:workflow/workflow@1.0.0-beta.app-init `yesterday`
...

JSON 形式の出力もサポートしています。

curl 127.0.1:5005/v1/executions -H 'accept: application/json'
[
  {
    "execution_id": "E_01KDJH6F811F2E0Q7AC4PDR9WE",
    "ffqn": "obelisk-flyio:workflow/workflow@1.0.0-beta.app-init",
    "pending_state": {
      "status": "Finished",
      "version": 16,
      "finished_at": "2025-12-28T13:09:50.226429459Z",
      "result_kind": "ok",
      "component_id_input_digest": "sha256:b2ee4bdf32367e5d4eaf3643b95b9d7261996a5fe03582bff58cc59a884dc29b"
    },
    "created_at": "2025-12-28T13:08:38.274234577Z",
    "first_scheduled_at": "2025-12-28T13:08:38.274234577Z",
    "component_digest": "sha256:b2ee4bdf32367e5d4eaf3643b95b9d7261996a5fe03582bff58cc59a884dc29b"
  },
  ...
]

PostgreSQL

Obelisk は当初から SQLite をサポートしており、ローカル開発や数秒のダウンタイムで再デプロイが許容される環境に最適です。
バックアップとリストアは Litestream により処理され、S3 互換エンドポイントを共有することで数百台の VM 上に展開できます。

PostgreSQL サポート は SQLite の制限を解消します:

  • 非同期レプリケーションを扱い、VM がクラッシュした際に最後の数秒のコミット済みトランザクションが失われることを防止
  • マルチノード展開を可能にし、WASM コンポーネントを VM 間で分散させて負荷に応じて動的スケール
  • 単一障害点を排除し、高可用性を実現

obelisk.toml
で PostgreSQL を設定します。


まとめ

  • 協調キャンセル:ワークフローとアクティビティ(gRPC または WebAPI 経由)
  • WebAPI:テキスト・JSON 応答をポート 5005 で提供
  • PostgreSQL:マルチノード・高可用性展開と動的スケーリングを実現

これらの機能により、Obelisk はより堅牢かつ拡張性があり、開発者フレンドリーになりました。

同じ日のほかのニュース

一覧に戻る →

2025/12/30 6:46

USPS(米国郵便公社)が切手印日付システムの変更を発表しました。

## Japanese Translation: > **概要:** > USPSは最終規則(FR Doc. 2025‑20740)を発行し、国内郵便マニュアルに「セクション 608.11 —『切手印と郵便保有』」を追加しました。この規則では、切手印の定義が正式に示され、該当する印記がリストアップされています。切手印は印付け日でUSPSがその物件を保有していることを確認しますが、必ずしもアイテムの最初の受理日と同一ではありません。USPSは通常業務で全ての郵便に切手印を貼らないため、切手印が欠落していても、その物件が未処理だったとは限りません。機械による自動切手印は、施設内で最初に行われた自動処理操作の日付(「date of the first automated processing operation」)を表示し、投函日ではなく、地域輸送最適化(RTO)や路線ベースのサービス基準により受理日より遅くなることがあります。切手印は小売ユニットからの輸送後やカレンダー日がまたがる場合に付けられることが多いため、郵送日を示す信頼できる指標ではありません。同一日の切手印を確保するには、小売窓口で手動(ローカル)切手印を依頼できます。小売窓口で料金を支払うと「Postage Validation Imprint(PVI)」が付与され、受理日が記録されます。また、郵便証明書、登録メール、または認定メールは提示日を裏付ける領収書として機能します。この規則の影響は税務申告において重要です。IRC §7502 は、文書が期限までに物理的に届けられなかった場合に、提出の適時性を判断する際に切手印の日付を使用しています。

2025/12/30 1:07

**Zig における静的割り当て** Zig のコンパイル時メモリ管理を使えば、実行時ではなくコンパイル時にストレージを確保できます。データ構造のサイズが事前に分かっている場合やヒープ割り当てを避けたいときに便利です。 ### 重要概念 - **コンパイル時定数** `const` や `comptime` の値を使い、コンパイラがコンパイル中に評価できるサイズを記述します。 - **固定長配列** リテラルサイズで配列を宣言します。 ```zig const buf = [_]u8{0} ** 128; // 128 バイト、すべてゼロ初期化 ``` - **静的フィールドを持つ構造体** 固定長配列やその他コンパイル時に決まる型を含む構造体を定義します。 ### 例 ```zig const std = @import("std"); // 静的サイズのバッファを持つ構造体 pub const Message = struct { id: u32, payload: [256]u8, // 256 バイト、コンパイル時に確保 }; // 静的割り当てを使う関数 fn process(msg: *Message) void { // ヒープ割り当ては不要;msg はスタック上またはグローバルに存在 std.debug.print("ID: {d}\n", .{msg.id}); } pub fn main() !void { var msg = Message{ .id = 42, .payload = [_]u8{0} ** 256, // すべてのバイトをゼロで初期化 }; process(&msg); } ``` ### 利点 - **決定的なメモリ使用量** – サイズはコンパイル時に分かる - **実行時割り当てオーバーヘッドがゼロ** – ヒープアロケータ呼び出しなし - **安全性** – コンパイラが境界と寿命を検証できる ### 使うべき場面 - 固定長バッファ(例:ネットワークパケット、ファイルヘッダー) - 短時間しか存続しない小規模補助データ構造 - 性能や決定的な動作が重要な状況 --- コンパイル時定数・固定配列・構造体定義を活用することで、Zig は最小限のボイラープレートで最大の安全性を保ちつつメモリを静的に割り当てることができます。

## Japanese Translation: > **概要:** > このプロジェクトは、Zigで書かれた軽量Redis互換のキー/バリューサーバー「kv」を構築し、最小限のコマンドセットで本番環境に適した設計を目指しています。コアデザインでは起動時にすべてのメモリを確保することで、実行中にダイナミックヒープを使用せず、レイテンシスパイクやユース・アフター・フリー(use‑after‑free)バグを回避します。接続は`io_uring`で非同期に処理され、システムは3つのプール(Connection、受信バッファプール、送信バッファプール)を事前確保し、デフォルトでは約1000件までの同時接続数をサポートします。各接続は設定パラメータから派生した固定サイズの受信/送信バッファを使用します。 > コマンド解析はRedisのRESPプロトコルのサブセットに従い、Zigの`std.heap.FixedBufferAllocator`を用いてゼロコピーで解析し、各リクエスト後にアロケータをリセットします。バッファサイズは`list_length_max`と`val_size_max`に依存します。 > ストレージは未管理型の`StringHashMapUnmanaged(Value)`を使用し、初期化時に`ensureTotalCapacity`で容量を確保します。キーと値は共有`ByteArrayPool`に格納され、マップはポインタのみを保持します。削除操作では墓石(tombstone)が残り、墓石数が増えると再ハッシュが必要になる場合があります。 > 設定構造体(`Config`)は `connections_max`、`key_count`、`key_size_max`、`val_size_max`、`list_length_max` などのフィールドを公開し、派生アロケーションで接続ごとのバッファサイズを決定します。デフォルト設定(総計約748 MB、2048エントリ)では `val_size_max` または `list_length_max` を倍増すると、割り当て量が約2.8 GBに上昇する可能性があります。 > 今後の作業としては、カスタム静的コンテキストマップ実装の改善、より良いメモリ利用を実現する代替アロケータの探索、境界検査(fuzz)テストの追加による限界確認、および墓石再ハッシュ処理への対応が挙げられます。

2025/12/27 20:30

**フレームグラフ 対 ツリーマップ 対 サンバースト(2017)**

## Japanese Translation: **概要:** Flame グラフ(SVG)はディスク使用量を高レベルで明確に示します。たとえば、Linux 4.9‑rc5 では `drivers` ディレクトリが全容量の50%以上を占め、`drivers/net` サブディレクトリは約15%です。Tree マップ(macOS の GrandPerspective、Linux の Baobab)は非常に大きなファイルを素早く検出できますが、高レベルのラベルが欠けています;Baobab のツリー表示では各ディレクトリの横にミニバーグラフが表示されます。Sunburst(Baobab の極座標図)は視覚的に印象的ですが、角度で大きさを判断するため長さや面積よりも誤解しやすいです。他のツール―`ncdu` の ASCII バーと `du -hs * | sort -hr` ―はテキストベースで迅速なサマリーを提供しますが、同時に一階層のみ表示されます。 提案されたユーティリティは、これら三つの可視化(Flame グラフ(デフォルト)、Tree マップ、Sunburst)すべてを組み合わせるものです。Flame グラフは読みやすさ・印刷性・最小スペース使用量が優れているため、多数のサンプルファイルシステムでテストした後にデフォルトとして採用されます。このアプローチは、ディスク使用量を簡潔かつ印刷可能なスナップショットとして提供し、ユーザーや開発者がスペースを占有する項目をより効率的に検出できるよう支援します。アイデアは ACMQ の「The Flame Graph」記事と「A Tour through the Visualization Zoo」に引用された既存の研究に基づいています。 **反映された主なポイント:** flame グラフの高レベルビュー、Tree マップの大きなファイルを素早く検出できるがラベルが欠けている点、Sunburst の視覚的魅力とサイズ認識の問題、他ツールの制限、および提案ツールの三つのビュー(デフォルトは flame グラフ)と引用元への参照。