eclipse/leshan で最近直した問題について
かなりニッチな話題ですが、OMA LwM2Mのサーバ・クライアントのJava実装であるEclipse Leshanにパッチを送って取りこまれたのでそのご報告です。
Leshanのクライアントライブラリには予期せぬ例外が発生した際にクライアントアプリケーションがスタックし、プロセスは生き続けるものの一切の仕事をしなくなるという問題がありました。
Better handle unexpected error in DefaultRegistrationEngine. · Issue #933 · eclipse/leshan · GitHub
例えば以下のようなコードの箇所でRuntimeExceptionが発生すると、エラーログが記録されるだけで他のエラーハンドリングが成されません。
この RegistrationTask
は個別のスレッドで動くのですが、意図しない実行時例外 (例えばUDP通信のレイヤで失敗するなど) が発生した場合はこのスレッド (RegistrationTask
) はそれ以降何もしない、かつ孤児のような状況になり、孤児スレッドは回収されずプロセスは生き続けることとなります。
LwM2M的に register
が成功しない限りプロトコルとして意味のある通信はできませんから、つまりこの状態のクライアントアプリケーションは一生register処理を行うことのできない、無意味なプロセスと化します。
その他にも複数箇所同様の問題がある部分があったため、それらを修正したというのが以下になります。
- Add support of `Startable`, `Stoppable` and `Destroyable` to LwM2mObjectEnabler. by moznion · Pull Request #940 · eclipse/leshan · GitHub
- Add callback mechanism into LwM2mClientObserver for when the unexpected error occurred by moznion · Pull Request #941 · eclipse/leshan · GitHub
- Backport: error handling for unexpected error in DefaultRegistrationEngine by moznion · Pull Request #944 · eclipse/leshan · GitHub
これらの変更により、不慮の例外が当該箇所で発生した場合は自動的にリソースを開放する (つまりシャットダウンを正しく行なう) ようになるため、何もしないゾンビのようなプロセス (注: ゾンビプロセスではない) は基本的に発生しなくなります。
基本的、と記述した理由は利用者が独自に定義して利用している LwM2mInstanceEnabler
及び LwM2mObjectEnabler
に対して適切に Startable
、Stoppable
およびDestroyable
というそれぞれのInterfaceを実装してあげる必要があるためです。
不慮の例外が発生した際にしっかりと終了させたい場合は Destroyable
を実装する必要がありますし、ホットな状態での再起動処理を正しく行いたい場合は Startable
および Stoppable
を適切に満足させる必要があります。
この詳細についてはLwM2mInstanceEnabler
及びLwM2mObjectEnabler
のjavadocをご参照ください。
これらの修正はバージョン1.3.0以降から利用可能となっています。
現在開発中の次世代バージョンである2.0.0については順次対応予定 (2.0.0-M1よりも新しいバージョンで) となっているようです。
以上です。ご活用ください。