【Parallelクラス実装】

はじめに

Parallel クラスは、REST-API サーバー環境において外部モジュールの並列実行処理を統合する役割を担うクラスです。
REST-API のメイン処理ループに対して、SocketManager / RuntimeManager / SimpleSocket といった各モジュールのイベントループを接続し、API サーバーと並行して動作させるための仕組みを提供します。

REST-API サーバーは単体でも動作しますが、プロトコル処理や常駐処理、UDP/TCP 通信などを組み合わせる場合には Parallel クラスが必要になります。

Parallel クラスのタイプ

Parallel クラスは、SOCKET-MANAGER Framework に含まれる 3 種類のモジュールに対応しており、用途に応じて使い分けます。

● SocketManager モジュール

ビルトインのステートマシンを利用したソケット通信アプリ向けです。
REST-API サーバー環境自身もこのモジュールを利用しています。
WebSocket サーバー、Minecraft 連携、TCP/UDP を使った高度な IPC などにも利用されます。
複雑なプロトコル処理やコマンド処理を伴う場合に最適です。

● RuntimeManager モジュール

常駐型アプリケーション向けのモジュールです。
SOCKET-MANAGER Launcher の内部処理にも利用され、ステートマシンを使った周期処理やバックグラウンド処理を実装できます。

● SimpleSocket モジュール

ステートマシンを使わない軽量 TCP/UDP 通信向けです。
高速 API サーバーや軽量 IPC に最適で、トラフィック状況に応じたダウンタイム調整機能も備えています。

また、以下のように役割が分かれています。
・SOCKET-MANAGER Launcher のカスタムモニタリング機能 → UDP サーバーとして動作
・REST-API サンプルサーバー → UDP クライアントとして動作

共通インターフェース(IParallelClass)

Parallel クラスは、モジュールの種類に関わらず IParallelClass インターフェースを実装します。
REST-API のメイン処理クラスは、このインターフェースを通じて各モジュールを統合します。
interface IParallelClass
{
    public function initMain(): bool;

    public function cycleDriven(int $p_cycle_interval, int $p_alive_interval): bool;
}
                    

  • initMain … モジュール固有の初期化処理を行う
  • cycleDriven … REST-API のイベントループから周期的に呼び出され、
    SocketManager / RuntimeManager / SimpleSocket の内部イベントループを実行

Parallel クラス内で複数のモジュールを共存させることは可能ですが、増やしすぎるとサーバー負荷が増えるため注意が必要です。

SocketManager タイプの生成(スキャフォールディング)

以下のコマンドで SocketManager 用 Parallel クラスを生成できます。
php worker custom:parallel-socket-manager <カスタム名>
                    

生成ファイル:app/ParallelClass/<カスタム名>.php

生成されるクラスは以下の通りです。
<?php
/**
 * ソケットマネージャーのパラレルクラスのファイル
 * 
 * REST-APIサーバーのメイン処理クラスへ渡すためのクラスファイル
 */

namespace App\ParallelClass;

use SocketManager\Library\SocketManager;


/**
 * ソケットマネージャーのパラレルクラス
 * 
 * REST-APIサーバーのメイン処理クラスへ渡すためのクラス
 */
class <カスタム名> implements IParallelClass
{
    private SocketManager $manager;
    private ?array $conf_param = null;

    public function __construct(?array $p_conf_param, $p_context)
    {
        $this->conf_param = $p_conf_param;
        if($p_conf_param === null)
        {
            $this->conf_param['host'] = null;
        }
    }

    public function initMain(): bool
    {
        $this->manager = new SocketManager($this->conf_param['host'], 20000);

        /***********************************************************************
         * ソケットマネージャーの初期設定
         **********************************************************************/

        // 初期化クラスの設定
        // $this->manager->setInitSocketManager();

        // プロトコルUNITの設定
        // $this->manager->setProtocolUnits();

        // コマンドUNITの設定
        // $this->manager->setCommandUnits();

        /***********************************************************************
         * ソケットマネージャーの実行
         **********************************************************************/

        $ret = $this->manager->listen();
        if($ret === false)
        {
            return false;
        }

        return true;
    }

    public function cycleDriven(int $p_cycle_interval, int $p_alive_interval): bool
    {
        $ret = $this->manager->cycleDriven($p_cycle_interval, $p_alive_interval);
        if($ret === false)
        {
            $this->manager->shutdownAll();
            return false;
        }

        return true;
    }
}
                    

SocketManager インスタンスの生成、UNIT クラスの設定、listen() による待ち受けなどを行います。
初期化クラスや各 UNIT クラスの作成方法は ▶フレームワークのご紹介 の IMPLEMENT カテゴリのページを参照してください。

RuntimeManager タイプ(スキャフォールディング)

以下のコマンドで RuntimeManager 用 Parallel クラスを生成できます。
php worker custom:parallel-runtime-manager <カスタム名>
                    

生成ファイル:app/ParallelClass/<カスタム名>.php

生成されるクラスは以下の通りです。
<?php
/**
 * ランタイムマネージャーのパラレルクラスのファイル
 */

namespace App\ParallelClass;

use SocketManager\Library\RuntimeManager;

class <カスタム名> implements IParallelClass
{
    private RuntimeManager $manager;

    public function __construct(?array $p_conf_param, $p_context)
    {
    }

    public function initMain(): bool
    {
        $this->manager = new RuntimeManager();

        /***********************************************************************
         * ランタイムマネージャーの初期設定
         **********************************************************************/

        // 初期化クラスの設定
        // $this->manager->setInitRuntimeManager();

        // ランタイムUNITの設定
        // $this->manager->setRuntimeUnits();

        return true;
    }

    public function cycleDriven(int $p_cycle_interval, int $p_alive_interval): bool
    {
        $ret = $this->manager->cycleDriven($p_cycle_interval);
        if($ret === false)
        {
            return false;
        }

        return true;
    }
}
                    

RuntimeManager インスタンスの生成、初期化クラスや UNIT クラスの設定を行います。
初期化クラスや各 UNIT クラスの作成方法は ▶RuntimeManagerのご紹介 の IMPLEMENT カテゴリのページを参照してください。

SimpleSocket タイプ(スキャフォールディング)

以下のコマンドで SimpleSocket 用 Parallel クラスを生成できます。
php worker custom:parallel-simple-socket <カスタム名>
                    

生成ファイル:app/ParallelClass/<カスタム名>.php

生成されるクラスは以下の通りです。
<?php
/**
 * シンプルソケットのパラレルクラスのファイル
 */

namespace App\ParallelClass;

use SocketManager\Library\SimpleSocketGenerator;
use SocketManager\Library\SimpleSocketTypeEnum;
use SocketManager\Library\ISimpleSocketUdp;

use App\UnitParameter\ParameterForRestApi;

class <カスタム名> implements IParallelClass
{
    private ParameterForRestApi $context;
    private SimpleSocketGenerator $generator;

    public function __construct(?array $p_conf_param, $p_context)
    {
        $this->context = $p_context;
    }

    public function initMain(): bool
    {
        $this->generator = new SimpleSocketGenerator(SimpleSocketTypeEnum::UDP, null, null, 1000);
        $this->generator->setUnitParameter($this->context); // REST-APIのコンテキストクラスと連携

        $this->generator->setKeepRunning(function(?ISimpleSocketUdp $p_simple_socket, $p_context)
        {
            // イベントループで実行する処理
        }, $this->context);

        $w_ret = $this->generator->generate();
        if($w_ret === null)
        {
            return false;
        }

        return true;
    }

    public function cycleDriven(int $p_cycle_interval, int $p_alive_interval): bool
    {
        $ret = $this->generator->cycleDriven($p_cycle_interval);
        if($ret === false)
        {
            $this->generator->shutdownAll();
            return false;
        }

        return true;
    }
}
                    

SimpleSocketGenerator を利用し、TCP/UDP の種別を指定して軽量ソケット処理を実装できます。
setUnitParameter により REST-API のコンテキストと連携し、setKeepRunning に設定したクロージャがイベントループで実行されます。

SimpleSocket の詳細は ▶シンプルソケット機能 を参照してください。

Parallel クラスの利用方法

  • コンストラクタには REST-API の基本パラメータとコンテキストが渡される
  • メイン処理クラスの $classes['parallel'] にクラス名を設定すると適用される
  • プロトコル処理や常駐処理、UDP/TCP 通信などを REST-API と並行して動作させたい場合に利用
  • 単体の REST-API サーバーとして利用する場合は必須ではない

利用例

REST-API サーバー環境のサンプルサーバーでは、SimpleSocket を利用した UDP クライアントの Parallel クラスが実装されています。
詳しくは app/ParallelClass/ParallelForSimpleSocket.php のファイルを参照してください。

おわりに

Parallel クラスは、REST-API サーバーと外部モジュールを連携させるための重要な仕組みです。
SocketManager / RuntimeManager / SimpleSocket のいずれも、REST-API のイベントループと統合することで強力な並列処理環境を構築できます。

必要に応じてスキャフォールディングを活用し、プロジェクトに適した Parallel クラスを設計してください。
その他スキャフォールディングの詳細は ▶スキャフォールディング を参照してください。