nginx拡張モジュールをアップデートしました

先日作成しましたnginxの拡張モジュールを更新しました。
(前回の更新はこちらになります)

前回の拡張ではunixのshared memory segment上にデータを展開するようにしました。
これによって各プロセス間でユーザからのアクセス情報を共有できるといったものでした。

今回の対応では更にネットワーク上で構成された複数のnginxサーバでもデータを共有することを目的として、ネットワーク上のストレージ(今回の対応では実装としてはmemcachedを対象)に対応するようにしました。

一見ストレージとして memcached に格納できる様になっただけですが、内部的なコードはまた別の側面が改良されました。
当初は特定のストレージ、具体的にはプロセスのheap領域や前回対応したosの共有メモリセグメントにデータを置くという想定でしたが、ngxinのconfigurationファイルでストレージを指定できる方式にし、コードをほぼすべて書きなおしてあります。

これによって今現在指定できるストレージであるshmemとmemcachedに関してはソースコードが完全に分離できる形でインターフェースを切り分けています。
nginxが起動した時点でこのモジュールはconfigurationファイルを読み取り、指定されたストレージに基づいた初期化を行います。

実装としてはこのインタフェースは下記のような関数ポインタを定義した構造体として定義しており、このモジュール内部でのライフサイクルを定義しています。
例えばinit関数ポインタには各種ストレージを初期化する関数ポインタが代入されることを期待しており、update_entryでは各種ストレージ内部での更新処理を行う関数ポインタが代入されることを期待しております。

handler側ではこの構造体を元にライフサイクルを初期化〜破棄に関するまで定めており、適宜それぞれの箇所で関数を呼び出します。
ストレージ側の実装ではこれらのインタフェースを元に各種イベントにおける処理を実装することになります。

/**
 * function pointers. these behave like interface.
 */
typedef struct {
	int (*init)(ngx_cycle_t *cycle, ngx_http_access_filter_conf_t *afcf);
	void* (*get_entry)(char *key, ngx_http_access_filter_conf_t *afcf);
	storage_entry_t* (*get_data)(void *entry_p);
	void (*free_entry)(void *entry_p);
	int (*add_count)(char *key, void *data, ngx_http_access_filter_conf_t *afcf);
	int (*set_banned)(char *key, void *data, ngx_http_access_filter_conf_t *afcf);
	int (*update_entry)(char *key, void *entry_p, ngx_http_access_filter_conf_t *afcf);
	int (*create_entry)(char *key, ngx_http_access_filter_conf_t *afcf);
	int (*fin)(ngx_cycle_t *cycle, ngx_http_access_filter_conf_t *afcf);
} storage_accessor;

つまりこのnginxモジュールの中で更にストレージをモジュールとして扱い実装しており、これによりストレージは任意のものに差し替えられる拡張性を手に入れることになります。
これはすなわち、今後他のストレージを使用したいというような場合において、追加で実装したい時にはこのインタフェースで期待する関数を実装することだけで可能になります。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください