简体中文 English 繁體中文 日本語 Русский
本文为静态镜像,内容以交互版为准 在交互式文档中心打开 →

ラグジュアリー ロード モジュール システム

ErisPulse SDK は、モジュールを実際に必要になるまで初期化しない強力なラグジュアリー ロード モジュール システムを提供し、アプリケーションの起動速度とメモリ効率を大幅に向上させます。

概要

ErisPulse のコア機能の 1 つである遅延ロードモジュールシステムは、以下の方法で動作します。

動作原理

LazyModule クラス

ラグジュアリー・ロード・システムの中心となるのが LazyModule クラスです。これは、最初にアクセスされたときにのみモジュールを実際に初期化するラッパーです。

初期化プロセス

モジュールが初めてアクセスされたとき、LazyModule は以下の操作を実行します:

  1. モジュールクラスの __init__ パラメータ情報を取得します
  2. パラメータに基づいて sdk リファレンスを渡すかどうかを決定します
  3. モジュールの moduleInfo 属性を設定します
  4. BaseModule を継承したモジュールの場合、on_load メソッドを呼び出します
  5. module.init ライフサイクルイベントをトリガーします

イベント駆動の遅延起動(activate_on)

Note


この機能は ErisPulse 2.8.0以降が必要です。

lazy_load=True のモジュールは、最初の属性アクセス時にデフォルトでロードされます。
モジュールがコマンド/イベントハンドラを登録している場合、従来の方法では lazy_load=False にして即時ロードするしかありませんでした。activate_on は、トリガーを宣言し、最初の一致するイベント/コマンドが到着したときにモジュールを自動的に起動するという第三の選択肢を提供します。これにより、メモリに常駐することなく、トリガーエントリを失うこともありません。

from ErisPulse.loaders import ModuleLoadStrategy

class MyModule(BaseModule):
    @staticmethod
    def get_load_strategy():
        return ModuleLoadStrategy(
            lazy_load=True,
            activate_on=[
                # ---- イベントトリガー(受動的到達、ユーザーの意識を必要としない)----
                "message",                                    # タイプレベル:任意のメッセージイベント
                {"notice": "group_member_increase"},          # タイプ + 単一 detail_type
                {"message": ["private", "group"]},            # タイプ + 複数 detail_type

                # ---- コマンドトリガー(能動的入力、Help に表示されるプレースホルダーコマンド)----
                {"command": "roll"},                          # 略記:コマンド名
                {"command": ["roll", "dice"]},                # コマンド名リスト
                {"command": {                                 # dict 形式で宣言(name は必須)
                    "name": "dice",
                    "help": "サイコロを振る",
                    "usage": "/dice",
                    "group": "娯楽",
                    "aliases": ["d"],
                    "hidden": False,
                }},
            ],
        )

コマンド dict 形式の宣言パラメータ

dict 形式は @command() デコレータのユーザーレベルのパラメータを反映し、モジュールのロード前にプレースホルダーコマンドを登録するために使用されます:

パラメータ 型 デフォルト 説明
name str 必須 コマンド名;on_load での @command(name) と一致する必要がある。一致しないと、起動後にプレースホルダーが削除され、コマンドが存在しなくなる。
help str 回帰チェーン Help に表示される説明;宣言していない場合は回帰チェーンから値を取得(以下参照)
usage str 自動生成 用法行、デフォルトは {prefix}{name}
group str None コマンドグループ
aliases list[str] [] 別名として同時に登録。別名の入力でもトリガーとして機能する
hidden bool False True の場合、プレースホルダーコマンドも非表示(起動後の実際のコマンドの非表示の意味と一致);コマンド名を知っているユーザーの入力でもトリガーとして機能する

サポートしていない priority / permission / master:プレースホルダーコマンドの使命はトリガーの起動のみであり、権限チェックは起動後の実際のコマンドが実行する(プレースホルダー段階で権限をブロックすると、「コマンド入力で起動」が無効になる)。

プレースホルダーコマンドの help 回帰チェーン

モジュールがロードされていない状態で Help に表示されるコマンドの説明は、以下の順序で値を取得します(最初に取得した値が使用されます):

  1. dict 形式で宣言されたコマンドレベルの help(最も正確)
  2. モジュールの get_meta() の description
  3. モジュールの __description__ 属性
  4. パッケージのメタデータの Summary(PyPI パッケージの概要)
  5. 一般的なメッセージ:「このコマンドは遅延ロードモジュール X から来ています。初めて使用すると、モジュールが自動的にロードされます」

トリガーの意味

アーキテクチャ図と完全な意味については、アーキテクチャ概要を参照してください。

懒惰ロードの設定

グローバル設定

設定ファイルでグローバルな遅延ロードを有効または無効にします:

[ErisPulse.framework]
enable_lazy_loading = true  # true=遅延ロードを有効にする(デフォルト), false=遅延ロードを無効にする

モジュールレベルの制御

モジュールは get_load_strategy() 静的メソッドを実装することで、ロード戦略を制御できます:

from ErisPulse.Core.Bases import BaseModule
from ErisPulse.loaders import ModuleLoadStrategy

class MyModule(BaseModule):
    @staticmethod
    def get_load_strategy():
        """モジュールのロード戦略を返す"""
        return ModuleLoadStrategy(
            lazy_load=False,  # Falseを返すと即時ロード
            priority=100      # ロードの優先度、数値が大きいほど優先度が高い
        )

ラグロードモジュールの使用

基本的な使い方

開発者にとって、ラグロードモジュールは通常のモジュールと使用方法にほとんど違いはありません:

# SDKを介してラグロードモジュールにアクセス
from ErisPulse import sdk

# 以下のようにアクセスするとモジュールのラグロードがトリガーされます
result = await sdk.my_module.my_method()

モジュールの取得の統一されたエントリーポイント

SDK属性、モジュールマネージャー属性を通じてアクセスする場合でも、module.get()で検索する場合でも、 「登録済みだがまだロードされていない」ラグロードモジュールに対しては、すべて同じラグロードプロキシが返り、 そのプロパティにアクセスすることで初めてモジュールの初期化がトリガーされます:

# 3つの方法で取得できるのはすべてラグロードプロキシです(モジュールがロードされていない場合)、動作は一貫しており、ユーザーには透明です
sdk.my_module          # ロードをトリガーするエントリーポイント
sdk.module.my_module   # 同様にラグロードプロキシを返します
sdk.module.get("my_module")  # これもラグロードプロキシを返します。この操作自体はロードをトリガーしません

# プロキシの任意の属性にアクセスすることで、モジュールの初期化が実際に行われます
result = await sdk.my_module.my_method()

module.get()は検索用のインターフェースであり、ロードをトリガーしません:

明示的にロードをトリガーするには、await sdk.load_module("my_module")を使用してください。

非同期初期化

非同期初期化が必要なモジュールについては、まず明示的にロードすることを推奨します:

# まずモジュールを明示的にロード
await sdk.load_module("my_module")

# その後モジュールを使用
result = await sdk.my_module.my_method()

同期初期化

非同期初期化を必要としないモジュールについては、直接アクセスできます:

# 直接アクセスすると自動的に同期初期化されます
result = sdk.my_module.some_sync_method()

最佳実践

ロード戦略を選択する際は、以下の決定フローを参考にしてください。

flowchart TD
    A["モジュール宣言<br/>get_load_strategy()"] --> B{"起動時に即座に準備が必要か<br/>または高頻度でトリガーされるか?"}
    B -->|"はい"| C["lazy_load=False<br/>即時ロード"]
    B -->|"いいえ"| D{"コマンド / イベントハンドラを登録しているか?"}
    D -->|"はい"| E["lazy_load=True + activate_on<br/>イベント/コマンドが到着した際にアクティベート"]
    D -->|"いいえ"| F["lazy_load=True<br/>最初の属性アクセス時にロード"]
    C --> G["起動時に on_load() を呼び出す"]
    E --> H["stub を登録 → トリガー時にインスタンス化"]
    F --> I["LazyModule 代理"]

懒惰ロード(lazy_load=True)を使用することを推奨する場面

懒惰ロードを禁止することを推奨する場面(lazy_load=False)

priority パラメータは、即時ロードされるモジュール間の初期化順序を制御します。数値が大きいほど先に初期化されます。同じ優先度のモジュールは登録順にロードされます。

注意事項

  1. モジュールが遅延ロードを使用している場合、ErisPulse内で他のモジュールによって一度も呼び出されない場合、そのモジュールは決して初期化されません。
  2. モジュール内にEventの監視など、他のモジュールを積極的に監視するモジュールが含まれている場合、2つの選択肢があります:activate_on トリガーを宣言して遅延ロードを維持し、イベントが到達したときに自動的にアクティブ化するか、または即時ロードを必要とすることを宣言する(lazy_load=False)か、さもなければモジュールの正常な業務に影響を及ぼす可能性があります。
  3. 特殊な要望がない限り、遅延ロードを無効にすることは推奨しません。そうしないと、依存管理やライフサイクルイベントなどの問題が生じる可能性があります。
  4. activate_on のコマンド dict 声明において、name はモジュールの on_load で @command() によって登録された実際のコマンド名と一致する必要があります。一致しない場合、モジュールがアクティブ化された後にプレースホルダーコマンドが解除され、宣言と実装が一致しないコマンドは存在しません。

関連ドキュメント