ESM アジャイル事業部 開発者ブログ

永和システムマネジメント アジャイル事業部の開発者ブログです。

事業部メンバーで合宿に行って、モブプログラミングを体験しました。

7/6(木)~7(金)に事業部メンバーで合宿に行ってきました。 アジャイル事業部では毎年1~2回、合宿を計画してメンバーが参加します。 過去には「チームビルディング」や「自分たちが大切にしていることを探す」などのテーマでも実施しました。 ここ数回は、「(主に業務で使用しない)技術で遊ぼう」ということで、「IoTハッカソン」や「日々の生活を便利に」をテーマにプログラミングや電子工作にチャレンジしています。

f:id:m_pixy:20170707073218j:plain

今回は以下のコンテンツで一泊二日を過ごしました。

  • オフラインリアルタイムどう書く
  • 事業部計画書を読む会
  • バーベキュー
  • モブプログラミング

今回の会場は、桐花園という神奈川県のキャンプ場でした。 (http://tokaen.jp/) 私たちの合宿では初使用でした。本当に普通のキャンプ場なのですが、センター棟と呼ばれる建物は合宿所のような作りで、広い作業場所兼宴会場となった和室は使い勝手が良かったです。開発合宿先を探している方には候補のひとつとしていただければと思います。

オフラインリアルタイムどう書く

オフラインリアルタイムどう書く(以下「どう書く」)は、与えられたお題に対して1時間かけて解くイベントで、パブリックな場所では 横浜へなちょこプログラミング勉強会 | Doorkeeper で開催されています。 アジャイル事業部では、このイベントに会場提供をしていたり、社内勉強会として開催したりしています。 今回の問題は、「6×6のマスを、指示された通りに移動して、移動した終点の文字を出力する」というお題でした。(当日のお題はこちら 第37期合宿 どう書く 問題 · GitHub

f:id:m_pixy:20170711193442j:plain

若いメンバーがどんどん解答していく中、普段あまりコードを書いていない僕も必死でプログラミングしたものの、時間切れでした。 みんなが解答を出した後は、それぞれが自分の考え方や書いたコードを発表して、「あー、そんなやり方があったかー」と悔しい思いをしたり、「これはもっとうまくやれるはず」と上から目線になってみたり、楽しい時間を過ごしました。

事業部計画書を読む会

8月から新しい期が始まるのに合わせて、できたてホヤホヤの事業部計画書をみんなで読みました。なかなか普段は意識しない計画書の内容について、ああだこうだと意見を交わす貴重な時間でした。

バーベキュー

1日目の夕食は、バーベキュー。火を起こして、用意してもらった肉や野菜、焼きそばを焼いて、みんなで食べました。お酒を飲みながらということもあり、いろいろな場所で話が盛り上がっていました。

モブプログラミング

2日目は朝からモブプログラミング。2グループに分かれて、与えられたお題に沿ったソフトウェアを作ります。普段仕事で使っているRubyや、使える人が多いJavaを禁止して、あまり使ったことがない言語から選択します。さらには普段よく使うHerokuや、AWSなどは使用しないというルールで開始しました。 1チームはScala、もう1チームはPythonを選択しました。そして両チームともインフラはほぼ初挑戦の人が多かったGCPを選択。

f:id:m_pixy:20170707135802j:plain

両チームとも苦戦しながらも、みんなでシンタックスを調べたり推測したりしつつ、少しずつものが出来上がっていく過程を楽しみました。個人的にはPythonはまったく書いたことがなかったのですが、ドキュメントを調べながら初挑戦の言語で動作させていくことを楽しめました。また、「この人はこういう状況にハマった時にこういう試し方をして確認するんだなー」等、同僚の行動を見ることができたのも面白い体験でした。

RedDotRubyConf 2017 に行ってきました

こんにちは@color_boxです。 6/22 - 6/23 にシンガポールで開催されたRedDotRubyConf 2017に参加してきました。 今日はカンファレンスに参加した感想を書こうと思います。

f:id:color_box22:20170622091959j:plain:w480

シンガポール

今回の参加者は @muryoimpl@yucao24hours@color_box、 引率の @kakutani の計4名です。

今回の旅費はアジャイル事業部から出してもらっています。🙏🏼

本編

実際の発表で使用されたビデオやスライドはこちらです。

弊社顧問の@a_matsudaRubyの新機能とRailsに関する基調講演Rubyのしくみをベースにネットミームとイラストを交えておもしろおかしく紹介した発表巨大なRailsのアプリケーションの開発速度をいかに維持するかの工夫に関する発表 など、興味深い発表が盛り沢山でした。

個人的に興味深かったのは、巨大なRailsのアプリケーションの開発速度をいかに維持するかの工夫に関する発表でした。 Shopify のような大きいサービスになると開発のためのオーバヘッドは決して無視できない大きさになります。 それを減らすための工夫が重要になるという点が興味深かったです。

英語

すべての発表は英語で行われたため、聞き取り能力が試される時間でもありました。

スライドに情報が多いタイプの発表は聞き取りができなくてもかろうじて意味は読み取れます。 しかし、スライドに情報が少ないタイプの発表だと聞き取りができないと読み取れる意味が少なかったり間違っていたりするため、その点は苦労します。

また、他のエンジニアの方と話すときも基本は英語です。 なので、ここでは聞き取り能力だけでなく、発言する能力も試されます。

英語のヒヤリングやコミュニケーションに今後の課題があると感じました。

その他

食事

カンファレンス参加中は朝食とランチが提供されます。 東南アジア特有の料理が多くどれも美味しかったです。

f:id:color_box22:20170623091151j:plain:w480

まとめ

国内でのカンファレンスとは雰囲気が少々異なるカンファレンスでした。 英語などの障壁もありますが、学べるものは多かったです。 何より、今回シンガポール渡航したことで海外へ行く心理的なハードルが下がりました。 今後も機会があれば参加してみようと思います。

最後になりましたが、引率をしてくださった弊社顧問の角谷さん。 シンガポールへの渡航費、宿泊費を負担してくれた弊社アジャイル事業部に深くお礼申し上げます。

ありがとうございました。

LTをしている方達を見て、次は自分もやってみようと思う @color_box でした。

それでは

GentooInstallBattle on ThinkPad X1 Carbon 5th Generation

こんにちは、hibariya です。さいきん会社支給のマシンを買い替え、ThinkPad X240 から X1 Carbon (5th) になりました。Gentoo Linux のインストールをするのは約2年ぶりです。いつも通りちょっと大変でしたが、無事に新しいマシンから記事を書ける状態になりました。

さっそく次回のインストールへの備えも兼ねて今回の記録を残しておきたいと思います。だいたいは公式のハンドブック過去に残していた記録を参考にしてさくさく進んだので、ここでは前回と違うところ、特にカーネル周りの設定をどうやったかについて書きます。

カーネルのビルド

前回までは、関係がありそうな設定はひとまず有効にしておくという割とおおざっぱなやり方でビルドしていましたが、本来何が必要だったのかが曖昧になっている状態というのは少し不安です。今回はもう少し丁寧に、なるべく必要なものに絞ることにしました。しかしカーネルの設定をちゃんとやろうとすると、どうしてもちょっとめんどうで難しそうな印象があります。

Manually configuring a kernel is often seen as the most difficult procedure a Linux user ever has to perform. Nothing is less true - after configuring a couple of kernels no-one even remembers that it was difficult ;)

Gentoo Linux amd64 Handbook: Installing Gentoo - Gentoo Wiki

実際には、何が必要かは少し調べるとだいたいあたりがつきますし、手数は多いものの設定の項目自体は (思っていたよりは) それほど多くありませんでした。

おおまかな流れとしては、まず make defconfig でデフォルトの設定を生成し、そのうえで必要そうなものを有効にしていきます。

flaggie sys-kernel/gentoo-sources +symlink
emerge gentoo-sources
cd /usr/src/linux
make defconfig
make menuconfig # 追加で必要そうなものを設定
make -j3 && make install && make modules_install

以下のドキュメントと、 lspci lsusb dmesg などの出力をあわせて参考にしつつ、内蔵デバイスのサポートを追加していきました。

最終的には、デフォルトの設定に加え次のような設定を有効にしました。ストレージの接続規格が NVM Express になっているので、それも有効にしています。

  • NVMe
    • NVM Express block device (BLK_DEV_NVME)
  • Network
    • Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) (IWLWIFI)
    • Intel Wireless WiFi MVM Firmware support (IWLMVM)
  • USB
    • Battery level reporting for HID devices (HID_BATTERY_STRENGTH)
    • Lenovo / ThinkPad devices (HID_LENOVO)
    • xHCI HCD (USB 3.0) support (XHCI_HCD)
    • Generic xHCI driver for a platform device (USB_XHCI_PLATFORM)
  • UEFI
  • Systemd まわり
    • systemd (GENTOO_LINUX_INIT_SYSTEMD)
    • Built-in kernel command string (CMDLINE) root=/dev/nvme0n1p3 init=/usr/lib/systemd/systemd psmouse.proto=imps
  • 音の入出力
    • Enable generic HD-audio codec parser (SND_HDA_GENERIC)
  • 内蔵カメラ
    • USB Video Class (UVC) (USB_VIDEO_CLASS)
  • ACPI

ひとまず GUI やインターネットが使えるようになったところで、この段階ではまだ Docker や VirtualBox などは入っていません。とはいえ、ここまでくればだいたい山場は越えたと言ってよさそうです。

落とし穴

上記ではカーネルパラメータとして psmouse.proto=imps を渡しています。これは Systemd とは関係なく、ポインティングデバイスがうまく動作しない問題の workaround です。UEFI firmware をアップデートする、Track Point を無効にするなど色々やってみましたが、手元のマシンではこの方法に落ち着きました。

ThinkPad X1 Carbon 5th Gen

ロケールをデフォルト (ISO-8859-1) のままにしていたら gnome-terminal が立ち上がらず、ちょっとハマりました。en_US.UTF-8 に変更して無事立ち上がりました。

その他

cpuid2cpuflags で CPU の最適化フラグを設定しました。

$ emerge app-portage/cpuid2cpuflags
$ cpuinfo2cpuflags-x86
CPU_FLAGS_X86="aes avx avx2 fma3 mmx mmxext popcnt sse sse2 sse3 sse4_1 sse4_2 ssse3"
$ cpuinfo2cpuflags-x86 >> /etc/portage/make.conf

おわりに

これまで割と適当にやっていたカーネルの設定についてやったことを書きました。よりよいやり方があればぜひ教えてください。

graphql-batch でバックエンドへのクエリを減らす

こんにちは、hibariya です。最近 ミートアップ が開催されるなど、GraphQL が静かに注目を集めていますね。GraphQL は Web API で使えるクエリ言語です。GraphQL 自体は特定のデータベースに依存しないため、RDBMS を使ったアプリケーションで採用することも可能です。PostgreSQL を使う Idobata でも GraphQL の Public API を公開しました。GraphQL 自体がどういうものかについては、graphql.org や以下の資料が参考になるのではないかと思います。

GraphQL でサーバ側を実装するときに起こりがちな問題として、クライアントから投げられるクエリによっては RDBMS への問合せが大量に発生してしまうというものがあります。今回は RubyRails でこのような問題に対処する方法について書きます。

チャットアプリの例を使いたいと思います。次の例は、ログインしているユーザ (viewer) が閲覧できる発言 (message) の一覧と各発言が投稿されたチャットルーム (room) の名前を取得する GraphQL のクエリです。それぞれ、一対一に対応する Active Record のモデルがあるとします。

query {
  viewer {
    # a message belongs to a room
    messages(first: 10) {
      body
      room { name } # message.room による問合せが最大10回
    } } }

特に工夫をしなければ、room { name } を取得する SQL は message の数だけ DB に投げられてしまいます。Ruby で表現すると次のようなイメージです。

Message.readable_by(current_user).limit(10).map {|message|
  # message.room が10回
  {body: message.body, room: {name: message.room.name}}
}

次の例は、あるチャットルーム (room) のメンバー (member) 一覧を取得する例です。

query {
  viewer {
    # a chat room has many members
    rooms(first: 10) {
      name
      members { name } # room.members による問合せが10回
    } } }

この場合も members { name } を取得するSQLが room の数だけ発行されてしまいます。

Room.readable_by(current_user).limit(10).map {|room|
  # room.members が10回
  {name: room.name, members: room.members.map {|member| {name: member.name} }
}

このような問題の解決方法のひとつとして、graphql.org の Best Practices では複数の問合せをひとつにまとめる Batching を挙げています。これの Ruby での実装としては graphql-batch という gem があります。graphql-batch は特定の DB やライブラリに依存しておらず、問い合わせをする部分も自分で実装できるため、比較的導入しやすい gem です。さっそく使ってみましょう。

graphql-batch を使ってみる

graphql-batch を使うと「ひとつひとつの問合せをいったん Promise として保留にしておき、あとでまとめて問合せ」られるようになります。この「まとめて問合せ」を行なう処理は Loader というかたちでアプリケーション側に実装します。

class RecordLoader < GraphQL::Batch::Loader
  def initialize(model_class)
    @model_class = model_class
  end

  def perform(ids)
    @model_class.where(id: ids).each do |record|
      fulfill record.id, record
    end

    ids.each do |id|
      fulfill id, nil unless fulfilled?(id)
    end
  end
end

RecordLoader#perform(ids) が実際に問合せを行なう部分です。これを使って、message が投稿された room (message.room) を取得するための resolver を次のように書けます。

MessageType = GraphQL::ObjectType.define do
  field :body, !String
  field :room, !RoomType do
    resolve -> (message, args, ctx) {
      # message.room の代わりに:
      RecordLoader.for(Room).load(message.room_id) # => a Promise
    }
  end
end

RecordLoader.for(Room).load(…) は実際の関連 (room) ではなく Promise を返します。ここではいったん Promise を返しておき、必要になった時点でまとめて問合せて fulfill するというわけです。

RecordLoader#for は引数ごとに RecordLoader インスタンスをひとつだけ作って返します。例えば RecordLoader.for(Room)RecordLoader.for(Message) では違う Loader オブジェクトが返りますが、同じ引数で2回呼んだときは前回と同じものが返ってきます。RecordLoader#new の引数は、問合せをどういった単位でまとめたいかによって決まると言えるでしょう。

RecordLoader#load には、ロードする対象を一意に特定するためのキーを渡します。この例では Active Record のプライマリキー (id) を渡しています。ここで渡した id は各 Promise を解決するタイミングで RecordLoader#perform に ids としてまとめて渡されます。このようにして、元々は複数の message.room だったものを Room.where(id: ids) というひとつの問合せにできます。

Loader の応用例

Loader の実装としては、上記の RecordLoader の他に ActiveRecord::Associations::Preloader と組み合わせるというやり方も考えられます。これによって Active Record の eager loading の仕組みを利用できます。

class HasManyAssociationLoader < GraphQL::Batch::Loader
  def initialize(_model_class, association)
    @association = association
  end

  def perform(owners)
    ActiveRecord::Associations::Preloader.new.preload owners, @association

    owners.each do |owner|
      fulfill owner, owner.public_send(@association).to_a
    end
  end
end

この Loader を has_many な関連である room.members の読み込みに使うことで、複数の room.members をひとつの Preload に置き換えられます。

RoomType = GraphQL::ObjectType.define do
  field :name, !String
  field :members, [!UserType] do
    resolve -> (room, args, ctx) {
      # room.members の代わりに:
      HasManyAssociationLoader.for(Room, :members).load(room) # => a Promise
    }
  end
end

注意点として、この方法は関連を一気に読み込んでしまうため、数の多い has many な関連の一部だけがほしいような場合には不要なレコードを大量に読み込んでしまう可能性があります。

また、冒頭でも述べましたが graphql-batch 自体は特定の DB やライブラリに依存していないので Active Record 以外にも応用できます。例えば、Rails のキャッシュを fetch ではなく fetch_multi でまとめて取得する Loader をつくり、バックエンドとのラウンドトリップを抑えるという使い方もできるでしょう。

おわりに

主に graphql-batch を使ってバックエンドへの問合せを減らす方法について、基本的なものではありますが、いくつか例を紹介しました。Ruby で GraphQL を触りはじめた人たちの参考になれば幸いです。

今回のような N+1 Query を解決する際のよくあるやり方としては、Rails アプリであれば Active Record の includeseager_load などを用いた、いわゆる Eager Loading を用いることだと思います。同じことを GraphQL で行なう gem としては graphql-query-resolver があります。この gem は ActiveRecord::Associations::Preloader を使って、クエリに含まれる関連をまとめて問合せてくれるようです。ただ、試しに少し使ってみたところ、数の多い has_many な関連を扱う場合やクエリのカスタマイズをしたい場合にはすこし工夫が必要そうな印象でした。もしも新たな情報が得られたら、またどこかで共有できればと思います。

改訂2版 パーフェクトRubyが出版されました

こんにちは。takkanm です。

本日 2017/05/17 は、弊社メンバーが関わっている書籍パーフェクト Ruby の改訂2版の発売日です。

パーフェクト Ruby は、Ruby に関する内容を言語仕様から、メジャーなライブラリまでを網羅することを目的とされた書籍です。 弊社からは、私と hibariya が執筆に携わっています。

初版は 2013 年に発売されたので、今回は 4 年ぶりの改定となります。 改定内容としては、初版時にターゲットとした Ruby のバージョンである 2.0 から、昨年末にリリースされた 2.4 までの差分をアップデートしました。対象バージョンのアップデートにおいては追加されたメソッドが追加されているのはもちろん、初版から大きく仕様の変わった refinements についての内容を大きくリライトしました。 さらに、初版が発売後に対象を Rails に絞ったパーフェクト Rails が出版されたということもあり、Web 関連の章が削られ、代わりに test-unit を使ったテストの章が追加しています。 このように追加要素も多いので、初版を持っている方にもオススメです。

紙の本は、Amazon やお近くの書店でお求めいただけると思いますし、GihyoDigitalPublishing では PDF でもお買い求めいただけます。

みなさんが Ruby でプログラムを書く際の良きお供になれば幸いです。

併せて読みたい

AgileJapan2017とワークショップに参加して、モダンアジャイルについて考えてきました

こんにちは、平田です。 少し前の話になりますが、AgileJapan2017と、翌日に開催されたモダンアジャイルワークショップに参加してきました。

www.agilejapan.org

agilejapan.org

モダンアジャイルについて

アジャイルソフトウェア開発宣言が出されてから15年以上が経ち、その現代的な解釈を「モダンアジャイル」として Joshua Kerievsky さんがまとめました。 モダンアジャイルの4つの原則は以下の通りです。

  • Make people awesome(人々を最高に輝かせる)
  • Make safety a prerequisite(安全を必須条件にする)
  • Experiment and learn rapidly(高速に実験&学習する)
  • Deliver value continuously(継続的に価値を届ける)

それぞれの内容については、いろいろなブログ記事も出ているので、ググっていただくとして、私からは基調講演とワークショップの2日間で感じたことをいくつか紹介します。

f:id:m_pixy:20170414181136j:plain

安全

4つの原則のうちのひとつに含まれる「安全」については、基調講演の中でもかなり多くの時間を割いていました。安全は優先順位が一番高いというわけではなく、必須の前提条件であるという考え方です。Googleでの心理的安全の重要さが分かった調査結果は有名ですが、他にもメンバーが様々な挑戦をするために安全なミーティングをやるための5箇条など様々なエピソードが紹介されました。

面白かったのは、Slackが非アクティブなユーザーがいることを伝えてきて、そのユーザーの分の料金を返金してくれたというエピソードでした。Slackというサービスは顧客の予算を守ってくれるという安心感をくれたという話で、開発メンバーにかぎらず、関わるすべての人の安全のために行動するということの重要性が伝わりました。

アウトプットではなくアウトカム(成果)に着目する

良いソフトウェアを作ろう、動作するソフトウェアを作ろうと考えるのではなく、それらが生み出す「成果」に着目しようということです。 ワークショップの中で「継続的に価値を届ける」ことをチームで改善していくために、計測すべき指標を考えようというものがありました。私たちのチームでは、「継続的にチームがソフトウェアをリリースすることが重要である」と考え、たとえば日単位での本番リリース数などを数えようとしていたのですが、Joshuaさんから「それは成果なのか?」という問いかけがありました。

「包括的なドキュメントよりも動くソフトウェアを」というアジャイルマニフェストの先にある、「ソフトウェアがもたらす成果」に着目することの重要性に気づくことができました。

「要求」を「実験」として捉える

アジャイルマニフェストの「変化に対応する」というのは受動的である。高速に実験し、高速に学習するために、顧客からの要求さえも実験であると捉え、早く失敗していこうという話がありました。

まとめ

今回の基調講演や、Agile2016での基調講演(リンク)では、モダンアジャイルの4つの原則について、考えられた背景等をエピソードを交えて紹介されていました。実際のプロセスについては、チームで考えていくべきという考え方であると理解しましたが、ワークショップの中で紹介されたプロセスでは、クリックテストやセットベース設計など、UXやリーン、DevOpsなどの文脈で語られることの多いプラクティスが紹介されていました。モダンアジャイルの原則は、これらの考え方やプラクティスを束ねる概念として利用してみるのもの面白いと感じました。

最後に

さて、今回のAgileJapan2017には、2016年に引き続いて、永和システムマネジメントはサテライトスポンサーとして協力をしています。 聞きなれないスポンサーですが、これは全国で開催されるAgileJapanの地方サテライトに、永和のメンバーが講演や運営のサポートとして参加するというスポンサーです。

身近でアジャイルの話が聞ける、議論できるチャンスですので、ぜひお近くの方は参加いただければと思います。弊社のメンバーも各地のサテライトに参加します!

私も直近では、栃木サテライトにお邪魔する予定です。皆様とお会いできるのを楽しみにしています!

www.agilejapan.org

Repro様とExtreme Fish Bowl を開催しました

こんにちは @color_box です。

2017/01/27 に Repro のエンジニアの皆様と Extreme Fish Bowlを開催したので、それに関する報告をします。


Extreme Fish Bowl

Extreme Fish Bowlとは、皆に見られながらペアプログラミングをするというものです。 その場にいる全員の中でペアを組み、1台のマシンを使ってかわるがわるペアプログラミングをしていきます。 ペアプログラミングをしていない他の参加者は、観戦にまわります。

5分を1ターンとして、ターン終了時にドライバーが抜け、ナビゲータがドライバになります、ナビゲータは他の参加者の中から一人入って次のターンに進みます。 そうやってナビゲータとドライバを一人ずつ交代しながらプログラミングを進めていくのがExtreme Fish Bowlです。

プログラミングの対象となるお題は事前に与えられており、お題を解くようなコードを全員で考えていきます。 作業風景は常にスクリーンに映し出されており、会場にいる全員に共有されます。 もちろん手を動かしていない他の参加者も、ペアプログラミングをしていえる二人に温かい野次のような声援を飛ばして構いません。

f:id:color_box22:20170127204439j:plain


当日のコード

当日書かれたコードは下記リポジトリにおいてあります。 github.com

続きを読む