サクサク読めて、アプリ限定の機能も多数!
トップへ戻る
大そうじへの備え
walf443.hatenablog.com
github.com guard-rubocopの中身を見たらsystemで呼びだしていたので、直接Rubocop::CLIを呼びだして起動するようにしてみたら爆速になって快適になりました。 もっさりするのでテストのあとにrubocopを実行するようにしていたけど、これなら先に実行してもいいんじゃないかなーという速度感。 rubocop.ymlのsyntaxエラーとかの場合のエラーがうまくハンドリングできてないっぽいですが、通常の実行には(まだちょっとしか使ってないけど)問題なさそうです。 お試しは、Gemfileに gem 'guard-rubocop', github: 'walf443/guard-rubocop', branch: 'do_not_system' でどうぞ。
isucon予選中に、SQLを出力したくなったのだけど、ふとgithub.com/shogo82148/go-sql-proxyを使ってみようとしてとりあえず簡単に使う方法が書いてなくて少し使い方を調べるのに苦労したので、isuconで時間のロスなく使えるようにそのwrapperを書きました。 package main import ( database/sql "github.com/go-sql-driver/mysql" # load driver before load go-sql-tracer _ "github.com/walf443/go-sql-tracer" ) func main() { db, err := sql.Open('mysql:trace', dsn) } ポイントは、 元々使っていたドライバ名に":trace"とつけること go-sql-driver/
ListenしているSocketのfdを知りたいが、net.Listenerのインターフェースをみても取得する方法がないのでググったら、 http://naoina.plog.la/2013/11/12/235753683181 こんな記事をみつけた。 Socketからfdが取得できないのは、POSIX縛りになるからだと思われるが、ここで方法へどうやって辿りついたかよくわからなかったので調べてみた。 TCPListenerの定義を調べると、 // src/pkg/net/tcpsock_posix.go type TCPListener struct { fd *netFD }となっているので、reflectパッケージを使えば、 reflect.Indirect(reflect.Indirect(reflect.ValueOf(listener)).FieldByName("fd"))で、
ちょっとRidgepole試してみようかなと思って使いはじめた。rails書いていると他の人がmigrationふつうにしようとしてしまったりするだろうから、rake db:migrateのデフォルトの動作を無効にして、ridgepoleを動作させたい。 lib/tasks/ridgepole.rakeとかで、 # overwrite db:migrate or db:dump task 'db:migrate' => :environment do ENV['RAILS_ENV'] ||= "development" sh "bin/ridgepole -E#{ENV['RAILS_ENV']} -c config/database.yml --apply" sh "bin/ridgepole -E#{ENV['RAILS_ENV']} -c config/database.yml --
ChangeLogのファイルはプロジェクトにあったりなかったりなので、githubのリポジトリのタグ間のdiffへクリックでいけるようにしてみた。 これでbundle updateとかしたときにざっくりどういう更新があったのか確認ができる。 現在は、Gemfile.lockのdiffと、package.jsonのdiffに対応している。 Github Library Changes - Chrome ウェブストア github.com
webでHTML Media Captureについてググると、上の方にでてくるコンテンツはわりと、 <input type="file" accept="image/*;capture=camera" /> とか、 <input type="file" accept="image/*" capture="camera" /> とか書いてあったりするのだけど、http://www.w3.org/TR/html-media-capture/ を見たら、 partial interface HTMLInputElement { attribute boolean capture; };のようになっていて、capture属性はbooleanになっているなー、ということで、 <input type="file" name="image" accept="image/*" capture> のように書
isuconの予選で、カジュアルにここどれぐらい時間がかかっているか計測したい、ということで作った。 pprofは(使い方間違っているだけなのかもしれないけど)CPU時間での計測なので、io待ちとか、channel待ちとかの時間は出てこないので、web applicationのチューニングにはあまり適さないのかなという気がする。 https://github.com/walf443/stopwatch やりたいこととしては、 計測コードを簡単に無効にできる ここから、ここまで、という指定以外に前回の実行からどれぐらいたったのか? というのも自動でとりたい ということを達成したかった。 package main import ( "flag" "github.com/walf443/stopwatch" "time" ) func main() { flag.Parse() stopwatc
Dockerをローカルで実行できるようになっても、ポート転送を手動で設定しないといけないのがつらいので、コマンドでやれるようにするのを調べた。 VBoxManage controlvm boot2docker-vm natpf1 "node,tcp,127.0.0.1,49160,,49160" VBoxManage controlvm boot2docker-vm natpf1 delete nodeというようにすると、ポートフォワードの設定が変更できるので、ブラウザから立ちあげたコンテナへアクセスすることができます。 boot2docker-vmのマシンが起動していないときは、 VBoxManage modifyvm -boot2docker-vm natpf1 "node,tcp,127.0.0.1,49160,,49160" VBoxManage modifyvm -boot2do
雪がひどすぎて外出る気がしない。あー、そういえば、DockerがOSX対応したっていうし、ぼちぼち試してみるかー、と思って http://docs.docker.io/en/latest/installation/vagrant/ みてみたけど、あんまりかわってない気がする、というみなさんこんにちは。 そのページは前からあまり変わっていなくて、 https://github.com/dotcloud/docker/blob/master/docs/sources/installation/mac.rst こっちが新しい手順らしい。 手順はそのままな気がするけど、homebrewでやればもうちょい簡単なようです。 まずは事前にVirtualBoxをInstallしておきます。 brew tap homebrew/binary brew install docker brew install
なかなか書く機会はなかったのだけど、ふと使えそう!、という場面があったので、Server-Sent Eventsを書いてみたのでメモ。 レスポンスのContent-Typeはtext/event-stream dataを組み立てる際は、改行(\r, \n, \r\n)をエスケープする。 http://www.w3.org/TR/eventsource/#parsing-an-event-stream http://dev.ariel-networks.com/wp/archives/4168 任意に改行を入れられると、任意のイベントを定義されてしまうので、何らかの入力を元に出力するときには、改行コードのエスケープが必要。 UTF-8であること、という制約もあり、とりあえずはJSONにしておくのが扱いやすくてよさげ。 JSONにするときに改行はエンコードしてくれないことがあるっぽいので、そこ
pgrep -F pidfileオプションを使うと、pidfileを開いて、その中にあるプロセスIDが存在するか調べ、存在している場合には、0で終了してくれるようだ。 なので、起動スクリプトとかで、pidfileの存在チェックとかをするときには、 if test -e $PIDFILE && pgrep -F $PIDFILE > /dev/null; then restart fi とか書いてやれば、マシンがハングアップとかして、正常に終了しなくて、pidfileが残っているがファイル内にあるプロセスIDはもういない場合にrestartをしても悲しいことにならずにすむ。
1日目で参加してきた。 今回は他の二人にアプリケーション側はお任せして、自分はミドルウェアまわりをやる、ということにしていた。 最初は、PHPを動くように設定を変更して、ベンチマークを実行していたのだけど、どうもfailしてしまう。原因を見ると、ログイン回りなので、セッションがおかしそうだ、というところまではわかったのだけど、ちゃんとした原因まではわかっていなかった。 セッションをファイルストレージに書くように変更してもfailするので、途中rubyにしようか、phpを5.5でコンパイルしなおして頑張ってみる、とか12:30ぐらいまで右往左往してた。 その後もfailし続けたので、セッションをAPCuに入れるようにしようとしてみたりとかしたが、解決できなかった。 途中で、ベンチマークスクリプトのworkloadをあげると、なんとかスコアが最後までfailしないでおける、ということがわかった
kamipoさんが補足を書いてくれたので、参照するとよいです。 基礎的だけど、SELECT ... FOR UPDATEをちゃんと理解できてない気がするな、ということで実際にコンソールで打ちながら挙動を確認してみた。 今回確認した環境は、 mysql> show variables like 'tx_isolation'; +---------------+-----------------+ | Variable_name | Value | +---------------+-----------------+ | tx_isolation | REPEATABLE-READ | +---------------+-----------------+ 1 row in set (0.00 sec) mysql> show variables like 'version'; +-----
とあるサービスでslow logをみていたら、どこかの記事で読んだことのあるクエリがでてきたのだけど、もうちょっと速くできないものか、と考えてみた。 結論を言えば、 BEFORE: SELECT sql_no_cache COUNT(*) FROM (SELECT item_id FROM category2item WHERE category_id = '2' group by item_id ) AS t; 1 row in set (2.06 sec) AFTER: SELECT sql_no_cache COUNT(*) FROM (SELECT 1 FROM category2item WHERE category_id = '2' group by item_id ) AS t; 1 row in set (1.89 sec)という感じで、SELECT item_idではなく
arproxyを使うと、SQLにフックして色々書きかえることができて非常に便利ですね。 module Arproxy class QueryLocationCommentAppender < Arproxy::Base WHITE_LIST_WORD_RE = %r{^[a-zA-Z0-9\-_/:\?]+$} def execute(sql, name=nil) if ENV["ARPROXY_QUERY_LOCATION"] # SQL Injection対策 # コメントの閉じ文字がパラメータに含まれていなければ大丈夫なはず if ENV["ARPROXY_QUERY_LOCATION"].index("*/").nil? # 制御文字や、マルチバイトの文字を防ぐため、文字種を制限する if ENV["ARPROXY_QUERY_LOCATION"] =~ WHITE_LIST_WO
前回非常に楽しかったので、今回も参加したいなーと思っていたのですが、「くらげとみかん」チームで、なんとか参加できました。 走り書きだけど、考えたこと、やったことをメモっておく(あとでまとめなおすかもしれない) まずは最初に全サーバーへsshの鍵を通して、screenで全サーバーへログインした。 前回ベンチマークを走らせるのが遅かった、という反省があったので、まずベンチマークを実行した。 まずappをいじるための環境を整備した。git reposを作ったり。(11:30) 次は、アプリケーションの概要を把握するために、全tableのschemaをshow create tableしたり、全テーブルの件数を把握して、stockテーブル以外は対した容量にならない、ということを把握した。 long_query_timeを0にして、ベンチを走らせて、全クエリをslowログへ出力し、mysqldump
色々な言語が混ぜまくりすぎなので、他の人も環境を用意するようなものであればあまりおすすめできない。 guardfile内でふつうにWEBRick起動させるコードを書くのがよいんかな。 source/buildするディレクトリを分ける設定であるのを前提としております。 guard-shellとguard-livereloadが必要。 # A sample Guardfile # More info at https://github.com/guard/guard#readme guard 'shell' do watch(%r{source/.+\.rst}) { puts "invoke sphinx build" Process.spawn(%|make html >/dev/null|) } end guard 'shell' do watch(%r{app.psgi}) # dum
以前公開した、rails/rakeコマンドを超早くするrrailsですが、 http://d.hatena.ne.jp/walf443/20120427/1335482420 あれから、色々な方に使っていただいているようで、パッチをいくつかもらったりしてupdateしたりしています。 最近quark-zjuさんという方からたくさんpatchをいただいて、今までできなかったことができるようになった & 今までと非互換なところがでてきた、ということで紹介します。 rails console/serverができるように 今まで子プロセスへPTYの引きつぎをしていなかったため、rails console/serverなどが実行しても、こちらの入力をrrailsへ教えることができなかったのですが、できるようになりました。 個人的にはrails consoleあんまり使わないので対応しなくてもいいかな
最近DCI(Data Context Interaction)アーキテクチャというのを良く耳にするので、ちょっと調べたり他の人のコード例などをもとにちょろっと書いてみたりしたところ、やっぱりよくわからないなーと思いつつ、つまりはこういうこと?というのをまとめてみる。 たぶん色々と大分間違っているんだろうなぁと思いつつ、間違いを指摘してもらえるとありがたいです。 DCIは、MVCを置きかえるものではない。MVCのModelの部分が肥大化し、管理が難しくなる傾向にある(Skinny Controller, Fat Model)ので、そこをうまく扱うにはこう考えて分割すればよろしい、という考え方。つまり、M(D-C-I) - Controller - Viewみたいに書くことになる。 同じモデルでも、ユーザーの役割によって、振舞いが異なることがある 例えば、管理者(Administrator)に
ChangeLogはリリースのたびに見直して手で丁寧に書いておく方が利用者にとってはうれしいことが多いですが、一方でまとめなおし作業はまぁまぁめんどいです。 そこで、手直しするにしてもそれまでの情報をコミットログから雛形を自動生成してやれないかなーとおもってつくってみました。 https://github.com/walf443/dotfiles/blob/master/bin/git-changelog 基本的には標準出力に出すので、自動生成して、git add -pしてひとまず欲しいところだけ取りこんで、記述を微調整すればよいのかなー、という感じです。 生成例はこんな感じ https://github.com/walf443/seqdiag.js/blob/master/Changes.md ChangeLogのないライブラリの更新がどんな感じかなーと眺めたりするのにもまずまず便利です
cronなどで統計処理のSQLをたくさん投げたりするときに、mysqlにあまり負荷をかけたくないので、適度にsleepを挟みながら実行させる、という処理を書くときに、perlだと、Sub::Throttleというid:kazuhookuさんのライブラリを使っていたのですが、rubyで同様のライブラリを探すとなかったので、rubyへrate_throttleという名前で移植しました。(本当はProc::Throttleにするつもりだったのですが、既にあったので....) require 'rate_throttle' 1000.times do # limit block to 10% workload. RateThrottle.throttle(0.1) do # do something. end end こんな感じで書くと、ブロックを実行した後にその実行時間が10%になるようにsle
おかげさまでRack::CommonLogger::Fluentを運用しはじめました。 Mongoに記録してごにょごにょとか、色々な方法があるらしいのですが、とりあえずファイルに記録しておいて、用途はあとで考えようという感じで使っています。 ということで、ログファイルを色々みてみてアクセスがどんな感じなのか、を調べたりするときに便利そうなflgrepというツールを作ってみました。(既にどこかにありそうな気もしつつ。Rack::CommonLogger::Fluentのv0.4.0から同梱されています。 Rack::CommonLogger::Fluentに入ってはいますが、fluentdのログ形式であれば使えるんではないかと思います。 $ flgrep Usage: flgrep [options] -c, --column=s column name to target -v, --va
railsのアクセスログは、とても機械的に解析しづらく、運用するにはあまりよろしくない。そこで、Rack::CommonLoggerを使ってアクセスログを別途とったりしようとしていたのですが、(一般的にはNew Rericとかをつかうのが普通なんでしょうか?) ログのローテーションとか考え出すと、あまり良い方法が思いつかない、という関係で、 syslogへ投げる fluentdへ投げる というアイディアを思いついたのですが、syslogだと機械解析しづらいフォーマットになってしまったりあまり詳しい人が意外といなかったりする関係で、流行っているfluentdへ投げちゃえと思いRack::CommonLogger::Fluentというrackのミドルウェアを書いてみた次第。 https://github.com/walf443/rack-common_logger-fluent まだ作り始めで
最近はお仕事で久々にがっつりrubyを書いてます。rails難しいです。 それはさておき、railsコマンドの実行が遅いのがつらいので、色々探していたら、jugyoさんのrails-shを見つけました。 rails-shはscalaのsbtとかみたいに、railsを読みこみ済みの環境を起動しっぱなしにしておき、既にライブラリ読みこみ状態からコンソールからコマンドを実行することで、ライブラリ読みこみにかかる時間を短縮する、というツールで、非常に実行を高速化することができます。 しばらく使っていたのですが、 raills-shのコンソールへ移動して打つのを忘れる zshじゃない RAILS_ENVがtestなコマンドも欲しいと2つのscreenのwindowを消費する rake -Tが動かない などがあったので、TCPでコマンドを送り、それ経由でrails/rakeコマンドを実行させるrrai
月日の流れは早いもので、「モバイルファクトリー入りたい」の記事を書いて会社へ遊びにいってから、5年と約半年が過ぎました。 昨日が最終出社日でした。 会社では、様々なサイトの開発、運用、フレームワークの開発、deploy/監視のフローやツールの整備、様々なクラウド環境の検証など、様々なことをでき、大変よい経験になりました。 一年目で新卒で入社したときには、私一人に対し、id:tokuhirom、id:nekokak、id:mikihoshiといった豪華メンバーが色々と教えてくれる、という夢のような経験ができ、非常に良い刺激を受けました。 そこで教えてもらった仕事の姿勢、考え方などをベースにして、ここ数年は、サービス開発/運用のための基盤の整備などを行なっていたのですが、自分は良いと思ってやってはいるものの、はたしてこのやり方でよいのだろうか、とか、他の会社はもっとよいやり方をしているのではな
メンテナンスなどで、マスターデータを書きかえるときは、 use strict; use warnings; use DBIx::Handler; my $db = DBIx::Handler->new("dbi:mysql:test;", "root", "", { RaiseError => 1}); $db->dbh->do(q{ CREATE TABLE IF NOT EXISTS hoge ( id int unsigned not null auto_increment primary key, test int unsigned not null ) ENGINE=InnoDB CHARSET=utf8 }); my $txn_guard = $db->txn_scope; $db->dbh->do(q{TRUNCATE TABLE hoge}); for my $counte
巨大なtableへのalter tableが必要になったのだけど、enumへのalterって確か最適化してくれたんじゃなかったっけな、ということで、一応確認のため検証してみる 次のschemaを用意します。 CREATE TABLE `enum_test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `type` enum('foo','bar') DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=105135 DEFAULT CHARSET=utf8 次のようなデータを大量にINSERTするプログラムを書き、入れておきます。 use strict; use warnings; use DBI; my $dbh = DBI->connect('dbi:mysql:test;',
YAPCでmalaさんの話を聞いていて、memcachedのようにお手軽に使えるbloom filterがあるとひょっとすると便利かもしれない、とふと思ったのでAnyEventつかって、Bloom::Fasterのwrapperを書いてみました。 https://github.com/walf443/p5-bloomd-server 以下のようなプログラムを書いてサーバーを起動します use strict; use warnings; use EV; use AnyEvent; use Bloomd::Server my $cv = AnyEvent->condvar; my $server = Bloomd::Server->new( capacity => 100_000_000, backupdir => '.', ulog => 'ulog', ); $server->run $c
結構前に自宅サーバーの仮想化はXenにしていたのをこれからはKVMらしいのでKVMに変えてみるか、とやってみたときは、ホストOSにX入れないとうまく動かなかったりそういう点が嫌だなぁと思っていたが、だいぶ環境や情報が揃ってきて、Xenで作ったりするのと同程度には楽にできるようになったようだなと思ったので、部屋の模様替えして再起動したついでにえいや、とやってみた。 ちょっと覚え書き程度にまとめておく。 sudo -H virt-install -n natty -r 256 --vcpus=1 \ -f /var/lib/libvirt/images/natty.img -s 5 \ --os-type=linux --os-variant=virtio26 \ --network bridge=br0 \ --location='http://jp.archive.ubuntu.com/u
次のページ
このページを最初にブックマークしてみませんか?
『walf443's blog』の新着エントリーを見る
j次のブックマーク
k前のブックマーク
lあとで読む
eコメント一覧を開く
oページを開く