読者です 読者をやめる 読者になる 読者になる

esaの更新通知を適切なチャンネルに振り分ける

こんにちは、mzpです。

先日、Misocaオフィスでesa meetupを開催しました。当日お越しいただいた方々ありがとうございます。 会の様子は以下のような記事にまとめられています。

f:id:mzp:20170126111947j:plain

最近、esaの更新通知を1つのチャンネルに流すのではなく、適切なチャンネルに振り分けるようにしたのでその話を書きたいと思います。

これまでのMisoca

これまでesaの更新通知をSlackの単一のチャンネル(#now_esa)に流していましたが、日報のような更新頻度の高いものの通知で、更新頻度の低い文書の通知が埋もれてしまうという問題がありました。

初期: 標準のWebhook

標準のWebhookの設定を変更して「日報」カテゴリ以下の更新を #now_nippou チャンネルに通知するようにしました。

f:id:mzp:20170126154224p:plain

これにより、日報の更新通知と、それ以外の記事の更新通知が分かれるため、日報がとても読みやすくなりました。 他のメンバーにもかなり好評でした。

f:id:mzp:20170126172149p:plain

同じように、「プロジェクト/なんとか」カテゴリ以下の更新はこのチャンネル、「プロジェクト/かんとか」カテゴリ以下の更新はこのチャンネルという設定をどんどん増やしていきました。こちらもなかなか好評でした。

f:id:mzp:20170126173847p:plain

問題点

しかし通知先が増えるにつれて、以下のような問題が生じました。

  • 「他の箇所で通知してないやつ」という設定ができないので、通知が二重で届くことがある。*1
  • 通知先のチャンネルを変えるには個別にincomming webhookを作る必要があるため、大量のincomming webhookを管理しないといけない。

通知が二重で届くことについては、他のメンバーからも不満がで始めました。

f:id:mzp:20170126173035p:plain

解決策: AWS Lambda

じゃあ自分でやるか、ということでAWS lambdaでルーティングする仕組みを作りました。 名前は伝書鳩からの連想でhatoにしました。

https://github.com/mzp/hato

hatoを使うと、以下のようなことができるようになります。

  • どのパターンをどのチャンネルに通知するかを一箇所で設定できる
  • Slackのincomming webhookは1つあればよい
  • 一致するパターンがあった場合はそこで処理をやめるため、重複して通知されない

今のところ以下のような設定にしています。

module.exports = [
  // 日報は更新量が多いので専用のチャンネルに流す
  { pattern: '^日報', channel: '#now_nippou' },

  // 各プロジェクトの通知はそれぞれのチェンネルに流す
  { pattern: 'プロジェクト/2017/採用', channel: '#talk_recruit' },
  { pattern: 'プロジェクト/2016/xxx', channel: '#talk_xxx' },

  // どこにも通知してないやつは、esaチャンネルに流す
  { pattern: '', channel: '#now_esa' }
]

余談

Webhookの通知テストをしていたら、会社のチャンネルに@さんのアイコンがまざってきておもしろかったです。

f:id:mzp:20170126174158p:plain

採用

Misocaでは情報共有ツールを大事にするソフトウェアエンジニアを募集しています。

*1:厳密にはできないのではなく、「それ以外」を表現する正規表現を簡潔に書くことができない、です

2016年の大みそかを迎えて

こんにちは、マツモトサトシ (a.k.a @Dominion525) です。

今日はア・バオア・クー防衛戦…ではなく年末大みそかです。 そもそもMisoca は晦日(三十日≒月末)に由来しており、なかでも「おおつごもり」と称される大晦日は1年に一度の大事な日だったりします。 そこでいくつかの大きなトピックにについて振り返ってみようと思います。

2月:弥生グループにジョイン

2016年、一番大きかった出来事といえばもちろん上記になると思うのですが、意気込みその他については 開発ブログ1周年&弥生×Misoca - Misoca開発ブログ をご参照ください。

意気込み的なものは取り立てて大きく変わるわけではないのですが、10ヶ月ほど経って雑感を纏めてみます。

よかったこと

  • 財務面の安定
    • いままでは採用面談などでも「うちの会社は来年の今頃は無くなっているかもしれないのですが、そこは覚悟の上でよろしく願いします」って言っていたのが、少なくとも1年とかでどうにかなってしまうリスクはほぼなくなりました。その分後顧の憂いなしにより良いプロダクトを作っていくことに注力出来るようになりました。
  • 人員の増加
    • 従前よりも積極的にメンバーを採用していくことが出来るようになりました。とはいえご多分にはもれずエンジニアが足りない問題みたいなのはありますので、ぜひエントリ よろしくお願いします!
  • いろんなリソースが使える
    • たかだか10数人のMisocaからすれば弥生は大組織です。その中にはいろんな分野の専門家の方がいらっしゃるわけで、今までだと手が届かなかった様々な知見やリソースにリーチすることが出来るようになりました。

あんまりよくないこと(今後改善していきたいこと)

  • ステークホルダの増加
    • とはいっても、関係者は増えます。今まではほぼ独断でできたことが、関係各所と調整のうえで行う必要が出てきたりもします。それは組織力があるということの裏返しなので致し方ないところではあるのですが、できるだけ政治レイヤのオーバーヘッドを縮小して、スピードを維持していきたいと思ってます。
  • システム連係の改善
    • 双方の既存ユーザのベネフィットを増加させてシナジーを得る、というの肝要ではあるのですが、現状ではそこまでシームレスな連係によるバリューは提供できているとはいい難いと思っています。 ので、今後は重点的に改善していけると良いなあと言う感じです。
  • カルチャーのギャップ
    • 事前から予想はしていたとは言え、両者の暗黙的なコンテキストには 異なっている部分がそれなりにありました。大きな話題については事前に協議しているのでだいたいは一致しているんですが、わりと細かい点での齟齬がそこそこの頻度で発生しました。 現状では人的な交流やコミュニケーションを密に行うことによってだいぶ改善はしてきたかと認識しています。とは言え万全ではないので今後も継続的な活動が必要だなあと思っています。

その他、PROS/CONS いろいろあるのですが、細かい部分はオフラインのときに訊いてもらえるとわりといくらでも話します。

9月:RubyKaigi 2016 にスポンサーとして参加

今回始めてRubykaigiに正式なスポンサー(*1として支援しました。 初期のRuby会議から参加はしていたのですが、きちんと支援できたのは今回が初めてです。 単なる地方からの一参加者とだったところから、ここまで成長してこれたんだなあと思うのとわりと感無量的なところがあります。

くわしくはRubyKaigi 2016 参加レポート - Misoca開発ブログ をご参照ください。

10月:松江オフィス開設について

既報のとおり松江に開発拠点を置きました。 - Misocaが島根県松江市に進出、島根県および松江市と調印式を実施

RubyをコアテクノロジとするMisocaとしては、島根県松江市は特別な土地ではありますし、すでに@hidakatsuyaが活発に活動してくれている場所でもあります。

この度島根県松江市の支援も受けつつ、名古屋オフィスだけではなく松江オフィスも発展させていければ、と思っています。 なお、現時点は松江オフィスは物理的な場所が松江にあることを除けば何かに特化した機能をもつのではなく、拡張された開発チームとしてMisocaの開発を行っています。

松江オフィスについては、インターンSaaya HasegawaMisocaの日常-松江オフィス by Saaya Hasegawa | 株式会社Misoca が紹介してくれていますし、活動の様子は今後松江在住で松江オフィスのコアである @hidakatsuyaがいろいろ報告してくれるものと期待しています。

開発チームの現況について

以前の記事 から少し増減がありますのでご報告がてら。

増えた

  • ゆきはるさん / @snowsunny1107

    • 夏くらいからジョインしてくれました。とはいうものの下記の記事にもある通り、Misocaがスタンドファーム株式会社で受託開発とかやっていたときにもお手伝いいただいているので、こんな感じのガレージ(出典:公認会計士ナビ)時代を知る最古参メンバーだったりします。*2
    • 主にReact/Redux 周りの中心としたフロントエンドを扱うことが多いのですが、サーバサイドも頑張ってくれているオールラウンドプレイヤーです。
    • 主な過去のエントリ
  • いっしーさん / @issi_1109

  • えんださん / @enda1111

    • 11月くらいからジョインしてくれました。もともとはC++で画像解析をしてたり、硬派な感じのプログラマでした。その後東京のスタートアップにジョインして、Rails ベースで開発したり、機械学習を活用したデータ分析を行ったりしていたそうです。幅広いスキルに期待ができます。
    • ゴルフが趣味とのことなのですが、スポーツ全般に疎い*3Misocaチームではなかなか一緒にできるひとがいないので、名古屋近辺でゆるくゴルフできる人は誘ってあげてください。
    • 主な過去エントリ
      • まだないので楽しみにしてます!

卒業

これからについて

Misocaでは開発者と開発チームが最大限パフォーマンスを発揮できるように、各人が自律的によりよい環境を模索して運営が行われています。 もちろんうまくいくこともあれば期待通りの成果が得られないこともあるのですが、それらすべてを糧として次の段階に進むように頑張っています。

そんなMisocaとMisoca開発チームを一緒に作ってくれるメンバー*4をぼくたちは求めています。 くわしくは下記を参照してください。 また、エントリまでいかなくてもどんな雰囲気か覗いてみたい、という場合も随時見学を受け付けていますのでお気軽にどうぞ。開発チームのメンバと一緒にランチに行ったりできます。

www.wantedly.com

www.wantedly.com

2017年もよろしくお願い致します!

*1:いままではAdditional Sponsorでした。

*2:その後一旦4年位離れて、再度召還しました。

*3:自転車派とマラソン派とボルダリング派はいます。

*4: マーケティングとか、開発以外の人も絶賛募集しています。

NGK2016Bで発表してきました

こんにちは、再びいっしーです。

12/17(土)に NGK2016Bというイベントで発表してきました。
Misocaの日常についてお話ししたので、内容を共有させていただきます。*1

資料

原稿

表紙

f:id:issi_0x0:20161220163130j:plain こんにちは、株式会社Misocaのissiです。
今日はMisocaの日常についてお話しします。

自己紹介

f:id:issi_0x0:20161220163402j:plain 私は11月からMisocaにJoinしました。
親会社である弥生の人間でもありますが、技術や文化の交流のために来ました。

大学時代にOCamlと型の話を嗜んでいたことが出向に選ばれた理由、かどうかは定かではありません。

宣伝

f:id:issi_0x0:20161220163445j:plain スポンサーセッションということで、宣伝です。

請求書作成サービス『Misoca』、みなさん、ぜひ登録してくださいね。

Misocaの開発

f:id:issi_0x0:20161220163707j:plain そんなMisocaがどうやって開発されているか、これもみなさんご存知だと思います。なので、次に行きます。

Misocaといえば

f:id:issi_0x0:20161220163717j:plain さて、Misocaといえばmzpさんや黒曜さんが有名です。

そんな2人と日常的に話すことといえば・・・

f:id:issi_0x0:20161220163827j:plain そう、型です。

問題点

f:id:issi_0x0:20161220163936j:plain ただ、ここは型の聖地名古屋なので、ただの型の話は飽きていらっしゃると思います。

解決策

f:id:issi_0x0:20161220164019j:plain なので、今日はすこし趣向を変えて、日本語と絡めてお話ししたいと思います。

本LTの結論

f:id:issi_0x0:20161220164115j:plain 結論からいうと、日本語などの自然言語の文というのはプログラムです。
・・・はて?と思った方いますよね。説明します。たとえば。

例文1:Misocaが請求書を作る。

f:id:issi_0x0:20161220164244j:plain 「Misocaが請求書を作る」という文があります。

特におかしいところのない文です。このように、ある文が文として形式的に成り立っていることは、プログラムで言うところのコンパイルが通る状態です。
では、「形式的に」とはどういうことか。

例文2:作るMisocaが請求書を。

f:id:issi_0x0:20161220164306j:plain 次の文です。「作るMisocaが請求書を。」
わからなくもないけど順番おかしくね?みたいなのが、形式的に成り立たない、ということです。これはコンパイルが通らないプログラムです。
・・・では、次はどうでしょう。

例文3:Misocaが請求書を食べる。

f:id:issi_0x0:20161220164322j:plain 「Misocaが請求書を食べる。」

形式的にはよさそうですが、比喩でもない限り意味不明です。これは、コンパイルは通るが期待と結果が違うプログラムといえます。

形式的に証明してみましょう

f:id:issi_0x0:20161220164353j:plain さて、ここまでは直観で話してきましたが、せっかくなので形式的に証明してみましょう。

準備1:規則を与える

f:id:issi_0x0:20161220164447j:plain まず、規則を与えます。
左の規則は、A/Bの右側にBがきたときAが導出されることを表しています。

逆に、右は、A\Bの左側にBがきたときAが導出される、という規則です。

準備2:単語に型をつける

f:id:issi_0x0:20161220164454j:plain 次に、単語に型をつけます。

ここではざっくり、名詞句にはNP、他動詞には(S\NP)\NPという型をつけます。
Sは文であることを表す型です。

例文1の形式的証明

f:id:issi_0x0:20161220164556j:plain 先ほどの、文として成り立っている例文です。 「請求書を」と「作る」に規則を適用して、S/NPが導かれ、さらに「Misocaが」に規則を適用するとSが導かれ、文であることが証明できました。

例文2の形式的証明

f:id:issi_0x0:20161220164650j:plain 文として成り立っていなかった例文は、規則が使えず、Sを導くことができないので文でないことが証明できます。

例文3の形式的証明

f:id:issi_0x0:20161220164659j:plain 意味不明な例文は、文であることは証明できました。
が、意味が正しいことを証明するには、もっと他の規則が必要になります。

他の文が気になる方へ

f:id:issi_0x0:20161220164749j:plain 意味の証明論やほかの文がどうなるかが気になる方はこの本をどうぞ。

まとめ

f:id:issi_0x0:20161220164820j:plain まとめです。自然言語の文はプログラムで、型と規則があれば文かどうかが証明できます。
めっちゃシンプルですよね!
そう、シンプルなんです。Misocaではシンプルを大切にしています。


採用

f:id:issi_0x0:20161220164830j:plain 同じようにシンプルを大切にしている方、世の中をシンプルにしたい方、型に興味がある方、Misocaではエンジニアを募集しています。ぜひ一度あって開発や好きなことについてお話ししましょう。 お互いに刺激を与えながら、学習し、いっしょに成長していけたら嬉しいです。

*1:なんと今回が初LTでした。めっちゃ緊張した

Grape+SwaggerでAPIのドキュメント作成を自動化した

こんにちは、Misoca開発チームのいっしーです。
11月からMisocaにJoinしました。

10年ほど東京にいたので、未知の土地に新鮮な気持ちでいます。
名古屋の好きなところはB級グルメがたくさんあるところ、こわいところは学生時代に学んでいた関数型言語OCaml自然言語の形式理論の話がナチュラルに通じてしまうところです。

さて、そんな私の初仕事であるMisoca API v3が先日リリースされました。
見積書や取引先をAPI経由で扱えるようになっています。

www.misoca.jp

また、技術面ではGrapegrape-swaggerを新たに導入しました。
今回はこれらについて紹介したいと思います。

背景

Misoca API v1 (以後、v1とします) では、Rails標準のControllerでリクエストを受け付け、結果をjson形式などでレスポンスを返す形を取っていました。また、APIドキュメントは手書きしていました。

問題点

やはりというべきか、v1では変更への追従がひとつの課題でした。
Web版Misocaの仕様変更をAPIに反映させることも、APIの変更をドキュメントへ反映させることも、毎回漏れなく行うには結構な手間がかかりました。

もっと楽したい……。

Grape+Swaggerへの移行

上記の問題を解決するために、まずはドキュメントの作成を自動化することにしました。 コードからのドキュメントの生成には、AutodocやApipie-railsなどがありましたが、標準化されたフォーマットということでSwaggerを採用しました。SwaggerではSwaggerUIと呼ばれるAPIドキュメントビューワーも提供されています。
コードの実装には、Grapeを使用しました。GrapeはRubyでRESTlikeなAPIを実装するためのフレームワークで、コードをきれいに記述できたり、APIのルーティングをDSLで記述することができます。

今回、Grape+Swaggerで実現したいことは以下の二つです。

  • コードからドキュメントを自動生成できる
  • サンプルレスポンスを表示できる

gemのインストール

まずは、以下のgemをインストールしました。

gem 'grape'                   # Grapeを使うときのGem
gem 'grape-entity'            # 1対多のデータ構造を書くときに使う
gem 'grape-swagger'           # Grapeで定義したAPIをSwagger形式でドキュメント化するために使う
gem 'grape-swagger-entity'    # レスポンスモデルをSwaggerで見られる形式にするときに使う

APIとドキュメントの実装

次にAPI本体を実装します。
v3のクラスはApplicationControllerを継承しませんが、以下の理由からapp/controllers/api/v3 以下にファイルを置いています。

  • 役割的にはcontroller
  • 他のAPIと同じような場所に置きたかった
  • autoloadの効くディレクトリに置きたかった

そして、以下のような実装になっています。

module Api
  module V3
    module Estimates
      class Read < Grape::API
        # 共通メソッドのinclude。今は以下のようなメソッドが定義されている
        #   - desc_scope(scopes, desc, **args)
        #   - current_party/current_user
        #   - 有効な access_token を持っているかの判定
        include Api::V3::Authenticate

        # Grape記法でAPIの説明を書く
        desc '見積書'
        resource :estimate do
          desc_scope %w(read write), '見積書を取得します', success: ApiEntity::Estimate
          params do
            requires :id, type: Integer, desc: '見積書のID'
          end
          route_param :id do
            get do
              # API本体の実装
            end
          end
        end
      end
    end
  end
end

descで記載している部分が、APIの説明としてSwaggerで表示されます。

レスポンススキーマの実装

そして、サンプルレスポンスを自動生成するために、app/presenter/api_entity以下にレスポンススキーマを定義します。

module ApiEntity
  class Estimate < Grape::Entity
    class Item < Grape::Entity
      expose :name, documentation: { desc: '品目' }
      expose :unit_price, documentation: { desc: '単価', type: 'number' }
      expose :quantity, documentation: { desc: '数量', type: 'number' }
      expose :unit_name, documentation: { desc: '単位' }
      expose :tax_exempted, documentation: { desc: '消費税対象外フラグ', type: 'boolean' }
    end

    class Body < Grape::Entity
      ...

SwaggerUIへの出力

最後に、API本体をapp/controllers/api/v3/root.rb内でマウントし、Swagger形式のドキュメントを作成します。

module Api
  module V3
    class Root < Grape::API
      format :json
      ...

      # APIをマウントする
      mount Api::V3::Contacts::Read
      mount Api::V3::Contacts::Write
      mount Api::V3::Estimates::Read
      mount Api::V3::Estimates::Send
      mount Api::V3::Estimates::Write

      # swaggerドキュメントを生成する
      add_swagger_documentation(
        ...
      )
    end
  end
end

ここで生成されたjson形式のドキュメントは http://localhost:3000/api/v3/swagger_doc で確認することができます。
root.rbapp/controllers直下に配置した場合は、 http://localhost:3000/swagger_doc を確認してください。

このアドレスをSwaggerUI右上のテキストボックスに入力することで、ドキュメントがSwaggerUIで表示されます。 f:id:issi_0x0:20161220102814p:plain

完成!

以上を行なってSwaggerUIで表示されたものがこちらです。
説明文やリクエストパラメータ、サンプルレスポンスなどがドキュメントに反映されていることがわかると思います。 f:id:issi_0x0:20161216101208p:plain

実際に動くものがみたい方はこちらでどうぞ。

苦労した点

GrapeはApplicationControllerを継承していないため、そこで定義していた変数が一部使えなくなりました。 具体的には、現在ログインしているユーザを表すcurrent_userなどです。 これらは認証を行うために必要なので、別途、実装しました。

認証情報を取得する

認証を行うために、grape helperを使ってGrapeの拡張を行います。いまのところv3でしか使わないので、app/controllers/api/v3以下にauthenticate.rbを作成し、その中でcurrent_userなどを定義します。

require 'doorkeeper/grape/helpers'

module Api
  module V3
    module Authenticate
      extend ActiveSupport::Concern
      ...

      included do
        helpers Doorkeeper::Grape::Helpers
        ...

        helpers do
          def current_user
            ...
          end

          ...
        end
      end
    end
  end
end

まとめ

APIドキュメントを自動生成するようにしたことで、コード修正とドキュメント修正の二重苦から解放され、保守がかなり楽になりました。
ドキュメント生成の時間が削減できた分、新しいAPIをどんどん提供していきますので、お楽しみに!

Misocaの新しい受発注機能がSketchでデザインされてる様子

こんにちは、こくぼ @ です。株式会社ファントムタイプ @ から来ました。 ちょっと前の話ですが、宮城県の松島に行ってきました。ちょうど紅葉がきれいな季節でした。

写真は朝日を浴びる福浦橋です。 f:id:yusuke-k:20161215183524j:plain

今回はMisocaの受発注機能がどのようにつくられているのか、という話をしたいと思います。

Misocaの受発注機能とは

皆さんMisocaと言えば「請求書を簡単に作れて取引先に送るところまでやってくれるサービス」というイメージが強いではないでしょうか? 受発注機能ではそれに加えて、取引先とのコミュニケーションもサポートしています。

f:id:yusuke-k:20161215162107p:plain

Misocaが掲げる「仕組みで世の中をシンプルにする」「事業者間の取引を最適化する」といったビジョン・ミッションを推進するための野心的な取り組みです。

受発注機能のスクリーンショット

例えば、取引先に見積書を送ったとします。 その見積に対しての相談や発注操作を取引先がMisoca上でできるようになっています。

見積を送る受注側の画面

f:id:yusuke-k:20161216101220p:plain

最初に受注側のMisocaユーザーが見積を送るとこうなります。

f:id:yusuke-k:20161215120530p:plain

見積をもらった発注側の画面

f:id:yusuke-k:20161216101231p:plain

発注側が同じ画面を開くとこうなります。

f:id:yusuke-k:20161215120542p:plain

発注側のユーザーが発注手続きを完了すると、相手側に発注されたことが通知されます。 他にもファイル共有もできますし、取引先とのコミュニケーションに必要な機能を順次拡張しています。

ビジネス上で必要な取引先とのやり取りをMisoca上で完結できることを目指しています。

受発注機能のビジュアルを支える技術

受発注機能のビジュアルデザインはSketchでつくられています。 本記事ではSketchを使ったアプリ開発の事例を紹介します。

Sketchについて

https://www.sketchapp.com/images/app-icon@2x.png

SketchとはオランダのBohemian Codingという会社がつくっているデザインツールです。 UIやロゴのデザインに特化した機能を揃えているのが特徴です。 似たようなツールはいくつか出てきてますが、デザイナーであればデファクト・スタンダードと言ってもいいくらいの存在感があります(個人の感想)。

Sketchの簡単な使い方についてはQiitaに個人的に記事を書いてるのでそちらを参照してください。 qiita.com

MisocaとSketch

はじまりはiOSアプリ

元々はMisocaのiOSアプリをつくるときにTHE GUILD さんによって導入されました。

f:id:yusuke-k:20161215190654p:plain

UIやアイコンのデザインがSketchでつくられていく様子を見てこれが未来だと思いました。 アプリのデザインに最適化されたツールとしての使いやすさもあり、違和感なく使い始めることもできました。

Webへの展開

iOSアプリでの開発に使ってみてうまく導入できたので同じ要領で受発注機能の開発にも使っています。 最近はデザイナーとエンジニア間の共通ツールとして定着してきています。

冒頭のスクリーンショットは元は以下のようにデザインされました。

f:id:yusuke-k:20161214184851p:plain

その他、必要なUIを随時足していきました。

f:id:yusuke-k:20161214184857p:plain

まだ開発中のが多くて公開できるものが少ないのですが、雰囲気はこんな感じです。

Sketchを使うと何が嬉しいの?

距離を測る

UIデザインに最適化されているので、例えば要素間の距離を測ったり、CSSに落とし込むときの情報を取得したりというのに優れてます。

f:id:yusuke-k:20161214165032p:plain

ガイドを引く

他にも、スマートガイドを使って両隅に余白をつくったり、

f:id:yusuke-k:20161215114226p:plain

要素を部品化する

要素をシンボル化してデザインパーツとして共通化できたります。

f:id:yusuke-k:20161215115218p:plain

デザイン界隈には Atomic Design というデザインパターンがあります。Sketchのシンボル化機能とAtomic Designの親和性すごく高いと個人的に思ってます。 そしてこのAtomic Designの考え方とエンジニアの嗜好性も近いところにあると思うので興味があるエンジニアの方は覚えておくのをオススメします。

postd.cc

豊富なプラグイン

豊富なプラグインがエコシステムとして存在するのがSketchの魅力の一つです。 例えば要素のサイズとかスペースのドキュメント化を超簡単にしてくれるMeasureプラグインという人気のプラグインがあります。

f:id:yusuke-k:20161216111221p:plain

他にも要素を複製したりとか、画像をFlichrやインターネットから適当に選んでハメてくれたり、画面間に線を引いたりとか色んなプラグインがあってデザイン作業をアシストしてくれます。

もっと進んだ使い方

例えばFlintoというツールを使うとSketchのデータを取り込んでプロトタイピングできます。 最近だとAdobe UXFacebookOrigami Studio などプロトタイピングツール戦国時代が始まってきた感じがあります。

その他昨今のデザインツールについての話はこちらの記事を参考にしていただけるとよいと思います。

www.yasuhisa.com

Sketchの注意点

当たり前ですが、.sketchファイルはSketchアプリを持っていないと開けません。 Sketchは画像やPDFにエクスポートする機能を持っていますが、エクスポートしないと見れないのは注意が必要です。

今はまだβ版ですが、Sketch Cloudという機能があり、それを使うともっと簡単に共有できるようになる予定です。

まとめ

Sketchはデザイナーに人気のツールなのでデザイナーとエンジニアの協業では当たり前に使われているツールだと思います。 今回の記事で、MisocaでもちゃんとUIデザインを考えながら開発してるんだよ、というのを知っていただけるとうれしいです。

Jenkinsとrrrspecと私

Misoca開発チームの黒曜(@kokuyouwind)です。
最近PS VRを買いました。画像は夏にSony StoreのPS VR体験会へ行った際、スタッフの方が撮ってくださった写真です。

f:id:kokuyouwind:20161130184820j:plain

OculusやViveと比べると解像度は低めですが十分な没入感がありますし、なによりアイマスVOCALOIDなどのキャラクターコンテンツが色々あるのは強いですね。
PS VRはいいぞ。

rspec-queueからrrrspecへの移行

MisocaではJenkinsを使ってCIを回しています。
またrspecでテストを書いており、Jenkins上では時間短縮のためにrspec-queueを使って並列実行していました。
しかし、テストが増えるにつれてrspecの実行時間が長くなってしまい、CPUコア数やメモリの制約で1ノード内での並列数も限界になっていました。

このため、ビルド時間の短縮を目的にrrrspecへの移行を行いました。 今回はこの移行についての話を紹介したいと思います。

rrrspecについて

rrrspecは、クックパッド社製のrspec分散実行ライブラリです。
複数のworkerがそれぞれジョブキューからジョブを取得して実行する構成になっており、workerのマシンやプロセスが落ちた際の自動復帰、無反応プロセスのタイムアウトなどの機能が特徴となっています。

技術的な詳細についてはクックパッド開発者ブログの記事がまとまっています。
また、Software Design 2016年8月号に特集記事が掲載されており、今回のrrrspec移行でも、こちらの特集記事を参考に作業を進めました。

サーバ構成

rrrspec移行前

rrrspec移行前は下図のような構成になっており、Jenkins Slaveノード上でrspec-queueプロセスを立ち上げて実行していました。
またMySQLはプロセスのメモリオーバーヘッドを考慮し、2つのJenkins Slaveノードのうち片方でのみ立ち上げて、それを両方から見る構成にしていました。

f:id:kokuyouwind:20161202112726p:plain

この構成だと、Jenkins SlaveノードのCPUやメモリ構成を簡単には変えられないため、rspec_queueで上げられる並列度には限界がありました。
またJenkins Slaveノードにはベアメタルサーバーを利用していたのですが、普段はかなりのリソースを余らせているものの、ジョブが集中するタイミングではリソースが全く足りない、という状況になっていました。

rrrspec移行後

rrrspec移行後は下図のような構成になっています。

f:id:kokuyouwind:20161202112746p:plain

移行前と比べるとかなり複雑な構成に見えますが、Jenkinsクラスタとrrrspecクラスタはrrrspec masterノードを間に挟んでいるだけで、クラスタ間では参照がない構成になっています。
こうしてみると、それぞれのクラスタについては比較的シンプルな構成となっているのが分かるかと思います。

rrrspec-workerノードについて、図中には1ノードのみ記載していますが、実際には複数台を起動しtaskが分散実行されるようにしています。
この際、rrrspec masterノードからはrrrspec workerノードを知る必要がないため、適切な設定でrrrspec workerノードを立ち上げるだけでスケールアウトすることができる、というのがrrrspecの素晴らしい点だと思います。

JenkinsのJob定義

rrrspecの移行と同時期にJenkinsのバージョンを2系に上げたため、rrrspecを実行するテストはPipelineを利用してJenkinsfileに記述しています。
以前のジョブ定義に比べると、Jenkinsfile化されたことで履歴管理ができレビューもしやすくなり、stage viewを見ることで失敗したstageを手早く把握できるようになりました。

stage viewでの表示

stage viewでの表示は以下のようになっています。

f:id:kokuyouwind:20161201180829p:plain

このうち、rrrspecに関連しているstageはRspec StartとRspec Waitです。

Jenkinsfileの内容

Rspec Start stageでは、以下のように rrrspec-client start を実行し、 taskId を取得します。

stage 'Rspec Start'
taskId = sh(returnStdout: true, script: '''#!/bin/bash -e
bundle exec rrrspec-client start \
  --rsync-name=jenkins-${NODE_NAME}-${EXECUTOR_NUMBER}
''').trim().split("\n").last()

一方、Rspec Wait stageでは取得した taskId を指定してrrrspecのタスクセット完了を待ち、完了したら結果を表示します。

stage 'Rspec Wait'
withEnv(["TASKID=${taskId}"]) {
  bash '''
bundle exec rrrspec-client waitfor $TASKID
bundle exec rrrspec-client show $TASKID
'''
}

この2つのstageの間に、lintやフロントエンドのテストを行うstageを挟んでいます。
これにより、pipelineとしては直列のまま先にrrrspecを回す、というちょっとした並列処理を行ってジョブ実行時間を短縮しています。

なお、Jenkinsではparallelを使って並列処理を定義することもできるのですが、parallel内部ではstageを定義することができません。
このためstage viewでrrrspecとlint・フロントエンドテストが1つのstageとして表示されてしまい、どこで落ちたか分かりにくくなってしまうという問題があったため、上述のような実装になっています。

rrrspec workerのスケーリング

rrrspec workerはインスタンスが突然停止されても問題ないことから、コストパフォーマンスの高いAmazon EC2 スポットインスタンスを利用しています。
前述の通り、適切な設定でAMIを作成しておけばインスタンスを起動しただけでrrrspec masterに接続してtaskの実行を開始することができます。
このため他ノードの設定などを行う必要がなく、簡単にAuto Scalingの仕組みに載せることができます。
CIでの自動テストでは、Jobがない状態ではリソースが不要な一方で、Jobが集中しているときには大量のリソースを必要とします。
このためAuto Scalingに載せやすいというのはコスト削減の点でもJobのスループット向上の点でも非常に重要です。

スケーリング設定

現在はrrrspec workerインスタンスのAuto Scalingを以下のように設定しています。

  • スケジュールされたアクション
    • 平日5時から、最小5, 最大5
    • 平日9時から、最小5, 最大15
    • 毎日20時から、最小1, 最大5
  • スケーリングポリシー

考慮したこと

Misocaでは、.rrrspecconfig.max_workers = 5と設定しているため、1つのTasksetにつきrrrspec workerを最大で5ノード利用します。
このため5ノード単位でworkerをスケールさせることで、各Tasksetを最大効率で実行することができます。

また、基本的には日中の決まった時間にのみ勤務しているため日中にリソースを集中させたいのですが、フレックス勤務を採用しており夜間に少し作業を行うこともあるため、夜間でもCIが実行できるようにしておく必要がありました。
さらにallnightジョブのプラクティスを取り入れており、作業の行われていない早朝に数回テストを実行して安定性を確認するJobを実行しているため、この時間帯はリソースを確保しておく必要があります。

設定の意図

スケジュールについては、最小数指定で最低限のインスタンスを常に確保しつつ、負荷があがったタイミングでは最大数までスケールするように意図しています。
5インスタンスのまとまりで考えると、allnightジョブを走らせる平日5時〜9時は1並列固定、平日日中は1-3並列です。
夜間はやや特殊で、常時確保するのは1インスタンスのみで、ビルドが始まったタイミングで5台までスケールするようにしています。
このため夜間は少しビルドに時間がかかりますが、5インスタンスを常に立ち上げておくのに比べるとほぼ1/5のコストに抑えられます。
夜間はたまにしかジョブが実行されないことを考えると妥当なトレードオフではないかと思います。

スケーリングポリシーについては、CPU負荷が高い場合はリソースが枯渇しているのでインスタンスを増やし、CPU負荷が下がったときには余っているリソースを開放する、という動作を意図しています。
インスタンス追加する基準が60%となっているのは、10台ある状態で5台だけが動いているときにはリソースが余っているため、インスタンスが追加されないようにするためです。

スケーリングの可視化

インスタンス数やCPU UtilizationなどはCloudwatchのダッシュボードを使って一覧できるようにしています。
左上のインスタンス数グラフとその下のCPU Utilizationをみると、CPU負荷に応じてインスタンス数がスケールしているのが分かるかと思います。

f:id:kokuyouwind:20161201191229p:plain

まとめ

Misocaではrrrspecを利用してテストを分散実行するようにすることで、以前は20分前後かかっていたビルド時間を10分程度まで短縮することができました。
またスポットインスタンスを利用し必要なタイミングでスケールさせるようにすることで、以前に比べてコストも削減できました。

今後の課題として、以下のようなことを考えています。

  • スポットインスタンスをm4.large以外も使えるようにして、よりコストパフォーマンスの高いものを自動で使うようにできないか
  • 常にm4.largeを確保しているMySQLノードについてもスケールさせられないか
  • CPU Utilizationではなくrrrspecのtasksetの状態に応じてスケールさせられないか

宣伝

Misocaは継続的にCIを改善したいエンジニアを募集しています!

あと島根で働きたいエンジニアも募集しています!

Slackを使いこなすための設定とMisocaにおけるSlackしぐさ

はじめに

MisocaチームのRKTMです。

この投稿は、ときどきナガノという、 長野県庁の企画を利用して、長野県松本市コワーキングスペースにて書いています。 Misocaではリモートワークができるため、金曜日に旅先へ移動して仕事->土日をフルに観光に使えます。

松本からは冠雪した北アルプスを眺めるられるかなーと思っていましたが、ちょっと雲がありますね。あの雲の向こうの雪山に心惹かれています。 f:id:RKTM:20161125132337j:plain

SlackはMisocaチームに欠かせないツール

MisocaチームではSlackをどうやって使っているか、という記事は過去に公開しています。

tech.misoca.jp

Misocaではリモートワークを推奨しているため、松江オフィス、岐阜など、名古屋オフィス以外でメンバーが活動しています。

www.wantedly.com

リモートの人がいることもあり基本的なコミュニケーションはSlackで行っています。(口頭のほうが早いことはハングアウトを使って同期的に話しています。)

f:id:RKTM:20161125135459p:plain

なお、MisocaのSlack statsは以下の通りです。

全期間でのメッセージ合計数 f:id:RKTM:20161122141558p:plain

782K。

メンバーのメッセージ数 f:id:RKTM:20161125135656p:plain

自分の発言数が多いことに気づきます。

自分とmzpの二人でMisocaの発言数の10%を占めている…という発見がありました。

Slackで読むスピードを上げよう/もっと気軽に書き込もう

最近Misocaでは開発メンバーが二人Joinしましたが、Slackに慣れないようです。

主なハードルは

  • メッセージ流量に追いつかない
  • 書き込みづらい

という2点の模様。

そこでMisocaに新しく入った/入る人を想定して、 流量に圧倒されず読むスピードを上げるためのおすすめ設定、 Slackに気軽に書き込むためのtipsを記載します。

早く読むためのSlackのおすすめ機能や設定

以下がSlackおすすめ機能です。

ショートカットキー

/shortcutsでショートカットキーが表示されます。 最低限知っておくと良いのは(環境によってキーに多少の違いがありますが)、以下の通りです。

  • Cmd+kでchannel検索
  • Option + ↑ or ↓でチャンネルリストの上下移動
  • Option + Shift+↑ or ↓で未読のチャンネルリストの上下移動
  • (ショートカットキーではないですが)入力エリアでで、自分が最後に投稿したメッセージの編集ができる(typoした時などに便利)

自分へのmention/reactionを表示

ヘッダー右のアットマークをクリックすると 重要なmention(依頼など)の見落としがないか確認できて便利。

f:id:RKTM:20161125135812p:plain

個人の設定変更

f:id:RKTM:20161121132225p:plain

Slackのチーム名プルダウンからPreferencesを選択すると、個人の設定変更画面が表示されます。

チャンネル一覧を未読のものだけにする

f:id:RKTM:20161121132618p:plain

この設定で、未読のチャンネルのみがサイドバーに表示されます。 この設定をしないと、大量のチャンネルがずらっと並んで非常につらいことになります。 未読ではないチャンネルに移動する時はCmd+kを使ってください。

人によって評価が分かれる設定

チャンネルのStar

特定のチャンネルをサイドバー上部にまとめて表示し、すぐにアクセスできるようにする機能。

ALL UNREADS

未読の発言だけを集約した仮想チャンネル。

チャンネルを移動せずに未読を消化できるので良いですが、 発言の文脈がわかりづらく、1時間ぐらいでやめました。

その他tips:参加するチャンネルを絞る

そもそも、自分に関係の少ないチャンネルからは勇気を持ってleaveしましょう。

MisocaにおけるSlack tips

気軽に書き込める個人チャンネルをつくろう

Misocaでは、各自が好きなことを好きに書き込める自分用のチャンネルを作っています。 そこは共有場ではなく、自分の場ということで、好きなことを好きなだけ書いてOKです。 仕事に関係ない独りごとから、作業メモや詰まっていることまで、誰に気兼ねすることなく書き込みましょう。

こちらを参考にしました。 c16e.com

Misocaではチャンネル名はcurrent_xxxというパターンにしています。

書き込んでいると色々な人が集まってきて解決してくれたり悪乗りしてくれたりします。 f:id:RKTM:20161122155103p:plain

自分で閉じずにとにかく書き込みましょう

  • 自分の作業が詰まった時や判断に悩んだ時はSlackに書きこみましょう。
  • 質問もお気軽に。気の良い人が優しく教えてくれます。

f:id:RKTM:20161122154309p:plain f:id:RKTM:20161122151757p:plain 質問から発展して最新の情報にアップデートできました。

秘密にしたいことでなければ、DMは使わないでおこう

オープンにしておけば、そのやり取りを見たチームメンバーが更にいいアイデア出してくれるかもしれません。 また、そのやり取りが他の人にとって有益な情報である可能性もあります。

最後に

Slackのおすすめ設定と、MisocaにおけるSlack tipsについて記載しました。
Slackは軽量で色々なサービスとも連携できる便利なサービスですが、 後から入った人には少し敷居が高いかもしれません。

本記事がそんな方やチームに、少しでもご参考になれば幸いです。
みなさんのSlackおすすめ設定などもぜひ教えてください!