English

プラグイン開発ガイド(compression / Python)

1. はじめに

SINETStream では設定ファイルあるいはコンストラクタのパラメータで指定するcompression.algorithmの値に応じて、 メッセージの圧縮/展開を行います。

SINETStream v1.7 以降では以下の compression.algorithm をサポートしています。

gzip, zstdはSINETStream本体に組み込みの compression.algorithm です。

新たなプラグインを実装することで、上記に示したcompression.algorithm以外の圧縮アルゴリズムで SINETStreamのメッセージを圧縮/展開できるようになります。

1.1 対象者

このドキュメントが対象としている読者を以下に示します。

1.2 前提知識

このドキュメントの説明は、以下の知識を有している読者を前提としています。

2. プラグインの実装方法

2.1 概要

SINETStreamのプラグインを作成するためには以下の作業が必要となります。

それぞれの作業項目の詳細について以下に記します。

2.2 プラグインに定められているプロパティを実装したクラスの作成

compressionのプラグインでは圧縮アルゴリズム応じた圧縮/展開関数をプロパティとして提供する必要があります。 具体的には以下のプロパティの定義が必要となります。

プラグインが上記のプロパティを実装することを確認するために、 抽象基底クラス sinetstream.spi.PluginCompressionを利用することができます。 PluginCompressionでは上記のプロパティが抽象プロパティとして定義されています。

2.3 パッケージメタデータの作成

setuptoolsのエントリポイントにクラスを登録することで、SINETStreamがプラグインを見つけることができるようになります。 これは登録されたエントリポイントをsetuptoolsが検出する機能を利用して実現しています。 setuptoolsはPythonの配布パッケージのビルドなどを行うためのツールです。

登録されているエントリポイントからSINETStreamで必要となるクラスを探し出すことができるようにするためには、 エントリポイントのグループと名前を適切に設定する必要があります。 compressionプラグインではsinetstream.compressionをグループに指定します。 また名前には compressionとして追加する圧縮アルゴリズム名を指定します。

例えばcompressionlz4を追加するプラグインの場合setup.cfg に以下の記述を行います。

[options.entry_points]
sinetstream.compression =
    lz4 = sinetstreamplugin.compression.lz4:LZ4Compression

エントリポイントの詳細については setuptools documentation - Entry Points を参照してください。

3. プラグインの実装例

プラグイン実装の具体的な手順を示すために実装例を示します。

ここではSINETStreamのメッセージをLZ4で圧縮・展開するためのcompressionプラグインを実装します。

3.1 ファイル構成

以下のファイルを作成します。

3.2 プラグイン実装

プラグインの実装を行うモジュールファイルlz4.pyについて説明します。

まずクラス定義を行います。

class LZ4Compression(PluginCompression):
    def __init__(self, level=None, params={}):
        self._level = level
        self._params = params

ここでは抽象基底クラスPluginCompressionを継承したクラスを定義します。 プラグインクラスの実装においてPluginValueTypeを継承することは必須ではありません。 しかし開発環境によっては抽象基底クラスを継承することにより、 プラグイン実装に必要となるメソッドに関する情報などの支援を受けられる場合があります。

次に圧縮・展開処理を実装するメソッドを定義します。 い

    def compress(self, data, params):
        return lz4.frame.compress(data, **params)

    def decompress(self, data):
        return lz4.frame.decompress(data)

次にプラグインで実装する必要のあるプロパティを定義します。

    @property
    def compressor(self):
        params = copy.deepcopy(self._params)
        if self._level is not None and "compression_level" not in params:
            params["compression_level"] = self._level
        return lambda data: self.compress(data, params)

    @property
    def decompressor(self):
        return lambda data: self.decompress(data)

先ほど定義した圧縮処理compress、展開処理decompressを返すプロパティを定義しています。 圧縮処理では圧縮レベルを指定するためにlambdaをつかっています。

3.3 パッケージング

3.3.1 setup.py, setup.cfgの作成

パッケージングを行う際のコマンドラインインタフェースとなる setup.py とその設定ファイル setup.cfg を作成します。

まず setup.py を作成します。設定については全てsetup.cfgで行うので setup.pyは必要最小限なものとします。

from setuptools import setup
setup()

次に setup.cfg を作成します。

[metadata]
name = sinetstream-comp-lz4
version = 1.7.0

[options]
package_dir=
    =src
packages = find_namespace:
zip_safe = False
namespace_packages =
  sinetstreamplugin
install_requires =
  sinetstream>=1.7.0
  lz4
python_requires = >= 3.7

[options.packages.find]
where = src

[options.entry_points]
sinetstream.compression =
    lz4 = sinetstreamplugin.compression.lz4:LZ4Compression

プラグインに直接関わる設定は options.entry_pointsセクションです。 sinetstream.compressioncompressionプラグインに対応するグループになります。 グループに対して (value_typeのタイプ名)=(パッケージ名:クラス名) を指定しています。

3.3.2 パッケージの作成

wheelパッケージを作成します。

$ python setup.py bdist_wheel
running bdist_wheel
running build
running build_py
(中略)
$ ls dist/
dist/sinetstream_comp_lz4-1.7.0-py3-none-any.whl

3.4 利用例

作成したプラグインを利用してデータ圧縮する例を以下に示します。

with MessageWriter(service='service-1', data_compression=True, compression={'algorithm': 'lz4'}) as writer:
    writer.publish('test')

MessageWriterのコンストラクタのパラメータcompression.algorithmの値に 新たに作成したcompressionプラグインの圧縮アルゴリズム名lz4を指定しています。

3.5 ソースコード

ここまで記した実装例のファイルへのリンクを以下に示します。