OxPHP\Shared\* の命名規約

OxPHP\Shared\* 名前空間はアプリケーションレベルの並行処理 API です。 Atomic、Counter、Flag、Map、Channel、Mutex、Once、Pool が含まれます。 メソッド名は単一のルールセットに従っているため、型ごとにドキュメントを 確認しなくても API を予測できます。

このドキュメントが正規のリファレンスです。新しいプリミティブや、既存の プリミティブへの変更は、必ずこれに従わなければなりません。

ルール

1. 値を読む — get()

PHP の慣例です。Map::get()、Counter::get()、Once::get() で使われます。

Atomic::load(Ordering $order = Ordering::SeqCst) は意図的な例外です。ordering 引数を 伴って存在すること自体が、この読み取りが単なるゲッターとは異なるメモリモデル 契約の一部であることを示しています。

2. 値を書く — set()、atomic には store()

Map::set()、Mutex の値の更新(withLock の内部で参照渡しによって)、Once::getOrInit()。 Atomic::store(int $value, Ordering $order = Ordering::SeqCst) は同じ理由から load と対になっています。

3. 要素の数 — count(): int

現在のサイズを公開するすべてのコンテナは、count(): int という名前で それを行います。Channel はさらに \Countable を実装しているため、 キューに入った項目については count($ch) がネイティブなイディオムとして 機能します。Map は count(): int をメソッドとして公開しますが \Countable は実装していません。直接呼び出してください。Pool には count() がありません。生存しているスロット数は stats()->size() から 読み取ってください。

php
$ch = new OxPHP\Shared\Channel(1024); $map = new OxPHP\Shared\Map(); $pool = new OxPHP\Shared\Pool($factory); count($ch); // queued items (Channel implements \Countable) $map->count(); // entries $pool->stats()->size(); // total live slots (in-use + idle)

size()、len()、pending() はありません。実装者の指が覚えている言語が 何であれ、これらは公開サーフェスでは禁止されています。

4. 真偽値ゲッター — is*() プレフィックス

Channel::isClosed()。

裸の動詞(test、check)やドメイン固有の名前(closed)は使いません。 is プレフィックスは、真偽値プロパティの純粋な読み取りであることを示します。

状態が単一の真偽値よりも豊かな型は、それを is*() ゲッターではなく、 enum を返す status() メソッドとして公開します。Channel の RecvResult::status() と Once::status(): Once\Status (Uninitialized/Pending/Ready/Poisoned)がこれに従っています。答えが 2 つより多くのケースを持つ場合は status() を使ってください。

Mutex は isCorrupted() を公開しません。破損は解消不能で残り続け、 次の acquire の際に CorruptedMutexException として表面化します。 再取得して catch する以外に、そのプローブでできる有用なことはありません。

5. 待機ポリシーの三分法 — try* / 裸 / *Timeout

ブロッキングプリミティブ(Channel、Mutex)は、オーバーロードされた ?float $timeout 引数ではなく、メソッド名を通じて待機ポリシーを 表現します。

サフィックス 挙動 例
try* 非ブロッキング。失敗バリアントを即座に報告します。 Channel::trySend、Channel::tryRecv、Mutex::tryWithLock
(裸の名前) 永久にブロック(またはリクエストファイバーがキャンセルされるまで)。 Channel::send、Channel::recv、Mutex::withLock
*Timeout 有界待機。必須の int $ms > 0 を取ります。 Channel::sendTimeout、Channel::recvTimeout、Mutex::withLockTimeout

この三分法は、3 つのあいまいなポリシー(null = 永久、0 = try、正の値 = 有界)を 1 つのパラメータから取り出し、自己文書化された名前を持つ 3 つの メソッドに分けます。

Note

*Timeout メソッドの $ms 引数は厳密に正です。ゼロ、負数、非整数、 欠落した値はブリッジで OxPHP\Shared\TypeException を送出します。

条件付き成功の操作は、try* ではなく setIfAbsent という綴りで Map 上に 存在します。Map::setIfAbsent はキーが存在しなかった場合にのみコミットし (HashMap::try_insert と対応)、既存の値を返します。挿入が行われた場合は null を返します。setIfAbsent という名前は その単一のセマンティクスのために予約されています。他の場所で再利用しないで ください。

try* メソッドが失敗をどう報告するかは型によって異なります。Channel は 値型の Result を返し、Mutex は ContentionException を送出し、 Pool::tryAcquire() はプールが飽和しているときに null を返し、 Once::trySet() はセルがすでに Ready または Pending のときに false を 返します。

6. Compare-and-swap — compareAndSet()

Atomic::compareAndSet()、Flag::compareAndSet()。常に bool を返します (スワップが起きたか、起きなかったか)。

7. 置換して前の値を返す — swap()

int には Atomic::swap()、bool には Flag::swap()。前の値を返します。

8. 前の値を返す atomic RMW — fetch*() プレフィックス

Atomic::fetchAdd()、fetchSub()、fetchAnd()、fetchOr()、 fetchXor()。

fetch プレフィックスは戻り値の契約をエンコードします。すなわち操作前の 値です。これは、新しい値を返す Counter::add()(LongAdder 形式の 集約カウンター)とは対照的です。

新しい RMW メソッドを追加する際は、まず契約を選び、それから名前を決めます。

  • 前の値を返す → fetchVerb(args)
  • 新しい値を返す → 裸の verb(args)

これらを混在させないでください。

9. デフォルトへリセット — clear()

Map::clear() — コンテナを空にします。削除されたエントリの数を返します。

Counter には clear() はありません。set(0) がそのウィンドウ付きリセット です。Counter::set() は void ではなく前の値を返す、文書化された例外 です。これはアトミックな交換であり、set(0) が直前の合計を読み取ることは LongAdder の sumThenReset イディオムです。(Atomic は同じ操作を swap() と綴りますが、Counter は set を維持します。set($n) はシード設定と ウィンドウ処理において自然に読めるためです。)

10. レジストリ ID — id(): int

すべての Shared\* インスタンスは、ログおよび /__ox_shared/entry?id=<id> 可観測性エンドポイントのために id(): int を公開します。

チートシート

概念 正規の名前 例
値を読む get() Map::get、Counter::get
atomic を読む load($order) Atomic::load
値を書く set() Map::set
atomic を書く store($v, $order) Atomic::store
要素の数 count(): int Map::count、Channel::count
真偽値プロパティ is*(): bool Channel::isClosed
条件付き挿入 setIfAbsent($k, $v) Map::setIfAbsent
非ブロッキング待機 try*() Channel::trySend、Mutex::tryWithLock
永久待機 裸の動詞 Channel::send、Channel::recv、Mutex::withLock
有界待機 *Timeout(int $ms) Channel::sendTimeout、Mutex::withLockTimeout
Compare-and-swap compareAndSet() Atomic::compareAndSet
スワップして前の値を返す swap() Atomic::swap、Flag::swap
atomic RMW、前の値を返す fetch*() Atomic::fetchAdd
atomic RMW、新しい値を返す 裸の動詞 Counter::add
デフォルトへリセット clear() Map::clear
レジストリ ID id(): int すべての Shared\* 型

新しい Shared\* 型の追加

新しいプリミティブを提案する際は、マージ前にこのチェックリストを埋めて ください。

  • すべてのメソッドがチートシートの行にマッピングされる、または例外を 説明する ADR がある(上記の Atomic::load/store と Counter::set を 参照)。
  • 型が値のコレクションを保持する場合、\Countable を実装し count(): int を公開する。
  • 読み取りメソッドは get または load(atomic のみ)である。
  • 真偽値ゲッターは is* プレフィックスを使う。
  • 待機ポリシーのバリアントは try* / 裸 / *Timeout(int $ms) の 三分法に従う。*Timeout バリアントは int $ms > 0 を取り、ゼロ / 負数 / 非整数の入力を TypeException で拒否する。待機ポリシーの try* メソッドは値型の Result を返すか、ドメイン例外を送出するかのいずれかで あり、null でのエンコードは決して行わない。 プールが飽和しているときに null を返す Pool::tryAcquire() は、これに 従っていない。 条件付き成功の操作は try* ではなく専用の setIfAbsent 命名に従う。
  • len、size、pending、test、その他の場当たり的な名前は使わない。
  • ドメイン固有の動詞(evict、drain、flush など)は、チートシートの 正規エントリがその概念をカバーしていない場合にのみ登場する。

可観測性の名前

オペレーター向けのサーフェス(Prometheus メトリクス名と /__ox_shared/entry?id=<id> の JSON)は、PHP API とは別の契約です。 これをリネームするとダッシュボードとアラートルールが壊れるためです。 Channel または Pool の要素数は、/metrics では oxphp_shared_channel_count または oxphp_shared_pool_count、type_specific の JSON では count です。 Channel の場合は Channel::count() が返す数であり、Pool の場合は生存している スロット数、つまり Pool::stats()->size() が返す数です。

0.13.0 で削除

以前の綴り(oxphp_shared_channel_pending、oxphp_shared_pool_size、 および JSON キーの pending と size)は、もう出力されません。これらを 参照したままのダッシュボードやアラートルールはシリーズを見つけられないため、 それらに対するしきい値アラートは決して発火しません。

安定性

これらのルールは OxPHP\Shared\* 1.0 契約の一部です。1.0 リリース後は、 リネームは破壊的変更であり、非推奨サイクルを必要とします。1.0 より前でも、 これらのルールは依然として拘束力を持ちます。これらに違反する新しいメソッドは レビューで却下されます。