OxPHP\Shared\* の命名規約

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

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

ルール

1. 値を読む — get()

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

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

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

Map::set()Mutex の値リセット(with 経由)、Once::getOrInit()Atomic::store($value, ?Ordering) は同じ理由から load と対になっています。

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

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

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->count(); // total live slots (in-use + idle)

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

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

Channel::isClosed()

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

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

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

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

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

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

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

Note

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

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

try* を統一する不変条件は次のとおりです。値型の Result を返す(Channel)か、 ContentionException を送出する(Mutex)かのいずれかです。「成功しなかった」 ことをエンコードするために null を返すことは決してありません。それが古い API であり、この三分法が排除した null 合体のあいまいさを生み出していました。

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() — コンテナを空にします。void を返します。

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::getCounter::get
atomic を読む load($order) Atomic::load
値を書く set() Map::set
atomic を書く store($v, $order) Atomic::store
要素の数 count(): int Map::countChannel::countPool::count
真偽値プロパティ is*(): bool Channel::isClosed
条件付き挿入 setIfAbsent($k, $v) Map::setIfAbsent
非ブロッキング待機 try*() Channel::trySendMutex::tryWithLock
永久待機 裸の動詞 Channel::sendChannel::recvMutex::withLock
有界待機 *Timeout(int $ms) Channel::sendTimeoutMutex::withLockTimeout
Compare-and-swap compareAndSet() Atomic::compareAndSet
スワップして前の値を返す swap() Atomic::swapFlag::swap
atomic RMW、前の値を返す fetch*() Atomic::fetchAdd
atomic RMW、新しい値を返す 裸の動詞 Counter::add
デフォルトへリセット clear() Map::clear
レジストリ ID id(): int すべての Shared\*

新しい Shared\* 型の追加

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

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

可観測性の名前は PHP API より遅れる

オペレーター向けのサーフェス(Prometheus メトリクス名と /__ox_shared/entry?id=<id> の JSON)は、PHP API とは別の契約です。 これをリネームするとダッシュボードとアラートルールが壊れます。暗黙の 不整合を避けるため、影響を受ける名前は 1 リリースサイクルの間二重に 出力されます。

サーフェス 非推奨(まだ出力される) 正規
Prometheus oxphp_shared_channel_pending oxphp_shared_channel_count
Prometheus oxphp_shared_pool_size oxphp_shared_pool_count
JSON エントリ Channel.pending Channel.count
JSON エントリ Pool.size Pool.count

非推奨メトリクスの # HELP 行には (deprecated, removed in a future release; use *_count) というプレフィックスが付き、ox_shared プラグインは introspection またはメトリクスが有効なときに起動時 WARN を出力します。

Migration

非推奨サイクルが終了する前に、ダッシュボードとアラートルールを _count 名へ移行してください。削除後は正規の名前だけが出力され、古い名前を参照する Prometheus/Grafana のパネルは空のシリーズを返し始めます。

安定性

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