p5-IkuSanを煩悩のままに公開

人生の迷子の行き着く先は富士の樹海ではないかと最近良く考えています。mix3です。

p5-IkuSan

IRCボットいい加減今のプロジェクトに欲しくなったので、自分がIRCボット作ったらこうするなというのを以前書いたのだが、今回は実際にそれを作ったという話です。

ただ単に作るだけだと別にUnazuSanで良いじゃないってなっちゃうので、以下の機能を盛り込みました

Getopt::Longの引数が取れる

以前の記事参照

並列にタスク処理が出来る

最初Gearman使って頑張ってたのだけれど @karupanerura さん作、AnyEvent::ForkManagerというのがあるのを見つたのでそれを使うように。worker数を指定出来る様にして並列に処理出来る様にしました

あんまり気にしなくても良いとは思うけれども処理中だからってボットが無反応になるのはなんとなく嫌だったので

タスク処理中、dieしたら共通処理出来る様に

Try::Tinyを使って囲ってるだけなので別にいらないと言えばいらない(自前でtry catchするのでも良い)が、どうせボットが返すエラー文言なんて一律で同じように返したって全然良いと思うので、共通処理を設定出来る様にしておきました

ということで

p5-IkuSanが出来ました

一応CPANに上げるつもりだったので、今まで使ったことなかったMinillaを使ってみたり、plenvCartonを経由してdaemontoolsで起動出来るようにするというplackアプリの起動で良くある感じのアレをちゃんとやってみたり、その際にCarton経由しつつsystem perl使おうとするとCartonの方で環境変数PERL5OPTが設定されてしまうのでunsetするなりしないと読むモジュールが違って悲しい思いをするということを知ったり、perl5.19.10とか使うとNet::SSLeayあたりでpanicとかなんとか言われて動かなかったり(原因不明)forkしてる関係で子プロセスからsend_messageやらなんやらしようとして死にまくったりして、ikachanリスペクトで頑張ってみたり、衣玖さんはやっぱり可愛いんだなと再認識したりしました。CPANの方にもちゃんと画像出る様にしたい。

あと以下の発言が実現出来てワタクシ非常に満足しております。煩悩はチカラなり。

revel入門

絶賛人生の迷子中、mix3です

golangでWebアプリ

を作ってレビューしてもらったらそれはもうフルボッコでそれこそ雄山のあれな感じでした

このWebアプリを作ったのは誰だぁっ

isucon3を元に手探りでやったため突っ込みどころを残してしまったようです

  • panic使ってerror潰すのやめろ
  • パス解決にCallerいらねーだろ
    • 一応カレントディレクトリを判断したいという意図だったけどいらないらしい
  • 動かし方 go run hoge.go じゃなくて go build hoge.go; ./hoge ってちゃんと書け

などなど

golangのWebアプリの良いサンプル、一応最初に自分で探してはみたものの良い感じのを見つけられず、後で「campoy/todoが参考になるんじゃない?」と教えてもらいました

最初に知りたかった… ちなみにパス解決の突っ込み

https://gist.github.com/mix3/9430209

mix3 ~/tmp/caller_sample $ go run main.go
2014/03/08 21:56:14 loading config (with caller) file: /private/tmp/caller_sample/config/config.json
2014/03/08 21:56:14 OK
2014/03/08 21:56:14 loading config file: config/config.json
2014/03/08 21:56:14 OK

mix3 ~/tmp $ go run caller_sample/main.go
2014/03/08 21:56:38 loading config (with caller) file: /private/tmp/caller_sample/config/config.json
2014/03/08 21:56:38 OK
2014/03/08 21:56:38 loading config file: config/config.json
2014/03/08 21:56:38 open config/config.json: no such file or directory
exit status 1

こんな感じで実行パスに左右されないパス解決が出来るので使い方間違ってなければ意味はある書き方だとは思うんですが、まあ今回は必要ないよってことですかね

revel使いましょ

そんな感じで センスの無い やつが手探りでやると悲惨なことになるのでWAFに乗っかった方がきっと良いと判断されたっぽい(実はそこらへん曖昧だったり…)のでとりあえずrevelにのっかることにしました

使い方は公式http://robfig.github.io/revel/index.htmlのtutorialとmanualとsample眺めてればなんとなく分かる感じです

以下revel/samples/bookingにはgorpとsqliteを使ったサンプルコードがあるのだけど、「mysqlにするにはどうすれば?」と少し悩んだのでメモ

conf/app.conf のsqliteの設定をmysqlのものに変更

db.import = github.com/go-sql-driver/mysql
db.driver = mysql
db.spec   = root@tcp(localhost:3306)/alphawing

app/controllers/gorp.go のimportしているドライバをmysqlのものに変更

_ "github.com/go-sql-driver/mysql"

app/controllers/gorp.go の gorp.DbMap{} を mysqlのものに変更

Dbm = &gorp.DbMap{Db: db.Db, Dialect: gorp.MySQLDialect{"InnoDB", "UTF8"}}

だいたいこれくらい弄るとmysqlで動く様になるはず

ちなみにsampleだからだと思うのだけど以下のような感じでコントローラ処理の前後にBegin,Commit,Rollback を入れ込んでて吹いた

func init() {
    revel.OnAppStart(InitDB)
    revel.InterceptMethod((*GorpController).Begin, revel.BEFORE)
    revel.InterceptMethod((*GorpController).Commit, revel.AFTER)
    revel.InterceptMethod((*GorpController).Rollback, revel.FINALLY)
}

modelsでちゃんとやりたいときにはどうしたらいんだろうか…

あけまして

おめでとうございます

今年もよろしくお願いします

Vagrant with Virtualbox tips - internal network setting

ちょっと詰まったことがあったのでメモ書き これ書いてる時点でVagrantのバージョンは 1.4.1 となります

Virtualboxのネットワークアダプタにはいくつか種類があり

  • NAT
    • ゲストOS -> 外
  • 内部ネットワーク
    • ゲストOS <-> ゲストOS
  • ホストオンリーアダプタ
    • ホスト -> ゲストOS

あたりを組み合わせて遊んだりするのですが、Vagrant で内部ネットワークを設定する方法が分かりづらかったのでメモ

VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
  config.vm.box = "box_name"
    config.vm.define :host1 do |host1|
    host1.vm.hostname = "host1"
    host1.vm.network :private_network, ip: "192.168.1.111", virtualbox__intnet: "intnet"
  end
    config.vm.define :host2 do |host2|
    host2.vm.hostname = "host2"
    host2.vm.network :private_network, ip: "192.168.1.112", virtualbox__intnet: "intnet"
  end
  config.vm.provision "shell", inline: "/etc/init.d/network restart"
end

抜粋するとこんな感じ

Private Networks - Networking - Vagrant Documentation とか見てると

virtualbox__intnet: true

とか書いてるけどそのまま設定すると「(trueが)文字列じゃねーよゴルァ!」と怒られるので、何かしら文字列を指定してあげる。

Virtualboxで設定した場合、内部ネットワークを指定した時のデフォルトが intnet なのでintnetで良いでしょう。

で、これで内部ネットワークの設定が出来るのですが初回の vagrant up 直後はNATによる設定で外に行けるはずなのに繋がらなかったりするので、

Shell Provisionerでnetworkの再起動をしてます。もっとスマートなやりかたあればいいんだけど。

ndenv を homebrew で入れる話 または如何にして心配するのを止めてRequireJSを愛するようになったか

というようなことを元々は teck.kayac.com Advent Calender 2013 の17日目 の記事として考えてたんだけど、結局なんか無性にWicketの事を書きたくなっちゃったので、お蔵入りになった記事をこっちに書く事にする。

カレンダーのノリで書いてたのをそのまま持ってくると大分寒い感じがするが、面倒なので不自然なカレンダー要素を消す意外は無編集で。

ndenv を homebrew で入れる話 または如何にして心配するのを止めてRequireJSを愛するようになったか

Advent Calenderネタの捏造のため紆余曲折あって週末Backbone.jsのexampleを永続化部分をローカルストレージじゃなくてAPIベースに書き換えつつテストをコマンドライン(Mocha on node)でやる、みたいなことをやってました。

その副産物としてndenvをhomebrewで入れられるようforkして弄りつつFormulaを書いたりしました。

brew tap mix3/ndenv
brew install ndenv node-build --HEAD

こんな感じで入れられると思います --HEAD なのはお察しください。多分他の誰かが既にやってるんじゃないかと思いますが気にしない事にしました。

先生助けてっ Mochaが息してないの!

で、node入れてbackbone-examplesを弄ったわけですがAPIベースにするのは割と簡単に出来る(Backboneがモデルの永続化にRESTが使える)のですが「さてRequireJSで分割したのだし何かテスト書くか」と適当に書くとあら不思議。Mochaでテストが全くが実行されません。

AMD準拠のmochaテストをWebとCUIで共通化 - それなりブログにあるように非同期関連でうまく行かないようで同ブログにて書いてある通り「amdefineで解決や!」と思ったらcollectionのテストの時にmodelを呼ぼうとして「みつかんねーよ!」と怒られてRequireJSの時と違ってbaseUrl設定してないんだし、そうだよなってなって奇声上げてました。

で色々見ててどうにもならない感じだったけど、なんか他のサンプルとか色々眺めてるとテストの中でrequirejs使ってるのが多いっぽかったので、どうもそっちの方が一般的のようです。

describe("Did it run?", function(){
    it("model is a model", function(done){
        // こんな感じで中でrequirejsを呼ぶ
        requirejs(["model"], function(model) {
            expect(model).to.be.a("model");
            done();
        });
    }); 
});

無理せずrequirejs使っていきましょう。

もう一つテストで困るのが、コマンドラインテストだとajaxとかで怒られるということ。(domが無いからってことで良いんだよね多分)

この辺りをコピって参考にしてjsdomを使うようにしてあげると良いようです。

ということで出来たのがこちらになります。

どうやってコマンドラインでテストするかばかり考えていて「Backbonアプリのテストってどんな感じで書けば良いのか」についてまでたどり着かなかったので次触るときはそこまで考えて触りたいものですね。

まとめ

  • 実は一番最初の発端は「AngularJS触ろう!」だったのにどうしてこうなった。
  • 今はMarionette.jsが気になります。
  • js、結局クライアントとサーバで分かれてるのが少し不幸っぽい(小並感)
<< < 1 | 2 | 3 | 4 | 5 >>