いくつかプラグインを作ってみて(RocketIOLindaなど)踏んだ地雷について書いておく。


ちなみに作るにあたって読んだドキュメントは
Sinatra: Writing Extensions
Sinatra Extension を書くお作法、というか我流 #Ruby #Sinatra – Qiita [キータ]
Sinatra でカスタムセッター/ゲッターを定義したり、それにより処理をフックしたりする #Ruby #Sinatra – Qiita [キータ]
sinatra-contribとeventmachineとrackのコード
だけです。


modular styleで動かない / classic styleで動かない

これはもう両方で試すしかないですね。
片方では動くのにもう片方では動かないとか、5回ぐらいあったのでもうこれはサンプル2種類作って試すしかないのではないかと思う。


他のpluginから呼び出された時に動かない

自作pluginをさらに自作pluginから呼び出した時に起こった。
変な事をするpluginばかり作っていたからだと思う。(rackと別にem-websocketでサーバーを建てるとか)
でもpluginの完成度を上げるには、そのpluginを使うplugin書いてみないと絶対わからないのではないかという不安が充満している。


サーバーが起動するまで待つ必要ある場合もある

EventMachineなサーバー(thinなど)と一緒に、他のEventMachineなライブラリ(em-websocketなど)を使う時は
自分でEM::runしてはならない。thinが起動しなくなってしまう。

EventMachineが起動するまで待つにはこうする
def self.start
return if @@running
@@running = true
EM::defer do
while !EM::reactor_running? do
sleep 1
end
puts "Sinatra::WebSocketIO.start port:#{options[:port]}"
EM::WebSocket.run :host => "0.0.0.0", :port => options[:port] do |ws|
ws.onopen do |handshake|
## (略)
どういうわけか、EventMachineが起動する前でもEM::deferは使えるので、そこでEM::reactor_running?を待ってやるとよい。
それから他のEventMachineなライブラリを起動してあげる。


modular styleとclassic styleでsetやenableのタイミングが違う

これもハマる場所で、どっちがどっちだったか忘れたけど
sinatra読み込まれる→プラグイン読み込まれる→setやenable→サーバー起動
だったり
sinatra読み込まれる→プラグイン読み込まれる→サーバー起動→setやenable
だったりした。
最終的に、上のEM::reactor_running?を待つ方法を使って、サーバーが起動するまでプラグインの中でsetでオプション渡されるような機能に処理が行かないようにした。


気軽にSinatra::Base.routesいじってるとよくわからない事起こりうる

ドヤ顔でroutesをいじっていたのですが
Sinatraのroutesを直接操作する
これも、modular styleとclassic styleで
プラグイン読み込まれる→ユーザーの書いたrouteが登録される→サーバー起動
だったり
ユーザーの書いたrouteが登録される→プラグイン読み込まれる→サーバー起動
と順番が違ったりして、やらかしましたね。

RocketIOは何バージョンかの間、これが動かない状態だった。このroute削除してた。
get '/*' do
## 略
end


require名とgem名が違うのでBundler.requireが通らない

これよくわからないんですけど、どうすればいいんですかね・・?