あーあーそのー

最近はshuyuheyと名乗ることが多いですが面倒なのでBLThunder1991のままにします。

ISUCON8予選に参加しました

ISUCON8に参加しました。参加は今年で3年連続3回目です。

ちなみに体調は最悪で、風邪を引いていたのもあり声がほとんど出ませんでした。チームメンバーの皆様にはご迷惑をかけてしまった。

isucon.net

結果は今年も予選落ちでした。うーん残念。着実に良くなっている感じはあるものの、次こそは予選突破したいなあ。

メンバー

実は毎年参加するチームが変わっています。今年は、Takuan-Oishiiさんと、hommahさんとのチームでした。

会社の同僚と、高専の同期というやや異色なチームでしたが、共通の知り合いである僕の心配をよそに、持ち前のコミュ力で普通に打ち解けてました。すげえな。

事前準備

キックオフの飲み会も含めて、合計3回ほど集まって練習しました。

基本はisucon7の感想戦を題材に、「どういう手順で何を調べたら我々はこのボトルネックに気づいて対処できたか」みたいなことを中心に考えました。なので、「ここまでこうやって設定している間に、誰がどういう風にレギュレーション理解しているといいのかな」とか「こういう手順でログを見たら、例えばここがおかしそうっていうことに気がつけるんじゃないかな」とか当日でも行動が再現できるレベルになるようにいろいろ考えられたことはすごく良かったように思いました。まあ予選落ちしたんだけど。

個人的には「当日の我々の知能レベルでは〜」のようなチーム内に独自の語彙というか言い回しが発生したのが面白かったです。よくあることだと思うんですが、チーム内に独自の共通言語が生まれるって、チームとしては割といい兆候な感じしませんか?しますよね?

事前練習までは、 1. 誰かがSSH鍵を配置して初期の設定完了させましょう 2. その間に残りの2人がレギュレーションとアプリをみてどんなものかを理解しましょう 3. その後、最初に手を付けるべきボトルネック2つぐらい出したら早速それに取り掛かることにしましょう

という感じのことを決めました。

あとは各々、手元のスクリプトをメンテしたり、僕はすばやく環境流し込んだり設定変更できるようにansibleのスクリプトを書いたりしていました。

当日

基本的には自分がやったこととか、関わったことしか覚えてないのでそれぐらいしか書きません。

当日は、事前準備で話していた1,2,3がそれぞれうまく実行できて、順調な滑り出しに見えました。

ただ、nginxしか頭になかった状態でのまさかのh2oで、どぎまぎしながらも設定ファイルをいろいろ変えてalpが使えるように変更した上で改善に取り組みました。alpに結構頼るつもりだったので、肝が冷えました。

終了後の感想チャットで「すぐnginxに変えた」っていうのを見て、確かにその手もあったなって思いましたw意外と焦っているもんだ。

最初は結構無駄なクエリ多いね、っていう話になってクエリを削る方向に行くかと思いきや、インデックス効いてないところを細々直したりしてました。今振り返るとあんまり筋がいいことしてないなあ。あとは、最初は1台構成だったものを2台に変えたり。

そんな感じで、今思えばほそぼそとした改善しかしておらず、初期スコアから全然変わらず。

最後の最後に、イベント取得のクエリがループ使っていて激重だったので、いい感じにチューニングしたら最後に1万ぐらいいきました。その時のチューニング結果のコミットというか動作確認の手順をミスって、泣きの1回ベンチの機会を失ってしまったのは素直に申し訳ないという気持ちでいっぱい。

あと、ちょくちょくペアで作業したりできていたのは個人的には楽しかったなあ。完全分業っていうのもISUCON的には戦略としてありだと思うけど、個人的にはワイワイやるのがやっぱり好きです。

感想

相変わらずISUCONはおもしれえなあっていう気持ちでいっぱいです。終わるたびに「はぁ〜」ってなるんですけど。

事前に色々考えたとしても、やっぱり当日は一歩及ばないっていうのを何度も繰り返している気がしていて、エンジニアとしてもまだまだだなあと思います。精進が必要だ。

あと、過去参加した中で一番ポータルサイトがリッチで声が出ました。嘘です。当日僕が声出ませんでした。でもびっくりしたのは本当です。 あんなに大変なイベントの運営をしてくださっているスタッフのみなさま、本当にありがとうございました。来年こそは予選を突破したい!

XP祭りに参加してきてTDDワイワイ会をやってきました

最近、何かしらのイベントに参加したらブログを書いたほうがいいのではないか?と思い始めたので、思いが続く限り書いてみようと思います。


TDDワイワイ会

XP祭り2018に参加してきました。初参加ながらTDDワイワイ会の出張ワークショップをしてきました。

tddyyx.connpass.com

基調講演がt_wadaさんの「テスト駆動開発の過去・現在・未来」だったというのもあり、これは割と人が来てくれるのでは?と期待しましたが、やっぱりたくさん来てくれて、ありがとうございました。プロジェクターを持ち寄ったかいがありました。

当日は僕がインストラクションを担当して、TDDとかモブプロの説明をしました。普段と変えたのは、最初に全体に対してTDDの説明をしたことと、1セッションで終わったこと。当日は「筋トレです!」っていうのを何度か言ったからか、参加者の皆さんは最初から筋トレスタンスで臨んでいたように思いました。次からも筋トレ筋トレ連呼しよう。

なんだかんだいつもと違うことが多かったからか、終始緊張をしていたような気がします。あんまり上手に振る舞えなかったなあとちょっとだけ反省しています。あと、普段から運営メンバーには説明がぶっきらぼーと言われることが多いのですが、今回も例にもれずぶっきらぼーだったみたいです。だんだんとぶっきらぼーにならないように改善します。次はうまくやるぞ!

あの場で少しでも面白いな〜と思ってくださった方がいれば、ぜひいつものワイワイ会にも参加してくれるととても嬉しいです。次回は、沖縄と東京での開催が決まっています。

tddyyx.connpass.com

tddyyx.connpass.com

全体の感想

実はワイワイ会で疲れてしまったからか(あとワイワイ会ちょっと長かったし)他のセッションをたくさん見れたわけじゃなかったので、来年参加することがあればもうちょっと余裕を持って振る舞いたいなあと思います。最後のLTはLTだな〜〜っていう感じで本当に面白かったです。語彙力がない。

懇親会では目ざとくスクリーンを見つけ、ワイワイを始めてしまいました。なんでかわからないけどたまたまプロジェクターを持ち歩いていたもので。本当に何から何まで楽しかったです。

スタッフの皆様お疲れ様でした、そしてありがとうございました!

Riot.jsでどんどん重なっていくモーダルの背景色を薄いまま保つ

最近Riot.jsを使った案件をやっていて、そこで困ったことをどう解決したかを整理しておく。

やりたかったこと

Webの表現ではよくあると思うのだけど、要素をクリックすると詳細な画面とかメッセージがポップアップっぽく表示されて、後ろが半透明の黒背景で覆われていて他の要素がクリックできないようになる、みたいな要件。

f:id:BLThunder1991:20180722123557p:plain

今回の要件では、モーダルの中で再び別の要素をクリックすると、それが更に重なってモーダルで表示されるというものになっていた。モーダルがどんどん重なっていく、ということ。

パーツ的には半透明の黒背景(以下、カバーって呼びます)とコンテンツという構成になっているので、何も考えずにカバーとコンテンツを束ねた、modal-content.tag のようなタグを作ってしまって、 mount して一番外側の divappendChild するという感じにしたかった。

ただ、ここで問題になってくるのはモーダルが重なれば重なるほど、カバーの色が濃くなっていってしまうということ。そんなたくさん重ねることもないだろうけど、モーダルが増える度に濃くなっていくというのは目に見えて明らかで、なんだかかっこ悪いなあということで対処方法を考えた。

f:id:BLThunder1991:20180722124152g:plain

トライしたこと

カバーをタグとして切り出してしまって、常にアプリケーション内にカバータグを1つだけ存在させるという方法をまず試した。

モーダルのタグが mount されたら、modal_open みたいなイベントを trigger してインクリメント、 unmount したら逆にデクリメントして、0になったらカバーを display: none させるみたいな実装。

一応これでもそれらしい動きをしたのだけど、今回の要件ではモーダルのサイズとか位置がいくつかパターンがあり、重なり方によっては一個奥で開かれているモーダルがカバーに覆われていないということが発生した。

まあ常に一番奥にカバーをおいているから当たり前なんだけど。

結局どうしたか

結局、 modal-content.tag 自身に cover というタグを内包させることにした。そして、モーダルが重なる度に、常に一番手前にある cover だけに色をつける、という方法をとった。

mount される度に自分が一番手前の cover かどうかを調べるっていう事も考えたけど、イマイチかなあと思ってやめた。自分の1つ手前のやつが消えたら色を変えるっていうのもやらなくてはならないので、 mount だけが色の決定のトリガーにはならない。どこかのカバーが消えたことと出たことに反応して自分の色を決定しなければいけない。

そのときに、Riot.jsの機能の一つである、Mixinというのを使ってcover タグのクラス変数みたいな使い方をしてみた。これが今回のエントリの本題になる。

MixInの中で、modal が閉じたり開いたりしたかどうかのイベントをlistenして、 自分が手前に来たら isDark みたいなフラグを立ててあげるようにした。

自分自身が unmount されるときは、 cover のリストからIDを取り除きつつ、閉じたことを trigger するという感じ。

import riot from 'riot';
const coverObservable = riot.observable();

let nextId = 0;
let ids = [];

const CoverEvent = {
  OPEN_MODAL: Symbol('OPEN_MODAL'),
  CLOSE_MODAL: Symbol('CLOSE_MODAL')
};


export default class CoverMixin {
  init() {
    this.coverId = ++nextId;
    ids.push(this.coverId);
    this.isDark = true;

    this.on('mount', () => {
      coverObservable.trigger(CoverEvent.OPEN_MODAL);
      coverObservable.on(CoverEvent.OPEN_MODAL, this.onOtherCoverOpen);
      coverObservable.on(CoverEvent.CLOSE_MODAL, this.onOtherCoverClose);
    });

    this.on('unmount', () => {
      _.remove(ids, (item) => { return item === this.coverId });
      coverObservable.off(CoverEvent.OPEN_MODAL, this.onOtherCoverOpen);
      coverObservable.off(CoverEvent.CLOSE_MODAL, this.onOtherCoverClose);
      coverObservable.trigger(CoverEvent.CLOSE_MODAL);
    });
  }

  onOtherCoverOpen() {
    this.toggle();
  }

  onOtherCoverClose() {
    this.toggle();
  }

  toggle() {
    if (_.last(ids) === this.coverId) {
      this.toDarken();
    } else {
      this.toLighten();
    }
  }

  toDarken() {
    this.isDark = true;
    this.update();
  }

  toLighten() {
    this.isDark = false;
    this.update();
  }
}

このMixinを cover タグに mixin しておけば、 mount されたときと unmount されたときに勝手に背景に色を付けるべきかどうかを判断してくれるという仕組みになっている。

イベントのやりとりもすべて、observable を中で持っているMixinの中で閉じているので、全体の observableに表示用のロジックが紛れ込むこともないので、結構良いのではと思っている。

cover をタグとして切り出さなくても、modal のタグにMixInすればいいんじゃないの、とかも思ったがただ後ろに半透明の黒背景出したいだけなのに毎回毎回カバー用のCSSとか処理を書くのもなあと思って切り出している。あと、 coverId っていうインスタンス変数的なものは追加されてしまうので、それを万が一上書きするような事があっても面倒だし。

全部のコードは以下。

github.com

まとめ

Riot.jsで困ったという話ではなくて、おそらく何を使っていても困ったと思うのだけど、Riot.jsではこういう風に表現できるかもねということを整理した。

本当は、CSSとかでシュッと処理できるのではないかとも思っているのだけれど、すぐには思いつかなかった。どこかで出会ったら書き直したほうが効率が良さそう。

PBL Summit2015に参加してきて、その時に感じたPBLのこと

PBL Summitとは

2015.pblsummit.jp

PBL Summitとは、全国のPBLを行っている学生を集めて、自分のプロジェクトや得た学びについて共有するイベントです。

基本的には学生主体で企画しているイベントです。なんと、今回で4回目の開催になりました。

参加者は学生の他、大学の先生方や、PBLを経験してきたOB、企業の方々や、人事の方々まで様々です。

PBLを経験してきた学生は、端的にいうとプチ社会人経験を積んできているので、即戦力として企業の方々から期待をされているようです。

そもそもPBLとは?

Project Based Learning の略です。Projectは、Problemになったりもします。

とある目的を解決するために、学生同士の少人数のチーム(1人の場合もあります)でプロジェクトを遂行する教育(学習)方法です。

所謂、座学のような教育とは異なり、目的を達成するために必要な知識を選びながら自学自習することで、より現実の問題に結びつけて技術や知識を吸収することができます。 また、教員や先生方も一方的に教えるだけでなく、一緒に考えながらチームのサポーターとしてプロジェクトに関わっていくので、より深く学生と関わることができます。

最近で言うと、ハッカソンなんかもPBLの一つの形態と言えるかもしれません。

一方で、問題解決に必要な、ジャストな技術や知識のみをピックアップしていくので、そのあたりに偏りが生じてしまったりするというデメリットもあるのではないかとおもいます。

しかしながら、そういうのはバランスが大事ですので、きっちり座学でベースとなる知識を得た上で、PBLで応用力や課題発見・解決力を鍛えるみたいなのがバランスが良いのではないでしょうか。

小難しいことを言いましたが、なにか企画があって、それを実現するためにチームなり1人なりで全力で取り組んで、その中でたくさんのことを学んだりしながら、最終的に色々な人から評価をもらえる素敵な学習方法です。

PBL Summitはどんなことをするのか

一日がかりのイベントですが、2015年は 以下の流れでした。

  1. PBL Summitとは
  2. PBLの事例共有
  3. OB・OGによるパネルディスカッション
  4. ブース発表
  5. 懇親会・表彰式

この中で、メインのイベントになるのが、ブース発表です。

ブース発表では、各大学から参加したチーム(もしくは個人)が、取り組んできたプロジェクトについてプレゼンテーションします。

私は、発表者でしたのであまり多くのプレゼンを聞くことが出来なかったのですが、プログラムをみるかぎりおもしろそうは発表がたくさんありました。全部聞くことが出来なかったのがほんとうに残念です。

あと、懇親会で先輩方とたくさんお会いできて楽しかったです。とある事情で、あまり話したことはなかったけどめちゃめちゃよく知っている先輩とお話出来たのはうれしかった。

そして、OB・OG賞頂けたのは驚きました。今まで、こういった発表会という場で賞を頂いたことはなかったので、全く予想していませんでした。ものすごく嬉しかったです。ありがとうございました。

PBL Summitを通して感じたPBLに対すること

PBLって本当に評価方法難しいんじゃないかと思います。

大学で開講するにせよ、こういったイベントで順位をつけるにせよ、ほとんどが人の主観で評価されているのではないかと思います。

人がやることですから、それに優劣がつくのは当然ですし、付けられたチームも、それに納得していると思います。

しかし、個人的にはもうちょっとフィードバックがあってもいいんじゃないかと思います。何が評価されたのか、何が足りなかったのか。

自分で気づけとかフィードバックするに値しないとか、もしかしたら色々思うところがあるのかもしれませんが、そういう教えが許されるのが、社会に出てプロジェクトを遂行するのとは異なる、PBLなのではないかと思います。

PBLのすごい所は、好きな様にチャレンジできて、いくらでも失敗できて、先生や先輩方の様々な視点からの知見を有効活用できるところにあるのではないかと思います。大学と企業のどちらからもサポートいただけるのって凄いことだと思います。

プロジェクトを進めながら、PDCAサイクルをたくさん回しているチームばかりだと思いますので、自分たちのプロジェクトで優れていたもの、足りなかったものを知ることが出来れば、次のステップに必ず生かせると思います。

ダメかどうかだけ教えてくれ!後は自分たちでカイゼンするぜ!って感じです。

まとめ

言いたいことを取り留めもなく書いてしまいましたが、この一年PBLを通してたくさんのことを学びました。

来年も、少し違う形でプロジェクトに取り組むので学びをしっかりと生かせたらと思います。

最後になりますが、PBLという学習形態を修士過程で学ぶことができる大学院がいくつかあります。

個人的には非常に刺激的で、学びの多いカリキュラムだと思いますので、とりわけチームでのシステム開発に興味のある大学生の皆さんは是非どうぞ!

詳しい話はいくらでもします。最後に意味ありげにURLだけ載せます!

以上です!

高度IT人材育成のための実践的ソフトウェア開発専修プログラム

4ヶ月前に作ったものをメンテしてみたら、いい感じの振り返りになった

事の発端

RoboCupSoccer SSL向けのnode.jsとWebブラウザを使ったグラフィカルクライアントssl_gclient_nodeを作りました. - あーあーそのー

確かこの頃は、Node.jsを初めて触り始めた辺りだった気がする。WebSocketが面白くて、何かいい利用方法はないか考えて、思いつきでこれを作った気がする。

それから4ヶ月位たって、メンテをしてみたら今とやり方が違うところがチラホラあったので、振り返りのついでに忘備録として残しておく。

パッケージの管理

一番最初においおいって思ったのが、パッケージの管理。READMEにはこれとこれのパッケージをnpm installしてねみたいな感じで書いてあった。

% npm install express ws websocket.io protobufjs

package.jsonに書いておいてあげれば

% npm install

一発で済む。それにREADME見なくても良い。npm install --save socket.ioとかはこの後に覚えたんだなあということを知った。

あとは、bootstrapやjQueryもそのままpublicディレクトリの下に突っ込んであっただけだったので、bower使うようにした。

conponentsディレクトリ以下にbowerでインストールされるように設定しておいて、app.jsに次のように書いておけば参照できる。

app.use(express.static(path.join(__dirname, 'components')));

module.exportsする

起動スクリプトに全ての処理が書かれていた。 まあこれはこれで、動くっちゃあ動くのだけれ土、メンテナンス性が悪そうだなと思ったので分割して、module.exportsした。

そのついでに、expressのgenerator使って大枠を生成して、そこに移し替えるという形にした。

起動時の処理を./bin/wwwに書いて、app.jsにはサーバの設定処理を書いた。それ以外の処理(ブロードキャストパケットを受け取って処理するロジック)は別のファイルに分けることで、処理のロジックと設定のロジックを分けたつもり。

WebsocketからSocket.ioへ

単純に最近良く使っているのがSocket.ioだったので、そちらに合わせた形に。書いていて思ったけれど、どのライブラリを使うかみたいな判断はこういう軽いものに対してもちゃんと考えた方がいいななんて。

まあでも、Socket.ioのほうが、動作対象が広めみたいなので、コンセプト的にはSocket.ioの方があってるかな。

まとめ

やってみて、色々考え方とかやり方が変わっていることに気づいた。

ここはもうちょっとこうしたいなみたいなところはもっとたくさんあるので、また気が向いたらいろいろいじるつもりです。

そうなったらまた、今回みたいな発見があるのかもなあ。

発表する順番とかを決めるツールを作った

事の発端

担当者とか発表者とか決めるためのルーレットみたいなものを作った - あーあーそのー

結構前に作ったこれが、チーム内とか大学のコースでなんか決めるときにそこそこ使われている。

一方で、順番決める機能が欲しいみたいな意見もあって、それはいつかやりたいなと思ってたので思い切って別のツールとして作ってみた。

どうせなにか作るなら、何かの勉強もついでにやろうということで、今まで使ったことのなかった、Yeomanとかgulpとかも使ってみようということで、使ってみた。

The web's scaffolding tool for modern webapps | Yeoman

gulp.js - the streaming build system

出来たもの

出来たものは、これです。

roulette_seq

YeomanがデフォルトでBootstrapとか入れてくれるし、HTMLのテンプレートも用意してくれるので、自分としてはBodyのなかをガリガリ書くだけって感じでめっちゃ楽だった。

ファイル書き換えた瞬間にページがリフレッシュされるから、エディタからカーソル話した瞬間に即動作テストできるのはめっちゃ良い。

まあ、一回色々な仕組みに気がつかないでHTMLの中身前消しして自分で一生懸命書いてて、gulp buildしたらScriptとかStyleとかなにも出なくてめっちゃ苦戦した。HTMLにコメントされてる文字列使って、distに書き込む内容決めてるんですね……。勉強になった。

ついでにやってみたこと

前回に引き続き今回も、gh-pagesでツールを公開している。けど、前回と違って今回はYeomanでディレクトリ構成とか自動生成しているので、前回みたいにそのままgh-pagesにブランチを切ればOKというわけにはいかなかった。

一番最初は、gh-pagesをまっさらにしてdistからまるっとコピーしようと思ったんだけど、なんかスマートじゃないなって思って探したら、以下の記事に辿り着いた。

Generate GitHub pages in a submodule — blindgaenger

この記事の場合は、WebSiteを生成するツールを使っていたけど、masterのとあるディレクトリをgh-pagesのsubmoduleにして更新を半自動にするっていうのはgulpにもマッチしそうだと思って、試してみた。

masterのdistディレクトリを、gh-pagesのsubmoduleにして、gulp buildしたら、上書きされるようにした。

上書きされたら、cd distして、git addしてgit commitしてgit push origin gh-pagesすれば、更新される。

その辺りもついでに自動化出来ればよかったんだけど、そこはまた今度の機会にやることにする。

mixi ScrapChallengeに参加してきました

事の発端

Scrap Challenge 2014 | 株式会社ミクシィ 学生向けエンジニアイベント

なにやら合法的にクラッキング的なことを実践しながら学べるイベントが有るということで、参加してきました。

イベントの内容

午前中は、脆弱性やその対策などに関するレクチャーでした。例えばXSSとかCSRFとかSQLインジェクションがどういう脆弱性で、どうしてそれが起こってしまって、どうすれば対策できるのかなどのお話をしていただきました。

この辺りは、普段の授業で(結構最近ですけど)ちらっと聞いたこともあったのですが、リアリティあふれる事例込みでお話して頂けたのでより「あ、やべえなこれ」感が出ました。

午後からは、mixiっぽいSNSにチーム対抗で攻撃を仕掛けます。幾つか問題が出されるので、それにそって自分で工夫しながら攻撃を仕掛けるといった形です。一番攻撃できたチームが優勝です。

難易度に関しては結構バランスが良くて、時間がたつのはあっという間でした。全問解けるチームは数年やってて1か2チームだとか。個人的な得意不得意もなんとなく見えてきて、「あ、僕こういう攻撃ならすらすら考えられそうだな」みたいな。

問題や回答については内緒です。1月にもあるそうなので、是非参加して確かめてみてください。

感想とか

なにより合法的に攻撃できるのが楽しい。いや、これ良くないんですけど(笑)実際セキュリティとか、脆弱性って「結局どうなったらヤバイの?」みたいなところを言葉で説明されてもなんとなくわかりにくいような気がしています。実際に攻撃受けるとか、あるいは自分が攻撃して、「嗚呼、なるほど確かにヤバイな」みたいなところを肌で感じることが出来たのは非常に貴重な経験でした。

ちなみに休憩時間に、自分がPBLで取り組んでいたプロダクト(ローカルサーバ)に対してもちょっと攻撃してみましたが意外とガード堅かったです。さすがRails(?)