はじめに
このクラスはアプリケーションのエントリポイントとして機能し、RuntimeManagerクラスをインスタンス化して実行するまでの処理が含まれています。
専用のコマンドを使ってスキャフォールディングできるので、メイン処理をコーディングする必要はなく、組み換え可能なランタイムUNIT(ビジネスロジック)部のクラスを適用して使用します。 SocketManagerクラスとは異なり、プロトコル部は不要なので、より簡易的な実装になります。
ここではコマンドを実行してメイン処理クラスを生成した後、そのクラスを使ってカスタマイズできる内容を中心にご紹介します。
メイン処理クラスを生成するコマンドは以下の通り。
> php worker runtime:main MainForTest
[success] メイン処理クラスの生成に成功しました (MainForTest)
生成されたクラスはapp/MainClass
の場所にMainForTest.php
というファイル名で格納されます。
新しいメイン処理クラスが増えるとUsageのmain
カテゴリに項目が追加されます。
> php worker
SOCKET-MANAGER Framework 1.16.0
Usage:
command [arguments]
main
app:main-for-test Command description
craft
craft:init <初期化クラス名> 初期化クラスの生成
craft:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
craft:protocol <プロトコルUNIT定義のクラス名> プロトコルUNIT定義のクラスとステータス名Enumの生成
craft:command <コマンドUNIT定義のクラス名> コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成
craft:main <メイン処理のクラス名> メイン処理クラスの生成
craft:setting <設定ファイル名> 設定ファイルの生成
craft:locale <メッセージファイル名> メッセージファイルの生成
runtime
runtime:init <初期化クラス名> 初期化クラスの生成
runtime:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
runtime:units <ランタイムUNIT定義のクラス名> ランタイムUNIT定義のクラスとキュー/ステータス名Enumの生成
runtime:main <メイン処理のクラス名> メイン処理クラスの生成
上記Usageのようにmain
カテゴリにapp:main-for-test
という名前で追加されているのが確認できます。
アプリケーション識別子
メイン処理クラスが生成されると以下のプロパティが確認できます。
/**
* @var string $identifer アプリケーション識別子
*/
protected string $identifer = 'app:main-for-test';
ここではコマンドラインフォーマットを定義しています。
app:main-for-test
の部分がアプリケーション(プロセス)名で、コマンドパラメータを含めて自由にカスタマイズできます。
例えばサービス管理ランチャーを実装する場合、start(起動)やstop(停止)などのアクション名とサービス名は以下のように定義できます。
/**
* @var string $identifer アプリケーション識別子
*/
protected string $identifer = 'app:main-for-test {action} {service?}';
service
の後ろに付いている"はてな(?)マーク"は省略可能である事を表しています。
ちなみに"はてな(?)マーク"は最後尾の連続したパラメータにしか指定できません。
例えば{action?} {service?}
と書く事はできますが{action?} {service}
と書く事はできません。
なお、メイン処理クラス内では$this->getParameter('action')
のように書く事でパラメータを取得できます。
省略可能なパラメータが省略されている時はnullが返却されます。
コマンド説明文
メイン処理クラスが生成されると以下のプロパティが確認できます。
/**
* @var string $description コマンド説明
*/
protected string $description = 'Command description';
ここではUsageを表示した時のサーバーコマンドの説明文を定義しています。
初期状態ではCommand description
となっているので、これをプロパティで変更できます。
例えば以下のように変更すると
/**
* @var string $description コマンド説明
*/
protected string $description = 'テスト用のアプリ';
Usageでは以下のように表示されます。
> php worker
SOCKET-MANAGER Framework 1.16.0
Usage:
command [arguments]
main
app:main-for-test テスト用のアプリ
craft
craft:init <初期化クラス名> 初期化クラスの生成
craft:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
craft:protocol <プロトコルUNIT定義のクラス名> プロトコルUNIT定義のクラスとステータス名Enumの生成
craft:command <コマンドUNIT定義のクラス名> コマンドUNIT定義のクラスとキュー/ステータス名Enumの生成
craft:main <メイン処理のクラス名> メイン処理クラスの生成
craft:setting <設定ファイル名> 設定ファイルの生成
craft:locale <メッセージファイル名> メッセージファイルの生成
runtime
runtime:init <初期化クラス名> 初期化クラスの生成
runtime:parameter <UNITパラメータクラス名> UNITパラメータクラスの生成
runtime:units <ランタイムUNIT定義のクラス名> ランタイムUNIT定義のクラスとキュー/ステータス名Enumの生成
runtime:main <メイン処理のクラス名> メイン処理クラスの生成
設定可能項目
このメイン処理クラスであらかじめ設定可能な項目は、RuntimeManager
クラスの引数とそのクラス内のcycleDriven
メソッドの引数です。
各引数の設定方法には以下の3種類があります。
- ①メイン処理クラス内で直接指定
- この項目でご紹介する方法です。
- ②コマンドラインから取得
- 上記の>> アプリケーション識別子の項目でご紹介した方法です。
- ③設定ファイル
- >> 設定ファイルの管理のページでご紹介している方法です。
RuntimeManagerクラスの引数
RuntimeManagerクラスの引数は以下の一つのみです。
1)キュー名(デフォルト:RuntimeQueueEnum::STARTUP->value)
この引数には最初に実行されるキュー名を指定できます。
cycleDrivenメソッドの引数
メイン処理クラスの実行(exec)メソッド末尾のソースにはノンブロッキングループ内でcycleDriven
メソッドが呼ばれている箇所があります。
public function exec()
{
・
・
・
// ノンブロッキングループ
while(true)
{
// 周期ドリブン
$ret = $manager->cycleDriven();
if($ret === false)
{
goto finish;
}
}
・
・
・
}
このcycleDriven
メソッドの引数は以下の一つのみです。
1)周期インターバルタイム(デフォルト:2000μs)
この引数をデフォルト値で指定すると以下のようになります。
$manager->cycleDriven( 2000 );
$manager->cycleDriven();
御覧の通り、直接値を指定する事もできますが、引数を省略しても自動的にデフォルト値が適用される仕組みになっています。
クラス適用項目
メイン処理クラスの実行(exec)メソッドの中ほどに以下のコメント部分があります。
public function exec()
{
・
・
・
/**
* 初期化クラスの設定
*
* $manager_runtime->setInitRuntimeManager()メソッドで初期化クラスを設定します
*/
/**
* ランタイムUNITの設定
*
* $manager_runtime->setRuntimeUnits()メソッドでランタイムUNITクラスを設定します
*/
・
・
・
}
あらかじめ作成しておいた初期化クラス/ランタイムUNITクラスのインスタンスは、ここで以下のように引き渡してフレームワークライブラリへ適用します。
public function exec()
{
・
・
・
/**
* 初期化クラスの設定
*/
$manager->setInitRuntimeManager(new InitForTest());
/**
* ランタイムUNITの設定
*/
$manager->setRuntimeUnits(new ProtocolForTest());
・
・
・
}
あらかじめ複数のランタイムUNITクラスを用意している場合は、この部分を組み替える事によってビジネスロジックを変更する事が可能になります。
おわりに
これまで見てきたように、メイン処理クラスではコマンドライン/設定項目/ランタイムUNITの組み合わせを自由にデザインすることができます。
また、サーバー間通信のような通信処理が必要な場合は、SocketManagerクラスの以下のページでご紹介していたような構成にする事で、統一されたインターフェースで実装する事が可能です。