その手の平は尻もつかめるさ

ギジュツ的な事をメーンで書く予定です

eclipse/leshan で最近直した問題について

かなりニッチな話題ですが、OMA LwM2Mのサーバ・クライアントのJava実装であるEclipse Leshanにパッチを送って取りこまれたのでそのご報告です。

github.com

Leshanのクライアントライブラリには予期せぬ例外が発生した際にクライアントアプリケーションがスタックし、プロセスは生き続けるものの一切の仕事をしなくなるという問題がありました。

Better handle unexpected error in DefaultRegistrationEngine. · Issue #933 · eclipse/leshan · GitHub


例えば以下のようなコードの箇所でRuntimeExceptionが発生すると、エラーログが記録されるだけで他のエラーハンドリングが成されません。

https://github.com/eclipse/leshan/blob/leshan-1.2.0/leshan-client-core/src/main/java/org/eclipse/leshan/client/engine/DefaultRegistrationEngine.java#L557

この RegistrationTask は個別のスレッドで動くのですが、意図しない実行時例外 (例えばUDP通信のレイヤで失敗するなど) が発生した場合はこのスレッド (RegistrationTask) はそれ以降何もしない、かつ孤児のような状況になり、孤児スレッドは回収されずプロセスは生き続けることとなります。
LwM2M的に register が成功しない限りプロトコルとして意味のある通信はできませんから、つまりこの状態のクライアントアプリケーションは一生register処理を行うことのできない、無意味なプロセスと化します。


その他にも複数箇所同様の問題がある部分があったため、それらを修正したというのが以下になります。

これらの変更により、不慮の例外が当該箇所で発生した場合は自動的にリソースを開放する (つまりシャットダウンを正しく行なう) ようになるため、何もしないゾンビのようなプロセス (注: ゾンビプロセスではない) は基本的に発生しなくなります。


基本的、と記述した理由は利用者が独自に定義して利用している LwM2mInstanceEnabler 及び LwM2mObjectEnabler に対して適切に StartableStoppableおよびDestroyableというそれぞれのInterfaceを実装してあげる必要があるためです。
不慮の例外が発生した際にしっかりと終了させたい場合は Destroyable を実装する必要がありますし、ホットな状態での再起動処理を正しく行いたい場合は Startable および Stoppable を適切に満足させる必要があります。
この詳細についてはLwM2mInstanceEnabler及びLwM2mObjectEnablerjavadocをご参照ください。


これらの修正はバージョン1.3.0以降から利用可能となっています。

github.com

現在開発中の次世代バージョンである2.0.0については順次対応予定 (2.0.0-M1よりも新しいバージョンで) となっているようです。

以上です。ご活用ください。