Work Records

日々の作業記録です。ソフトウェアエンジニアリング全般から、趣味の話まで。

ruby メタプロ method_missing使用例 - delayed_job編 -

gemをもくもくとよんでみた結果得られた物を書こうと思う。
今回はmethod_missing。

method_missingとは

rubyのメタプロ的書き方の一つ。
継承チェーンを一番上まで辿ってもそんなメソッド無いよ!って時に呼ばれる輩。
ググれば色々と出てきますが、要するに実行時に初めて存在するメソッドを呼ぶ時に便利。

delayed_jobでの使用例

delayed_jobって?

非同期にmethodを実行する為のgem。
github.com

実行方法は、Readmeに書いてある通り、レシーバーとメッソッドの間にdelayを挟むだけ。
これで、@user.activate!(@device)ごとシリアライズしてデータベースにキューを保存、daemon化しているプロセスが定期的にキューを拾って実行、とやっている。

# without delayed_job
@user.activate!(@device)

# with delayed_job
@user.delay.activate!(@device)

method_missing使用例

まず、疑問に感じるのが、delayってどこでよんでいるのだ?と@user.delayがなんでactivateを呼べるのか?というところ

delayが呼べる理由

ここは単純だが、ObjectとModuleにincludeさせている箇所がある。
lib/delayed_job.rb

Object.send(:include, Delayed::MessageSending)
Module.send(:include, Delayed::MessageSending::ClassMethods)

これもメタプロっぽいがincludeで継承チェーンに突っ込んでいる。(ObjectとModuleなので殆どのクラスは継承する事になる)
Delayed::MessageSendingにdelayがいるのではれて皆がdelayを呼べるようになる。
lib/delayed/message_sending.rb

(snip)
module MessageSending
  def delay(options = {})
    DelayProxy.new(PerformableMethod, self, options)
  end
(snip)
activateを呼べる理由

ここでmethod_missingを使っている。
さっきのdelayの中で呼ばれていたDelayProxyを追うと

class DelayProxy < Delayed::Compatibility.proxy_object_class
  def initialize(payload_class, target, options)
    @payload_class = payload_class
    @target = target
    @options = options
  end

  def method_missing(method, *args)
    Job.enqueue({:payload_object => @payload_class.new(@target, method.to_sym, args)}.merge(@options))
  end
end

となっていて、.new以外は全部method_missingに送っているのである。
もうちょっと読み進めると、.newでレシーバーとメソッドとオプションをセットしていて
enqueueする時にそれらをセットしようとしている事が分かる。
こうやって、呼び出したいメソッドをごっそりとシリアライズしてdbにキューとしてしまっていた。

まとめ

最近メタプログラミングRubyを読んでいて、method_missingの正しい使い道って何だろう?と思っていた。
こんなの黒魔術じゃないかと。
でもdelayed_jobは完全に正しくmethod_missingを使っているなと感動した。
次回はシリアライズあたりをおってみようとおもう。多分続く。

Qiita投稿 MySQL記事まとめ

最近はQiitaに投稿しています

Qiita(というかKobito)が結構便利なので最近は単純な技術系記事はQiitaに投稿しています。
おかげで今月31日だというのにこれが最初の投稿。

最近のMySQL系の記事まとめ @Qiita

良く分かるMySQL Innodbのギャップロック

qiita.com

MySQL utf8からutf8mb4への変換

qiita.com

MySQLでToo many connectionsが出た時の対応

qiita.com

はてなに投稿するよりはてぶが集まるよ笑

ギャップロックの記事は、2015/08/31現在で32、ツイートは20。
正直今まではてなで書いてきたどの記事よりも多い。笑
まあ、自分なんかの個人ブログよりもQiitaの方がSEO的に強いよね。そりゃそうだ。

とはいえ、なんだかんだでやっぱり読んでほしいし、色々な人からフィードバック欲しいのでQiitaの方が良いかなあなんて思っている最近。特に単純で短めな技術記事はQiitaが良いですね。
はてなには、この記事のようにカテゴリでまとめた記事を書くとか、
技術だけじゃなくて、個人的なメッセージなどを書く場になっていきそうかなと思う。

まあ形は変われど、アウトプットは大事なので今後も、はてな・Qiitaを続けていこうと思います。


Parse.comのAnalyticsが優秀すぎる

Parse.comのAnalyticsが相当優秀

出来る事がこんなにある

  • Audience
  • Events
  • Data
  • Retention
  • Performance
  • Slow Queries
  • Crashes
  • Explorer

運用しているアプリを例に一つ一つ紹介してみる。

Audience

Daily Active Userとか見れる。しかも期間無制限っぽい。
f:id:kenjiszk:20150713003129p:plain

Events

APIのリクエスト数とか、push通知数とかが見れる。
f:id:kenjiszk:20150713003505p:plain

Data

各テーブルのカウント数が見れる。画像はUserテーブルの件数。
f:id:kenjiszk:20150713003626p:plain

Retention

ユーザーのリターンレート。
f:id:kenjiszk:20150713003754p:plain

Performance

リクエスト数 req/secがのグラフ。オレンジの線は無料枠のリミット。
f:id:kenjiszk:20150713003922p:plain

Slow Queries

図省略。1秒以上のクエリの割合とか、90パーセンタイルのレスポンスとかみれる。結構凄い。

Crashes

図省略。クラッシュレポートが見れる。stack traceも見れる。

explorer

これはまだ使用してないのでリンクだけ。
ユーザーの行動解析などが可能になるよう。
blog.parse.com

iPhoneアプリが中国からインストールされてた

ある日突然iPhoneアプリ・バブルデコレータのインストール数が上がっていた

水玉コラ簡単作成アプリ、バブルデコレータですが急にインストール数が上がりました。
https://itunes.apple.com/jp/app/baburudekoreta/id741537396?mt=8&at=10l8JW&ct=hatenablog

大抵こういった時は、大きめなサイトで記事になってるとかなんですがググっても何も出ない。
なんだこれ?

そんな時のAppアナリティクス

Appアナリティクスでみたらどうやら中国からインストールされていたっぽい。そう言えば、日本のapp store以外にも出してたんだった。
アメリカもちらほらいる。日本語よめるんだろうか。
f:id:kenjiszk:20150713000937p:plain

何はともあれ、ありがとう中国、アメリカ!

日本以外のマーケットに出すべきか

バブルデコレータみたいなネタ系アプリなら出しちゃっていい気がします。
あと、サーバーを持たないカジュアルゲームなんかも出しちゃって良さそう。
規模が大きなアプリやSNSになると、

  • 他言語対応が必要になる場合がある
  • サーバーを持っている場合、通信の遅延や、時間の同期問題なんかがありそう
  • 問い合わせとかが中国語で来てもサポート出来ない

みたいな問題が出てきそうな気がします。

中国の反応とか知りたい

コメント機能とか付けたら中国やアメリカの人達がこのアプリをどう思ったのか書いてくれそうなのでそんなのがあったら面白そうかなーと。


https://itunes.apple.com/jp/app/baburudekoreta/id741537396?mt=8&at=10l8JW&ct=hatenablog

dockerコンテナに静的なIPをふりたい

dockerのコンテナは立ち上げる毎にIPが変わる

コンテナ立ち上げる毎に、新しくIPが付けられる模様。

immutable infrastructure的な考えだと、IPコロコロ変わっても管理側で頑張れよってかんじはする

そもそもdockerは使い捨てが気軽に出来る様にできているので、IPを固定にして管理しようとする事自体センスが無いような気はしなくもない。

でも付けてみた

でも、固定で付けたい時はある。
色々調べてみると、どうやらsecondary ipにはあとからIPがふれるらしい

コマンド
(IPやインターフェースは読み替えてください)

ip addr add 172.17.128.5/16 dev eth0

結果

eth0: <BROADCAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.3/16 scope global eth0
       valid_lft forever preferred_lft forever
    inet 172.17.128.5/16 scope global secondary eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:acff:fe11:3/64 scope link 
       valid_lft forever preferred_lft forever

注意

注意1

DHCPのように、空いているIPを選んできてふる必要がある。例えば、コンテナに割り振っているレンジの中でpingが通らないものを選択するような仕組みが必要。
もしくは何らかの方法で絶対に被らない事を担保する仕組み。

注意2

docker inspect --format '{{ .NetworkSettings.IPAddress }}' CIP

で出て来るIPは依然としてprimaryのみ。プログラム内で動的にIPを取得する事は出来無いので、configなどにsecondaryで振りたいIPは管理するしかなさそう。


[asin:4774174416:detail]

Dockerコンテナからのログアウト時にいちいちコンテナが落ちる!

Dockerのコンテナからログアウトすると、コンテナが落ちる

docker初心者ですが、小ネタを。
docker attachでコンテナにアタッチしたらCtl+p,qで抜けないとこんな感じになる。

~]# docker ps
CONTAINER ID        IMAGE                                       COMMAND             CREATED             STATUS              PORTS               NAMES
eb98ac3abc0e        kenjiszk/mysql5_6:latest                    "/bin/bash"         14 hours ago        Up 14 hours                             test_db
~]# docker attach eb98ac3abc0e
/]# exit
~]# docker ps
CONTAINER ID        IMAGE                                       COMMAND             CREATED             STATUS              PORTS               NAMES
# docker ps -a
CONTAINER ID        IMAGE                                       COMMAND             CREATED             STATUS                     PORTS               NAMES
eb98ac3abc0e        kenjiszk/mysql5_6:latest                    "/bin/bash"         14 hours ago        Exited (0) 6 seconds ago                       test_db

nsenterをinstallすると幸せに!

qiita.com

docker-enterを使うと、上記問題が解決。ログアウトし放題!
ただ、docあたりでtab打つと、dockerとdocker-enterが出てきて"docker ps"とかさくっと打てなかったりする。


[asin:4774174416:detail]

アプリ広告収入 2015/05

個人的に作っているアプリの広告収入

拙作の大した事無いアプリの広告売上を公開しています。
ほとんどのアプリが単なる学習目的でしたがせっかくなので収益化を少しながらしています。
とてもしょぼい金額ですが、反省も込めて。

売上 @nend

ときめきエキスプレスStation ¥0
https://itunes.apple.com/jp/app/tokimekiekisupuresustation/id660044163?mt=8&at=10l8JW&ct=hatenablog

バブルデコレータ(iOS) ¥768
https://itunes.apple.com/jp/app/baburudekoreta/id741537396?mt=8&at=10l8JW&ct=hatenablog

バブルデコレータ(android) ¥375
https://play.google.com/store/apps/details?id=org.waremon.bubble2&hl=ja

高額喫煙納税 ¥0
https://itunes.apple.com/jp/app/gao-e-chi-yan-na-shui/id902170473?mt=8&at=10l8JW&ct=hatenablog

計 ¥1,144

まとめ

計 ¥1,281
まあ相変わらず。
今特に新しく作りたいもののアイディアもないのでしばらくはこんな感じでしょうか。

[asin:4798040436:detail]