時計を壊せ

駆け出しWebプログラマーの雑記

Gotanda.go && 五反田もくもく会に参加しました && Gotanda.pm #2 は明日です

Gotanda.go

Gotanda.go #1 : ATND

Gotanda.goはみんなでA Tour of Goをやっていました。
Goは数年前にちらっと触ったきりだったので、だいぶ忘れていましたが、
スライスの仕組みをちゃんと理解できたのは大きな収穫でした。
わいわい話をしながらやっていたので、わからないことを気軽にきけてとても良い会でした。 GotandaのGoはGolangのGoだと思います!
主催者の @polidog さん、会場提供のヴォラーレ株式会社さん、ありがとうございました!

五反田もくもく会

五反田もくもく会 #2 - connpass

諸事情でちょっと遅刻してしまいましたが、いい感じにもくもくすることができて良かったです。
実は主催側だったのですが、片付けしか手伝えず、ひたすらもくもくしていました。
当日はカップラーメンが振る舞われ、カップラーメンの空腹をそそる匂いが充満し、
また1人、また1人とカップラーメンの誘惑に負けてカップラーメンを食べはじめるという、
カオスな感じの場に仕上がったのが面白かったです。*1
ほぼ無限ビールとほぼ無限お菓子も好評だったようで良かったでした。
またやると思います。主催の id:kfly8 さん。お疲れ様でした!次回は準備から手伝います!><

Gotanda.pm #2

Gotanda.pm Perl Technology Conference #2 - connpass

明日やるんでよかったら!

*1:ただ、

YAPC::Asia Tokyo 2014で個人スポンサーしつつボランティアスタッフしつつperl5 meta programmingについて喋りつつreject conでWorkmanについてLTしました

タイトルが長い。

YAPC::Asiaとは

ここを読むと良い。

概要 / ABOUT - YAPC::Asia Tokyo 2014

Perlのトーク殆ど無いじゃんという意見についての個人的な見解

いまどき色々な言語が開発に利用されるのは当たり前だし、特定の言語だけに絞るメリットはあまり無いのではって思う。
Perlを使ってい(る|た)人が興味が深い他言語/他分野の話をしてもPerlの人には面白いし役立つしべつに良いじゃないか。楽しみ方はいくらでもある。

YAPC::Asiaと私、あるいは何故ぼくは個人スポンサーになったか

YAPC::Asiaは2011年から毎年参加しているが、質が高く素晴らしいイベントであり、良いコミュニティになっていると思う。
僕は毎年ここで開発への情熱を貰っている。色々な技術に触れてわくわくする。エンジニアとしての将来のキャリアに希望が持てる。色々な人に来てもらいたい。
そういう素晴らしいイベントも、継続するためにはやはりお金が必要だと思う。個人で出来る事は少ないけれど、少しでも運営の助けになればと思い、小額ではあるが個人スポンサーをさせて頂いた。

ボランティアスタッフをやった

2012年から個人スポンサーはやらせて頂いていたが、今年からJPAYAPC運営委員会がYAPCの主催を行うということになり、 運営リーダーも牧さんから和田さんに変わるなど、新体制での運営となった。
いろいろ大変なこともあるかもしれないので少しでも力になれればと思い、コアスタッフとしてお手伝いすることも考えたが、 ボランティアスタッフすら経験していないのに勝手が分かるはずが無いと思い、まずはボランティアスタッフとしてお手伝いしていこうと思ったので参加を決めた。

作業としてはコアスタッフの人々が殆どの事を決めてくれていたので、殆ど手を動かすだけで済んだ。
具体的には、特典のTシャツを畳んだり、マイクを質問者のもとに届けたり、懇親会の参加者への案内をしたり、イベントホール外で飲食が無いよう*1grepしてblockしにかかる仕事とかをしていた。

今年はひたすらスタッフをやってみようと思っていたので、トークは殆ど聞かなかった。*2
ぼくは短大の頃に文化祭の主催をするなどしていたので、懐かしい気分になれた。一部でもYAPC::Asiaをつくることに貢献できることに喜びがあった。
終われば懇親会やHUBでいろんなひとと飲んで騒いでできたし、keynote sessionのときは仕事は全部終わっていたので生で見た。楽しかった。

トークについて

Perl5 meta programming - YAPC::Asia Tokyo 2014ということで、Perl5でメタプログラミングをするための基礎的な要素について初学者向けに実際のコードを交えつつ解説した。(スライドはリンク先に掲載している) UNIVERSALとAUTOLOADは隣り合わせにするつもりだったがスライドを整理しているうちにズレてしまっていたなど、いろいろ不手際はあったが、少しでもpure perlメタプログラミングをするための方法について伝われば幸いである。 本当はもう少し実践的な話もしたかったが、これは別の機会でも良いだろう。 なお、このトークのスケジュールはPerl入学式Githubの裏側の話Perlあるある、そして あやかNowという人気トークの裏にあったので、当日はそんなに人は来ないだろうと目論んでおり、非常に気を抜いてリラックスして発表していたが、最終的には立ち見で聴いて頂く方も出てくるなど思いのほか多くの人に来て頂き本当に有難い限りだった。ありがとうございました。 毎年YAPCに来るたびに英語力の無さを実感していたので、英語力を鍛える意味を込めつつ英語でスライドを書いたが、もう一つ海外ゲストの人との話のネタにしたいという思いもあった。しかし、案の定というかGithubの裏側の話に吸い込まれたようでそれは叶わなかった。来年までにはもうちょっと喋れるくらいの英語力とコミュ力を身に付けたい。

LTについて

reject conでLTをした。

karupanerura/Workman · GitHub

これのデモをひたすらやった感じ。酔っ払ってたのでだいぶテキトーだった。 デモをやる裏で動画をひたすら流していて最高にカオスだった。 自分でやっておいて自分で吹き出してしまってしょうもない感じだった。

WORKMAN_CM - YouTube

YAPC Ramen Challenge

きました。

やりました。

f:id:karupanerura:20140904202906j:plain

dump sql type name. · b57ce92 · karupanerura/p5-Teng · GitHub

総括

めっちゃ楽しかったし継続していきたいので来年も(ボランティア)?スタッフやりつつ参加したいです! 関係者の皆様おつかれさまでした!ありがとうございました!来年もやりましょう!(手伝います!

*1:諸事情でイベントホール以外では飲食の許可が得られていなかった

*2:良い同僚が代わりに聞いて、社内でフィードバック会を開いてくれる事になっていたので、それを聞きつつスライドやYoutubeで補完すればいいやとなった。

Job-Queue Workerの実装を管理するdaemon

Message Queueとか

だいたいみんな、Message QueueとしてGearmanとかQ4MとかResqueとかRabbitMQとかZeroMQとかまあたくさんあるけど、なにかを使っていると思う。 Perlの人だとQudoとかTheSchwartzとかをつかっている人も多いと思う。
でも、preforkなworkerを実装するとなるとSignal処理とかをちゃんとやるのが意外と難しい。 下の2つのスライドを読むと難しいんだなぁという事がなんとなくわかるとおもう。

graceful shutdownとかgraceful restartとかは欲しいし、max_reqs_per_child的なこともしたいし、時間が掛かり過ぎているjobはリトライして新しいworkerで処理させたいとかそういう要求がある。
そこで、そのへんが共通化されたプロダクトがあると良いのではないかと考えた。

Dainamoについて

なお、perlにおいては似ている既成のプロジェクトとしてDainamoというものがある。*1

これは以下のような事ができて、以下のようなメリットがある。 * Message Queueの種類をあまり考慮せずにコードが書ける * サーバー毎にworker数を設定し、Profileという単位でweightをかけてworker数をバランスする * サーバー毎のプロセス数をスペックに合わせて管理しやすい * Profileを1つのプロジェクトで複数つくって即処理したいものはweightを多めにするといったこともできる * 設定ファイルからProfile::Group(Profileをまとめたもの)を複数読み込み、全てのworkerを起動できる * 複数プロジェクトが同居するケースとかのセットアップが楽

これは業務で運用しているが、とても便利な反面、困ったこともいくつかでてきた。

  • dainamo毎にworker数を設定し、Profileという単位でweightをかけてworker数をバランスする
    • 実際にProfileに割り当てられるプロセス数が分かりにくい。
    • 他のProfileの影響を受けてProfileのworker数が変化するので複数Projectの同居などを慎重に検討しなければならない。
  • graceful_shutdown_timeout(default:10秒)を超えるとSIGKILLをworkerプロセスに送る
    • 容赦が無さすぎて失敗時に走らせたい処理とかが出来ない
  • Proc::Daemonでdaemonizeする機能がある
  • 3段階のforkとなっていてデバッグし辛い
    • master process -> manager process (profile毎に1つ) -> worker process (実際のjobを捌く)
    • (依存モジュールが古いサーバーとかだと)manager processだけゾンビってるとかが稀にある

Workmanについて

というわけで、もっとシンプルなものが欲しいと思っていた。そこで最近、Workman というプロジェクトを開始した。 Job-Queue Worker frameworkと銘打っている。だいたい以下のような事が出来る事を目標にしている。

あらゆるMessage Queueを同一のインターフェースで扱う事が出来る

  • 時代の変化で古いMessage Queueから新しいMessage Queueに移行するときとかにあまりめんどくさい事考えたくない。
  • 代わりに、一部のMessage Queueに特有の機能は使いにくくなるがそれは許容する。
  • Queueバインディングの仕様を満たすためのテストを提供してQueueバインディングを開発しやすくする。

単一のProfileに対して単一のServerを立てる

  • (dainamoと比較して)manager process単位でサーバーを立てる。
  • 複数建てたければ建てればいい

上に挙げた2つのスライドのノウハウを取り入れる

  • シグナルハンドリングの不具合とかを心配したくない。

graceful shutdown / graceful shutdown をサポートする

  • 1つだけ時間がかかっているjobがあったとしても他のworkerはすぐrestartして欲しい
  • かといっていつまでも死なないのも困るのでgraceful_shutdown_timeoutを超えたら強制終了させる

graceful_shutdown_timeoutを過ぎて強制終了させるときにSIGABRTを送る

  • worker内ではWorkman::Server::Exception::ForceKilledがthrowされるのでそれを好きにゴニョる
  • on_abortというhookがあるので再enqueueなどの処理を書いてあげる

max_reqs_per_childしてくれる

  • あたりまえのようにサポートしてほしい

daemonizeをサポートしない

テストを充実させる

  • 特にシグナル処理の安全性やWorkerのライフサイクルとかは手動で動作確認とか結構厳しいし自動化するべきである

CodeRefを簡単にworkerにしたい

  • ちょっとしたプロジェクトとかだとあると便利なはず。Amon2::Lite的な発想。syntax sugar用意してもいいかも。
  • 当然classとしてもタスクを定義出来るようにする。

実装状況

実は、だいたいコア部分はできている。 たまにテストがコケる事はあるが、sleepとか絡むので仕方ないのかなともおもう。 以下のような感じで書くともうだいたい動く。

サーバー側

use strict;
use warnings;
use utf8;

use Data::Dumper;
use Workman::Server;
use Workman::Server::Profile;
use Workman::Queue::Gearman;
use Workman::Task;

my $queue   = Workman::Queue::Gearman->new(job_servers => ['127.0.0.1:7003']);
my $profile = Workman::Server::Profile->new(max_workers => 10, queue => $queue);
$profile->set_task_loader(sub {
    my $set = shift;

    warn "[$$] register tasks...";
    $set->add(
        Workman::Task->new(Echo => sub {
            my $args = shift;
            warn Dumper $args;
            return $args;
        })
    );
    $set->add(
        Workman::Task->new(Abort => sub {
            my $args = shift;
            die Dumper $args;
            return;
        })
    );
    $set->add(
        Workman::Task->new(Busy => sub {
            my $args = shift;
            sleep 1 for 1..1000;
            return;
        })
    );
});

Workman::Server->new(profile => $profile)->run();

set_task_loaderはWorkerプロセスで実行されるのがミソ。
この中でモジュールのロードを行えばgraceful restartしたときでもTaskが再読み込みできるし、 メモリを節約したいなら先に読んでおいてCoWを効かせてメモリを節約することもできる。 重いモジュールは先に読ませておくとかそういう小手先の諸々ができる。

クライアント側

use strict;
use warnings;
use utf8;

use Workman::Client;
use Workman::Queue::Gearman;
use Try::Tiny;
use Data::Dumper;

my $queue   = Workman::Queue::Gearman->new(job_servers => ['127.0.0.1:7003']);
my $client = Workman::Client->new(queue => $queue);

$client->enqueue_background(Echo => { msg => 'hello' }) for 1..10000;

こんなかんじで、共通化のインターフェースでenqueueできる。 ドキュメンテーションとか、configファイルから読む機能とか、簡単にworker serverを立ち上げるためのコマンドとかはこれからという段階だが、なんとなく雰囲気は伝わるかなと思う。 どうだろうか?

*1:gearman限定であればMasayuki Matsuki / Gearman-Starter - search.cpan.orgがある

yasnippet 8.0をupgradeしたらdefaliasしたmajor-modeを考慮しなくなったっぽい

EmacsWiki: C Perl Modeを参考に以下のようなコードを埋め込んでいた。

(defalias 'perl-mode 'cperl-mode)

perl-modeでいろいろなsnippetを作ってcperl-modeで使っていたけど、
どうもyasnippetをupgradeしたら動かなくなってしまった模様。(tagも8.0までしか付いてなくてどこで動かなくなったのかはcommit追わないとわからなくてめんどくさくなった)
本来はcperl-modeでsnippetを作るべきだし、曖昧さを解消しているので歓迎するべき変更だとは思うけど、原因なかなか分からなくてハマった。

#dwangocpp に参加するためにLTしてきた

C++

僕は8年くらいC++を書いていなかった。今年の前半はC++11を学ぶことにしていたので少しづつ触ってはいたが、流石に8年ぶりとなるのでC++の基礎的な文法から学び直すこととなり、せいぜいhello worldに毛が生えた程度のものしか書いてこなかった。autoなどC++11で導入された主要な機能を試す程度だ。
よりC++11について深い理解を得るための機会と実装ネタが必要だと感じていたところだった。

ドワンゴC++勉強会 #1が開催される事を知った。
江添とでちまるとボレロ村上の闇の共演という珍妙なサブタイトルを理解するのに苦しんだが、
どうやらこの勉強会は、Cプリプロセッサメタプログラミングと、コンパイルメタプログラミングについて学ぶことが出来る勉強会のようだ。
僕もYAPC::Asia 2014perl 5 meta programmingというトークを応募している程度にはメタプログラミングには関心が深い。これは面白そうだ!と是非参加したくなった。
しかし、定員は既に埋まっており、補欠登録をしている人は100人を超えそうな人数でとても入れそうになかった。
また、諸般の事情により貧相なネットワーク環境しか無い僕がニコ生配信を見るのは厳しかった。
しかし、僕はLT枠には空きがある事を発見した。C++erは至る所で闇の軍団と呼ばれている程に恐れられていると聞いているので、発表する敷居が高いということだろうか。
たしかに、既に応募されているLTもC++をdeepに利用している人のLTである事は容易に分かるタイトルであった。
僕は悩んだが、これは絶好の機会であるので、行くべきである。最近はTOMLのparserをperl5で実装していたので、parserの実装をネタにすることにした。C99を含む他言語をある程度は理解しているC++初心者には適度な難易度であろう。また、他に並行して4つ程ライブラリをperl5で開発していたが、この難易度であれば恐らく問題はなかろうという目論見だった。
そうして、C++初心者書がC++11でparserを書いてみた話という話でLTを応募し、無事参加する事が出来た。主催の@EzoeRyouさん、株式会社ドワンゴさんのご厚意に感謝致します。

内容としては予告通りの内容で、資料も公開して頂いている。

LT資料にも書いているがconstexprの可能性は素晴らしいと思った。
inline関数と違い、コンパイル時に処理し、定数化出来るという違いは大きい。
parser generatorの実装もできるだろうと思った。実際、発表者の id:boleros 氏は既に bolero-MURAKAMI/Sprout · GitHub でSprout.Weedという機能として実装していると伺った。いずれ試してみたい。
Cプリプロセッサマクロでループを表現する手法など高度なマクロの利用方法も素晴らしかった。既に洗脳が解けたので真似する気はあまり無いが、実際、マクロを利用したい場面は多い。僕も学生の頃にTerm::ANSIColor相当の機能を持つマクロ群を書いた事があるし、最近ではAndroid NDKでpicohttpparserのbindingをC99で書いたときにロギングのために__func__などを仕込むマクロを書いた。やろうと思えばなんでも出来るという勇気を貰った。(小並感)
C++の歴史は既に何度か資料を読んでいたが、日本のC++ WGの近況については衝撃を受けた。海外のWGではどのように運営されているのか少し興味が湧いた。

さて、僕のLTの話だが肝心の実装は間に合ったのか?結果から言えば、実装は間に合わなかった。LTは実装の途中で便利だと思ったC++11の機能を紹介し、お茶を濁した。エンジニアとして成果物が一切無いという屈辱のLTをすることとなった。*1

LT資料*2

落ち葉拾いであるが、perl5もリファレンスカウント方式のGCなのでshared_ptrが持つ根本的な問題についてはある程度は理解しているつもりだ。その上で、素晴らしい機能だと思う。
相互includeについては、当然ながら宣言はhppに、実装はcppにという具合に分割しており、#pragma onceを付けていた。宣言の時点で相互includeが発生したが為に困ってしまった。*3

今年の前半の最終日である今日中には完成させたいと思っているが、現状の設計ではconstexprを使う場面はやはりなさそうである。いずれconstexprを使ってparserをコンパイル時に生成する事も試したい。具体的にはstrptime(3)や正規表現エンジンを実装できたら有用だと思っている。

最後に改めて、主催の@EzoeRyouさん、株式会社ドワンゴさんに感謝を申し上げます。ありがとうございました。

*1:その為か@EzoeRyouさんに本の虫: ドワンゴC++勉強会#1を開催したで実際のLTの内容に一切触れずお茶を濁すような気遣いをさせてしまったようだ。

*2:写真はイメージです

*3:後の試行錯誤により、pragma onceではなくifndefによって重複読み込みを回避すると再定義エラーは出なくなったが、結局定義に必要な型情報が得られずコンパイルエラーとなってしまった。

Macにエコーをかけて発言させるfunctionできたよー!

Mac OS Xに何故か入っているsayコマンドをご愛用の皆様、いかがお過ごしだろうか。
sayコマンドはmacに様々な言語で様々なワードを発言させる事ができ、
非常に便利なので公私共に多用している方も非常に多いと思う。

しかし、あまりに多用していると、なにか物足りない。
さりげなさすぎて気づけない。ライブ感が無い。など、
様々な悩みを抱えると思う。

そういうときはビールでも飲めばいいのだけれど、
仕事中にビールを飲むわけにはいかないし、
中にはビールが嫌いで日本酒しか飲まないような人も居るだろう。

そういう人のためにライブ感を提供する方法として、sayにエコーを掛ける方法を考えた。
お使いのmacでこれを.zshrcなどにいれておくといい。

function say-with-echo {
    for i in `seq 2 8`; do
        say "$@" &
        sleep 0.0$i
    done
    wait
}

すると、以下のようにsayコマンドと同様に使うだけで簡単にエコーをかけることができる。

say-with-echo x-video

如何だろうか?エコー感は感じられただろうか?スペックは足りているだろうか?
少しでもライブ感が高まれば本望だ。今日もビールがうまい

gitで新しくブランチを切るベストプラクティス

git

普段から普通にやっている方法です。

git fetch
git checkout -b $BRANCH_NAME origin/master
git push -u origin $BRANCH_NAME

git fetchでoriginを最新にして、origin/masterからブランチを切ります。
これで、プロジェクトの最新の状態からbranchを切る事が出来ます。
現在どのbranchに居るかを気にせずとも、branchを切る元を間違える事がないので安心です。
(例えばうっかり関係ないtopic branchから切ってしまう。といったことを気にしなくて良くなります。)

また、git push -u origin $BRANCH_NAMEすることにより、
リモートブランチがupstreamとして紐付く為、いちいちgit pull origin $BRANCH_NAMEとかしなくて良くなり、うっかり違うブランチをpullするというような事故を防げます。

というやりかたがベストかなーと思っていますがより良い方法があれば知りたいです。
追記: git 1.9未満ではこの上でgit config push.default upstreamにしておくと安全です。git config push.default currentだと最初のpushが若干楽になりますが、upstreamのがカタイです。お好きな方で。*1
なお、git 2.0からはgit config push.default simpleがデフォルトになったので、git 2.0使おうぜもアリだと思います。

*1:もちろんですが、globalに適用したいときは--globalオプションを付けましょう。