いよいよRaksul Hack Weekが始まります!

こんにちは。エンジニアマネージャーの石川です。普段は、印刷ECサイトで提供している集客支援(ダイレクトメール、新聞折込、ポスティング等)の開発に携わってます。

前回、ハコベルの加藤よりHack Weekの紹介をさせていただきましたが、いよいよHack Week #2の開催が来週となりました。

Hack Weekは、エンジニア、デザイナ、PM、普段ラクスルの事業を支えているTECHチームが参加するハッカソンイベントです。自分たちでアイディアを出し合い、1週間かけて開発を行います。

本日は、前回の記事以降に行われたチームビルディングイベントの様子をご紹介したいと思います!

チームビルディングイベントを開催しました

Hack Week開催まで3週間を切った5/22、Hack Week pre-eventと称して、チームビルディングを目的としたイベントを開催しました。

前回の記事では、 Hack Week Lunch を実施の様子をご紹介しましたが、今回はチームビルディングイベントということもあり、美味しい食事とお酒を楽しみながら、自由な雰囲気でコミュニケーションを取りやすいイベントを目指しました。

まずはIceBreak

Hack Weekでは、普段は違うチームで開発をしているメンバーと一緒に開発ができる良いチャンスでもあります。

今回のイベントでは、普段のチーム以外のメンバーともぜひ交流を深めてほしい。

そこで、冒頭の時間をIceBreakタイムとして簡単なゲームを実施しました。

まずは隣にいる人と話すきっかけを持ってもらうこと、声を出して話して見ることで、緊張をほぐしてもらうことが目的です。

2人ペアを組んでもらい、簡単なゲームを通して15分ほど会話を楽しんでもらいました。

会場の雰囲気も和んできたところで…ラクスルビールで乾杯をしてイベントスタートです!

チームビルディングタイム

「こういう面白いことやろうと思ってるんだけど、フロントやってくれませんか?」

と、熱いプレゼンをするメンバー

「まだ何をやるか決めてないんですが、何やるか決めました?」

と、すこし不安な思いを抱えながらの参加となったメンバー

それぞれの想いが入り混じりながら、チームビルディングタイムがスタートしました。

それぞれの想いを胸に、イベントスタートです!

最初はみんな手探りでしたが、それぞれが持ち寄ったアイディアを語り合いながら食事とお酒を楽しみ、それぞれのテーブルで様々な議論が交わされました。

身振り手振りを交えて熱い議論を交わします。

チームビルディングイベントの結果は?

イベント開催をきっかけに、16のチームが結成されました!

チームビルディングイベント中に結成されたチームも合ったようですが、イベントの翌日以降に改めて話して結成したチームも多く見られたようです。

チームビルディングイベントに参加してみて

私自身も、ラクスルに入社して4ヶ月。

社内にまだまだ知り合いが少ないので少し不安な気持ちでの参加でしたが、自己紹介から始まり、お互いの事業の紹介をしたり、温めていたアイディアの話をしたり、Hack Weekに対する不安が解消され「いよいよ始まるんだな!」と期待が膨らむイベントになりました。

いよいよRaksul Hack Weekが始まります!

いよいよ来週からRaksul Hack Weekが始まります。

それぞれの16チームのテーマも出揃いました。

テーマは、普段関わっている事業に関するもの、最新の技術を使ったもの、様々です。

次回は、Hack Week開催後に結果をお届けしようと思います。

ラクスルではエンジニアを引き続き募集しております!

ラクスルでは、一緒に事業を盛り上げてくれる仲間を引き続き募集しております。

エンジニア一人一人が事業に対して高い解像度を持ち、事業に関わることができる。全職種一丸となって事業を成長させていける、そんな職場です。

ただ開発をするだけではなく、事業を一緒に創っていきたい方、ぜひ弊社オフィスに遊びにきてください!

 

 

gRPC Client Interceptor入門 with Ruby

こんにちは。サーバサイドエンジニアの三瓶です。印刷ECサイトの ラクスル の開発保守を担当するチームに所属しています。

ラクスルでは Raksul Platform Project (RPP) と称して技術負債の返済活動を継続的に行っているのですが、その流れの一環として印刷ECチームでは巨大化したアプリケーションから商品仕様に関わる部分を別サービスとして切り出す、という作業を最近行いました。

この切り出したサービスでは通信方式として gRPC を、言語としてはRubyを採用しています。

実際に導入してみて、gRPCはまだドキュメントも多くはないと感じたので、本記事ではgRPCが備える機能の1つである Interceptor についてチュートリアル形式でご紹介したいと思います。言語はもちろんRubyを使います。

※ gRPC導入に至った背景や経緯について興味のある方は弊社エンジニアの二串のスライドをご参照ください

Interceptorとは何か

Interceptorとは、RPCコールの前後に任意の処理を差し込める機能・レイヤーのことです。Railsアプリケーションに馴染みがある方は Rack Middleware のようなものを想像してもらうと理解しやすいかと思います。

Interceptorを使えば、認証やロギング、データのフィルタリングなど各通信で共通の処理をひとまとめにできます。
実際に、我々のプロジェクトではリクエストを一意に特定するためのIDをmetadataに付与するInterceptorやリクエストしたメソッド・パラメータ・処理時間をログに残すInterceptor、例外をCatchしてSentryに通知するInterceptor等を自作して、本番環境で稼働しています。

以下はClient → Server間の通信に2つのInterceptorが介在したときのイメージ図です。

作成するClient Interceptorの仕様を決める

ClientのInterceptorと一口に言っても、以下のパターンが考えられます。

  • リクエスト処理の「前」に差し込む。リクエストデータに何か手を入れたい場合など
  • リクエスト処理の「後」に差し込む。レスポンスデータに何か手を入れたい場合など
  • リクエスト処理の「前後」に差し込む。両方に手を入れたい場合や処理全体に何かをしたい場合など

このうち、今回はリクエストの「前」に差し込んでリクエストデータを大文字化する UpcaseInterceptor と、リクエストの「前後」に差し込んで処理時間を計測する PerformanceLoggingInterceptor の2つを作ってみることにします。

以下、それぞれのインターセプターの簡単な仕様です。

  • UpcaseInterceptor
    • リクエストの前に差し込む
    • リクエストオブジェクトに name というキー名のデータあればその値を大文字化する
  • PerformanceLoggingInterceptor
    • リクエストの前後に差し込む
    • リクエスト全体にかかった時間を計測し、標準出力へ出力する
    • 時間は小数点第3位以下を四捨五入する

また、動作の流れは次の図のようになります。赤い線の箇所でインターセプターの処理を挟みこむイメージです。

Client Interceptorを実装する

※ 注意:gRPCのRuby実装では、IntercptorのAPIインターフェースは EXPERIMENTAL という扱いのようです。そのため、今後のバージョンアップで今回紹介するものとはAPIインターフェースが変わっている、ということがありえますのでお気をつけください。

Interceptorを実装するのはとても簡単で、今回の仕様であれば数行で作れてしまいます。

UpcaseInterceptor

UpcaseInterceptorの実装は次のようになりました。

# upcase_interceptor.rb
class UpcaseInterceptor < GRPC::ClientInterceptor
  def request_response(request: nil, call: nil, method: nil, metadata: nil)
    request.name = request.name.upcase
    yield
  end
end

いくつかポイントとなる部分を説明します。

(1) GRPC::ClientInterceptor を継承する

インターセプタークラスは GRPC::ClientInterceptor クラスを継承する必要があります。
継承しない場合、GRPC::InterceptorRegistry::DescendantError 例外が発生します。

(2) 通信方式に合わせてメソッドをオーバーライドする

メソッドは利用する通信方式に合わせてオーバーライドします。gRPCには以下4つの通信方式があり、それぞれに対応するメソッドがあります。

  • Unary RPC : #request_response
  • Server streaming RPC : #server_streamer
  • Client streaming RPC : #client_streamer
  • Bidirectional streaming RPC : #bidi_streamer

今回は、1リクエストに対して1レスポンスが返ってくる一番シンプルな通信方式であるUnary RPCを使うため、request_response メソッドをオーバーライドしています。

※ 各通信方式の詳細が気になる方は https://grpc.io/docs/guides/concepts/ をご参照ください

(3) yieldで次の処理を呼び出す

次にメソッドの中ですが、yield を呼び出すことで次のインターセプターまたはリクエスト処理の本体を呼び出すことになります。
UpcaseInterceptorはリクエスト実行の前に呼び出したいので、yield をコールする前に変換処理をしています。

PerformanceLoggingInterceptor

同様に、処理時間を計測して出力するPerformanceLoggingInterceptorは次のようになりました。

# performance_logging_interceptor.rb
class PerformanceLoggingInterceptor < GRPC::ClientInterceptor
  def request_response(request: nil, call: nil, method: nil, metadata: nil)
    start_time = Time.now.to_f
    resp = yield
    request_time = Time.now.to_f - start_time

    puts "duration: #{request_time.round(3)} sec"
    resp
  end
end

PerformanceLoggingInterceptorはリクエスト処理の全体を計測したいため、リクエストの前後に処理を差し込みます。
前述のとおり、リクエスト処理は yield を呼び出すことで伝播されていくため、その前後を囲う形で時間を取れば良いということになります。

返り値は yield で受け取ったレスポンスオブジェクトをそのまま返します。

Interceptorを使う

それでは、作成した2つのInterceptorを実際に使ってみましょう。
gRPC公式のチュートリアル Ruby Quick Start にあるHelloWorldアプリケーションに、今回作成したインターセプターを組み込んで動かしてみます。

Client Interceptorは、Stub と呼ばれるクライアントオブジェクトを初期化するときに引数として渡します。

# greeter_client.rb
require 'grpc'
require 'helloworld_services_pb'

# ★ 作成したインターセプターをrequireする
require_relative './performance_logging_interceptor'
require_relative './upcase_interceptor'

def main
  stub = Helloworld::Greeter::Stub.new(
    'localhost:50051',
    :this_channel_is_insecure,
    interceptors: [UpcaseInterceptor.new, PerformanceLoggingInterceptor.new] # ★ ここでインターセプターを設定する
  )

  # 省略..
end

main

interceptors 引数に渡す順序でインターセプターの実行順序が決まります。
配列の末尾から先頭へと順に実行されるため、上の書き方の場合、PerformanceLoggingInterceptorUpcaseInterceptor の順で実行されることになります。当初のイメージ図の通りの順序ですね。

それでは実行してみましょう。
まず、比較対象としてインターセプターを使わなかった場合の結果を見てみます。

$ bundle exec ruby greeter_client.rb
"Greeting: Hello world"

チュートリアルの通りであれば、上のように “Greeting: Hello world” という結果が出力されると思います。

次にインターセプターを有効化した状態で実行してみます。

$ bundle exec ruby greeter_client.rb
duration: 0.002 sec
"Greeting: Hello WORLD"

UpcaseInterceptor によって “world” が大文字化されて、PerfomanceLoggingInterceptor によって実行にかかった時間が出力されました!

まとめ

以上、簡単ではありますが、RubyでのgRPC Client Interceptorの仕組みや使い方についてのご紹介でした。

アプリケーションを本格的に運用するにつれて様々な要求が発生してくるかと思いますが、Interceptorが役に立つ・解決手段となるケースもあるのではないかと思います。そのようなときにこの記事が参考になれば幸いです。

今年も Raksul Hack Week を開催します!

こんにちは。ハコベル(物流サービス)チームの加藤です。

今年も社内ハッカソンイベントの開催が決まり、準備が進んでいるのでその様子をご紹介したいと思います。

Raksul Hack Week #1

昨年9月に開催した社内ハッカソンイベント Raksul Hack Week #1

こんな概要で、オフィス内で4日間の日程で開催しました。

  • 参加者はエンジニア、プロダクトマネージャー、デザイナーとする
  • ハッカソンの期間は1週間とし、期間中はハッカソン100%コミット、普段の開発業務はやらない(※ ただし緊急対応系は最優先で)
  • チーム制とする
  • 最終日に各チームは成果発表する
  • ラクスルの事業、ステークホルダーに関わることであれば何に取り組んでも良い

(詳しくは 1週間やる、楽しい社内ハッカソンの作り方 をご覧ください)

Raksul Hack Week #1

いつもの業務から離れたテーマを行ったり、いつもとは違う技術を使って開発したり、他のチームのメンバーと仕事したり。それぞれのチームの発表もお互いに刺激になり、とても好評なイベントとなりました。

さらに、この中からプロジェクトとして採用されたり、実際に世に出たりしたものもあります。

ラクスルデザインブログもその一つ。バナー、LPから、各サービスのプロダクトデザイン、イベントブースのデザイン、RubyKaigi などのノベルティなど、オールマイティに活躍するラクスルの優秀なデザイナーが綴るブログとなっています。ぜひご覧ください。

どうなるかわからない不安を乗り越えて

さて、参加メンバーにも経営陣にも好評だった第1回を受けて、今年もめでたくRaksul Hack Week を開催することになりました。

今回の開催にあたっては運営メンバーを一新。UXデザイナーで入社した新卒2年目のロビンが手をあげてリーダーを務めます。印刷・広告・物流の各チームからメンバーが集まり、前回の運営メンバーのアドバイスをもらいないがら、週一回のミーティングをベースに準備を進めることにしました。

開催日程は、6月中旬の1週間。会社が成長しているので、参加メンバーも増加。2回目で大枠の進め方が見えているとはいえ、運営メンバーの中には前回まだ入社していなかったメンバーもいるのでどう進めるのか不安も出てきました。まずは、”Wednesday Raksul” という社内の技術勉強会中にみんなに前回の参加のJourney Map を書いてもらって、運営メンバーで共有するところから始めました。

とあるメンバーの Journey Map (イベント開催前)

とあるメンバーのJourney Map (イベント開催中)

第1回目は最終的にとても楽しく刺激になるイベントだったのですが、開催前には「やることを決められるだろうか」「チームメンバーを集められるだろうか」といった不安があったことが見えてきました。新しく入社したメンバーからも同じような声があがったので、なるべくその2つの課題のサポートができるばと思いながら進めることにしました。

Raksul Hack Week #2 のテーマは…

さてそんな中から生まれてきた、今年のRaksul Hack Week #2のテーマは

 

みんなで創る次の世界

〜好きなことから始まる挑戦〜

課題 ✖️技術✖️技術

 

事業部ごとに様々な背景を持ったメンバーが増えていたり、新卒メンバー4人は全員国籍が違うというほどダイバーシティーに力を入れていたりする現在のラクスル。

そんな中でラクスルの「仕組みを変えれば世界はもっと良くなる」というビジョンを実現する一つの手段として、次の世界をみんなの力を使って実現できるようなきっかけになるようなイベントにしたいという想いが込められています。

新しい試み Hack Week Lunch

Journey Map から見えてきたことや、今年のテーマを踏まえ、開催までの期間を以下のように区切りイベントを開催したり案内を出したりすることにしました。

  • 4月:アイデア月間
  • 5月:チーミング月間
  • 6月:Raksul Hack Week #2

4月から5月にかけては、各事業部のビジネスメンバーからお客様の課題、自分たちの業務の課題やこんなのがあれば嬉しいといった声を聞くランチイベント Hack Week Lunch を実施しました。

ディスカッションの内容をホワイトボードに記録。その場のディスカッションを盛り上げたり、その場でどんな話題が出たのか参加していないメンバーにも共有していきました。

Hack Week Lunch

さらにアイデアを共有するためのSlackチャンネル #hack_week_ideas を用意して、Hack Week に直接参加しないビジネスメンバーとエンジニア/デザイナー/PMがアイデアを出し合う場をオンライン上でも作りました。

#hack_week_ideas チャンネル

部門を超えて課題やアイデアを交換したりする場になってきて、次のステップの本質的な価値提供の話題も上ったりしています。このチャンネルを通年運用したいという声もありました。

開催まで1ヶ月弱

いよいよ開催まで1ヶ月弱となってきました。5月はチーミング月間。「チームメンバーを見つけられるだろうか」という声に少しでもお答えしようと、カジュアルなプレイベントを実施する予定です。

今年はどんなチームや取り組みが生まれるのでしょうか。意外な組み合わせが、面白い結果を生んだりすることもあります。偶然の流れも大切にしながら、Raksul Hack Week #2 を楽しんでいきたいと思います。

 

ラクスルでは事業をつくっていきたいエンジニアを絶賛募集しています!

自分の書くコードで、印刷・広告・物流といった大きな産業の課題を解決するようなインパクトを作り出してみませんか。技術・業界・業務など多角的に理解を深めながら、自らアイデアを出し、主体的に事業家人材と一緒に事業をつくっていく。そんな働き方をしたい方をお待ちしています!

RubyKaigi 2019に行ってきました!

こんにちは、ラクスルの村田です。

ラクスルはRubyKaigi 2019にRubyスポンサーとして参加してきました!

上の写真はCTOの泉がスポンサートークをしている様子です。

ラクスルの提供するサービスの多くにRubyが使われており、去年に引き続き会社としてRubyコミュニティに貢献するべく、今年も参加させていただきました。

こちらはブースで提供したノベルティです!

カップラーメンを模してあり、ふたには会社がある「目黒」の文字、
そして中央にはラクスルの「ラ」が書かれています。

社内のデザイナーが力を入れて作ってくれました。

頑張ってノベルティを作ったかいもあり、ブースは大盛況でした!

ノベルティの詳細は弊社のデザインブログの記事をご覧ください!

福岡県知事の小川さんもブースに来訪いただきました!

ラーメンの中に入っているノベルティはラクスルの自社サービスで作ったことや、
福岡にちなんでラーメンの形にしたことなどを話したそうです。

弊社のCMで女優ののんさんが親指と人差し指を広げるポーズ(ラクスルスイッチ)があるのですが、
みんなでそのラクスルスイッチをする様子です!

 

面白かったセッション

聞きに行ったどのセッションも勉強になりましたが、業務でAPIの開発を担当していることもあり、APIに関わるものが特に楽しめました。

 

 

業務でもcommitteeを使っていて、OpenAPI3への対応を待ち望んでいました。
これで念願のnullableができる…!

ota42yさんありがとうございます。

 

APIの設計に当たって、いくつかの設計方法で迷うことがよくあります。
その際にとても参考になるセッションでした。

 

そして、最終日の最後のkeynoteセッション。
普段は可読性を重視して実装することがほとんどなので、スピードを最優先にする書き方は
非常に新鮮で面白かったです。

反省点

人見知りな性格のため、一度も公式のアフターパーティーに参加できなかったことが反省点です。。。

社外でもRubyエンジニアの友達を作るため、来年は頑張って参加します…!

 

最後に

ラクスルではエンジニアを絶賛募集しています!

現在手がけている、印刷・物流・広告の事業はどれも競合がいないブルーオーシャンです。
そのような環境の中でテクノロジーを使って課題を解決していきませんか?

青い海を赤いRubyの力(CTOの泉が気に入っているフレーズ)を使って切り開いてみたい方は
是非一度オフィスに遊びに来てみてください。

また、RubyKaigi 2019をテーマとした勉強会が弊社オフィスで開催されるので興味のある方は是非ご参加ください。

https://raksul.connpass.com/event/125165/

ラクスルはRubyKaigi2019にRuby Sponsorとして協賛します

ラクスルの松原です。

ラクスル株式会社は昨年に引き続き、本年も2019/04/18(水)〜2019/04/20(金)に福岡国際会議場で開催されるRubyKaigi2019にスポンサーとして協賛させていただくことになりました。

https://rubykaigi.org/2019/sponsors

ラクスル株式会社では「ラクスル」「ハコベル」両サービスにおいてRubyを中心技術として活用しています。

今回のRubyKaigiでは1日目(2019/04/18)にCTO泉よりスポンサーセッションとして、印刷・物流・広告といった、あまり技術的に攻められていない「ブルーオーシャン」(競合が少なく成長余地のある領域)をテーマにお話させて頂く予定です。

また、期間中は会場にてブースも出展させていただきます。「福岡」をテーマとしたラクスル特注の限定ノベルティーも用意しておりますので、参加される方は気軽にブースにお立ち寄り下さい!

 

当日会場でお会いできるのを楽しみにしております!

| by

ラクスルテレビCMオンラインストアの初期開発の進め方

こんにちは。フロントエンドを担当している古谷です。

今回は、ラクスルテレビCMオンラインストアを開発開始からリリースするまでの進め方についてご紹介します。

こちらの記事は、以前行われた 【ラクスル×KCF】FrontendNight というイベントにて 本編には惜しくも入れられなかった部分を中心に構成しています。

イベントで発表したこちらの資料もあわせてご覧ください。

Storybookを使って安心しながら開発を進める ラクスルテレビCMオンラインストア開発

こちらの資料では、「進める際のリスクがなにかをしっかりと想定すること、そのための対応手段の選択肢を増やすために技術力をあげていくことが大事。」とまとめています。

この発表では主にツール、技術の選定にフォーカスして発表していました。
この記事では、進め方について、実際のPRの画面を交えながら紹介していきます。

速度を保ちつつ開発する進め方

こちらも、上記資料と同じくどんなことが起きたら開発がうまく回らないかを考えていました。

以下の不安があり、それらに対して対策を打っていました。

  • 技術選定はうまくいっても速度が出ないのではないか
  • 仕様や実装の変更による手戻りが多いのではないか

速度が出ない問題にはどう対処したか

基本的なことではありますが、PRの単位を小さく保つこと、そして丁寧にすることがあげられます。

こちらが実際のPRです。

(※ 小さくとかいてあるわりに、Files changed が15なのは、Snapshotで多くのコンポーネントに影響が出ているからです。)

PRのテンプレートを作った

おそらく多くのプロジェクトで行っていると思いますが、PULL_REQUEST_TEMPLATE.md の形式を整えます。 チケット番号、実装したものの概要は書くとして、それ以外になぜその実装にしたのかという理由を書くことが大切です。

また、(実装者が想定している)影響範囲を書いておくことで、全体把握をしているという信頼関係の構築がしやすくなると思っています。 リリース前だからこそできることですね。

## 概要

簡潔に何ができるようになるかを書きます。
また、その背景や対応するチケットがあれば貼ってください。

その実装にした理由をコミットメッセージに加えてこちらに書いてください。
その他、レビューを厚めにしてもらいたい点があれば書いてください。

## 影響範囲

Storybookのスクリーンショットなどわかりやすいものがあれば貼ってください。
Propsの変更など大きな変更があれば書いてください。

## TODO

* [ ] storybook
* [ ] このPRをmergeするために必要な残タスクがあれば列挙します

## このPRでやらないこと

このPRでは対象外にすることを書きます。
チケット、ISSUE、FIXMEを使って管理してください。

スクリーンショットを乗せるようにした

フロントエンドの開発では、スクリーンショットを乗せることでPRを中心にコミュニケーションが回ります。 スクリーンショットを乗せることで、仕様に沿った動きをしているかどうか、挙動の認識があっているかを一目でわかることが大切です。

レビューイはスクリーンショットを撮るために、当然手元で実装物を再現させる必要があります。

動作確認してからPRを出すのは当然ですが、複数パターン考えられるものを撮ったりするうちに、考慮漏れに気づいたり、モバイルサイズにした時に思わぬ挙動を見つけたりするのではないかと思います。私もこの段階で考慮漏れに気づくことがありました。

手元での動作確認は基本の所作ですが、 スクリーンショットを撮るということをフローに入れるだけで、うっかりは少なくなるはずです。

レビュアーも手元で再現させるのは当然ですが、PRで見るべき箇所がわかりやすいのでレビューしやすくなります。

やらないことを明記した

開発期に関しては、PRをためてしまい脳内バッファを消費することがないように、多少中途半端であってもmergeしてしまうことが大切と考えます。

また、完成度の高い物を作っても直前に変わる可能性もあるため、過度な作り込みは厳禁です。

とはいえ、中途半端なものがリリースされてしまっては問題なので、PRに明記することとチケットやコード内 FIXME などで残すようにしています。

ここで、想定している「ここでは積み残している事」を共有する事で、レビュー時に実装者の考慮漏れを見つけることができますし、積み残しを個人のタスクからチームのタスクに開放することが出来ます。

手戻りを発生させないようにどうしたか

手戻りの原因は沢山あると思いますが、一つはエンジニア以外とのコミュニケーション不足で起こるものがあると思っています。

これに関しては、PRにスクリーンショットを貼ることである程度対応ができました。

PRに貼るスクリーンショットをアニメーションGifにしておくと、連携したチャットツール(Slack)にPRに貼られた画像が流れます。Slackに動く画面が流れれば、エンジニア以外も実装している内容に関して興味が持てるようになります。

このPRの動くスクリーンショットと、Slackの絵文字コミュニケーションとあわされば、実装中のものに対して誰でもリアクションが出来る状態が保たれます。


※ 価格データなどはランダムなものを使っています
※ 実際のSlackの画像を編集しています

これによって成果物をベースとしたチーム全体の認識共有に繋がったと思います。 対面での進捗報告や、確認環境へのデプロイも大切ですが、もっと周囲がフォローしやすい形に持っていく事で、実装の認識の齟齬を発生しにくくすることができました。

まとめ

ラクスルテレビCMオンラインストアの初期開発では、PRをこまめに出すことと動くスクリーンショットを貼ることを心がけました。

まわりの関心を引きつけつつ、抜けもれなく開発を進めていました。

フェーズやチーム構成によって最適な進め方は違うと思いますが、参考になると幸いです。

ラクスルでは、新サービス開発をリードするフロントエンドエンジニアを募集しています。

 

ハコベルコネクトをリリースしました!

サーバサイドエンジニアの加藤です。
昨年8月に印刷から運送マッチングサービスのハコベルのチームに異動し、ハコベルコネクトの開発を進めてきました。

ハコベルコネクトとは

現在の物流業界における最大の課題はドライバー不足。ハコベルチームでは、現場の課題を調査し、その原因を探ってきました。見えてきたのは、複数の運送会社によって仕事が行われていることで、システム化が進まず紙・電話・FAXなどアナログで生産性を上げにくい現場環境でした。

ハコベルコネクトは、この情報断絶を解決すべく、大手物流荷主、一般貨物事業者など運送会社を自由度高くつなぐ物流プラットフォームを目指しています。

先月 1月24日に記者発表をし、日経新聞やTechCrunchにも取り上げられました。弊社CTOの泉がスマホのGoogle Chromeの新規タブで出てきたとのことで、社内でもちょっとした話題になりました。

今までも提供してきたサービスは、ハコベルカーゴ※に名称変更。これからもラストワンマイル向けのマッチングサービスを提供していきます。

仕事をする人に心地よい体験を

ハコベルコネクトは、PMやデザイナー・エンジニアが現場に足を運び、MVPを開発、実証実験を重ねて、徐々にその姿を明らかにしてできてきたプロダクトです。いくつもの運送会社の事業所に出向き、たくさんの方々にインタビューさせていただいたり、トラックに同乗させていただいたり。仕事をする人がどんな課題と向き合っているのか。様々なプロセスを経て、方向性が定まってきました。

ドライバーアプリイメージ

 

ハコベルコネクトという名前もその中で生まれてきました。SNSのように、会社と会社がつながりスムーズに情報のやりとりができることで、快適に仕事が出来るようにという想いが込められています。

ハコベルコネクトイメージ

技術負債の芽を最低限に ー今しかないでしょ!ー

さて、プロダクトとしてのリリースに向け、エンジニアとしてはどんなチャレンジがあったでしょうか。

  • 実証実験向けに急いで作られた側面があったため、既に技術負債気味なところがある
  • 業界独自の業務をモデリングしているため、キャッチアップしにくい
  • よくある機能でも複雑度が高く、要件の不整合が起きて開発が進みにくい

ハコベルチームには、私を含めラクスルの開発に関わってきたメンバーもいます。

「そうだ、ラクスルを作り直そう!」という投稿や「生まれ変わらNight -技術的負債からの一発逆転-」というイベントでご紹介させて頂いた通り、ラクスルは技術負債の課題に向き合ってきました。

(ちなみにまだまだ先はありますが、経営陣の理解もあり、ラクスルの技術負債の解消は着々と進んでいます。)

その教訓を活かして、ハコベルコネクトでは、リリース前に負債の芽の解消にも時間を使ってきました。リリース前ならば、ユーザー影響を気にせずにあらかじめアーキテクチャの整備を進めることが出来ます。「今しかないでしょ!」を合言葉に、気なっていたところはどんどん書き直しました。

ただし、特定業界向けのSaaSというサービスの成長特性を考えて、最初からドメイン分割やマイクロサービスを採用することはしていません。ラクスルで蓄積してきているベストプラクティスを取り入れ、まずはRails アプリケーションとしての Rail にきれいに乗るというところに集中しました。

フロントは、ラクスルの他のプロダクトでも採用しているVue.jsを使い、実証実験後にUIをフルリニューアル。Web APIが必要だったため、コントローラやサービスは約80%を書き換えました。

Web APIの開発中には、GraphQLが話題になったり、gRPC-Webが正式リリースになったりしたタイミングで、チーム内でGraphQLのPOCも行なったりしていたのですが、開発の状況を考慮して今回はオーソドックスにRESTful APIで開発していくことにしました。

フロントメンバーとのコミュニケーションやAPI エンドポイントの可視化のため、API仕様はSwaggerで記述することにしています。

チームでプロダクトを開発する ーペア&モブプロ、デザインスタジオー

先ほども書いた通り、ハコベルコネクトは、業界独自の業務をモデリングしているためキャッチアップしにくくチームの生産性がなかなか上がりにくい状態でした。

6ヶ月間でチームも倍増。新メンバーのキャッチアップスピードをあげたり、モチベーションを保ちつつ機能開発スピードを上げるのが重要課題になっていました。

そのため、複数人でコーディングするモブプログラミングやペアプログラミングを取り入れて、難しいドメイン知識を共有しつつ開発を進めたり、モチベーションが上がりにくい機能開発をわいわいと議論しながら進めました。

モブプログラミング用のスペースも導入され、今ではハコベルだけでなく他のチームで取り入れています。

モブプログラミングの様子

また、ラクスルの他のチームで行なっていた、コラボレーティブデザインの手法である「デザインスタジオ」も取り入れました。機能に対して色々なアイデアが出るのはもちろん、デザイナーも含めてこれから作る機能のデータ構造を共有したり、機能の背景を理解するのに役に立っています。

ハコベルチームには、運送業界出身のメンバーもいます。要件がわからない時はすぐに話を聞けるのも、チームで開発を進める上ですごく助けになりました。

新メンバー募集中です

さて、ハコベルコネクトはリリースしましたが、私たちの毎日を支えてくれている物流の現場には課題がたくさんあります。課題を解決すべく、ハコベルコネクトも成長させていきたいと思っています。

「仕組みを変えれば、世界はもっとよくなる」

エンジニアリングの力で世界を変えたいフロントエンドエンジニア、サーバサイドエンジニアを絶賛募集中です。興味を持たれた方は是非一度オフィスに遊びにきてください!

※ 2019/3/4 ハコベルマッチングからハコベルカーゴに再名称変更したためブランド画像更新しました。

“CircleCI agent received a kill signal midway through the job” と急に言われるようになった話(2/12追記)

ラクスルでサーバサイドエンジニアをやっている小林です。

追記(2019/02/12)

CircleCI のバグ(?)だったようで、すでに修正されてます。

また、原因を少し追ったので、追記しました。

結論

CircleCI の command 内で exit すると、エラーになるので、

true / false コマンドを使って回避しました。

 

本編

今日も元気に開発を行っていたら、CircleCI のテストが下記のようなエラーで

失敗するようなりました。

最初、メモリが足りなくて殺されたのかなと思い、Rebuild with SSH でコンテナに ssh して、

topps を見ていたのですが、どうやらメモリ不足というわけではなさそうでした。

また、過去にテストの通っていたブランチを Rebuild してもテストがコケるので、

CircleCI の挙動が何かしら変わったのかなと思い、.circleci/config.yml の設定を見直してみました。

すると、command 内で下記のようなことをしているコードがありました。

status=0
for file in $(
  circleci tests glob \
  "src/*/*Bundle/Tests/**/*Test.php" | \
  circleci tests split --split-by=timings
)
do
  php ./bin/phpunit -c app --log-junit $CIRCLE_TEST_REPORTS/phpunit/${file}.junit.xml ${file}
  if [ $? -ne 0 ]; then status=1; fi
done
exit $status

最後の exit が明らかに怪しいので、試しに消してみたところテストが通りました。

どうやら、exit すると circleci-agent も死ぬようになったのかなと推測されます。

というわけで、下記のように true / false コマンドを使うように修正しました。

status=true
for file in $(
  circleci tests glob \
  "src/*/*Bundle/Tests/**/*Test.php" | \
  circleci tests split --split-by=timings
)
do
  php ./bin/phpunit -c app --log-junit $CIRCLE_TEST_REPORTS/phpunit/${file}.junit.xml ${file}
  if [ $? -ne 0 ]; then status=false; fi
done
$status

変数にコマンドを代入すると、その変数を評価することで、コマンドを実行することができます。

2時間ほどハマったので、同じようにハマった方のお役に立てれば幸いです。

 

追記(2019/02/12)

CircleCI の挙動が何かしら変わった

のところを、もう少し深ぼってみました。

まず、再現条件をもう少し明確にするために、空のリポジトリに下記のような .circleci/config.yml を用意して CircleCI を走らせてみました。

version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.5.1

    steps:
      - checkout

      - run:
          command: exit 0

しかし、これではテストは失敗しませんでした。

問題の起きた .circleci/config.yml と見比べてみると、問題の起きたテストでは shell を変更していたので、下記のように .circleci/config.yml を修正してみました。

version: 2
jobs:
  build:
    docker:
      - image: circleci/ruby:2.5.1

    shell: /bin/bash --login

    steps:
      - checkout

      - run:
          command: exit 0

すると、前述のエラーと共にテストが失敗するようになりました。

shell を指定しない場合、 /bin/bash -eo pipefail で実行されているので、念の為、
/bin/bash -eo pipefail --login を設定してみましたが、やはりテストが失敗しました。

どうやら、/bin/bash --login を設定し、かつ exit するとダメなようです。

さて、--login オプションを指定すると、起動時に ~/.profile を、終了時に ~/.bash_logout を実行するようになります。

Man page of BASH#起動

そこで、Rebuild with SSH でログインして、~/.bash_logout の中身を見てみると、下記のようになっていました。

# ~/.bash_logout: executed by bash(1) when login shell exits.

# when leaving the console clear the screen to increase privacy

if [ "$SHLVL" = 1 ]; then
    [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q
fi

試しに、/usr/bin/clear_console を手動で叩いてみたところ、無事(?)「”CircleCI agent received a kill signal midway through the job”」というエラーと共にテストが失敗しました。

どうやら、/bin/bash --login で exit すると、~/.bash_logout内の /usr/bin/clear_console が実行され、テストが失敗する、というシナリオのようです。

さらに、/usr/bin/clear_console の中で何をやっているのかを追ってみました。

https://github.com/linuxmint/bash/blob/master/debian/clear_console.c

コードを見たところ、/dev/tty/dev/tty0/dev/console 、stdinstdoutstderr の順番に、ioctl(fd, KBDKBTYPE, &arg) を実行し、キーボードの種類が取得できたものについて、コンソールをクリアするという処理を行っていました。

特に kill している風でもなかったので、また、Rebuild with SSH でコンテナにログインして、開いているデバイスファイルを順に確認することにしました。

screen コマンドをインストールし、順番にデバイスファイルに接続していきます。

すると、screen /dev/console を実行すると、「”CircleCI agent received a kill signal midway through the job”」とエラーになってしまいました。

どうやら、/dev/console を参照しようとすると、エラーになるようです。

と、ここまで調べたところで、CircleCI側で修正されたようで、/dev/consoleを参照しても、エラーにならなくなりました。

無事、修正されたということで、追加の調査はここまでになりました。

MeetUpシールがとことん簡単に作れるプロダクトの話

突然ですがシールの作り方、わからなくないですか!?

ラクスルなら誰でも簡単にデザインできるサービス担当の武政です。

弊社でもミートアップや勉強会がよく行われていますが
企画にステッカーがあると一体感がでてテンションも上がりますよね。

でも忙しい中でデザイナーさんにお願いするのは申し訳ない…外注だと予算もかかる…
そんなお悩みの声に応えて、パパッとステッカーを制作できるプロダクトをリリースしました!

オンラインデザインのシール・ステッカー・ラベルです。

  • 円形、正方形、長方形が合計9サイズ
  • シール・ステッカーのテンプレートも約300点公開(2018/11現在)

MeetUp用のシールを作ろう!

私もオンラインデザインで、リリース記念のシールを作ってみました

MeetUp用シールの無料デザインテンプレートも公開!

ミートアップですぐ使えるテンプレートも用意しました!
ぜひロゴやテキスト入れて遊んでみてください。
※画像をクリックするとオンラインデザインに遷移します

①ミートアップ:おしゃれ  (円形 直径50mm)
円形はPCに貼るには定番ですね

テンプレート編集はこちらから>>

②ミートアップ:シンプル (正方形 50*50mm)
ロゴを置いて、背景色をロゴ内の色に変えるだけでそれらしくなります

テンプレート編集はこちらから>>

シールでこんな遊び方も!?

少年時代に熱中したキラキラ風シールも作れちゃいます。
③キラキラ風シール:※ホログラム加工ではありません (正方形 50*50mm)

テンプレート編集はこちらから>>

シールになった弊社CTOもニッコリ。

シール制作プロセスの何をシステムで解決したのか?

シールのデータ制作はコンテンツとしては驚くほど簡単ですが
制作データの構造が難しいという不思議な商品です。

  • 具体的に難しいポイントは「カットパス」データの作成
  • カットパスとはシールの形に切り抜くためのパスデータのこと
  • カットパスと聞いた瞬間に印刷業界以外の方は「んんん?」となりますよね

デザイナーさん以外にはこの「カットパスの理解と制作」が難しい。
これがシール作成における「できる/できない」を決定づける障壁です。


システムが解決したシール制作者の課題は「カットパスをつくる必要がない」という部分です。
これには制作が簡単になることに加え、制作作業の大幅な短縮効果があります。

このようにしてシールが簡単に作ることができるプロダクトができました。
ぜひお試しください!
https://raksul.com/online-design/sticker/

ラクスルではエンジニアを積極採用しています

ラクスルは画像処理や印刷技術、SVGに関わる開発ができるレアな環境です。
興味を持たれた方は是非一度オフィスに遊びにいらしてください!

WebpackerをやめるならWebpackManifestというgemが便利、という話

先日、社内のSlackでpixivさんのブログ記事 今日から簡単!Webpacker 完全脱出ガイド がシェアされてて、『あっ、これは…弊社でもやったやつではないか。』とおもいました。Webpackerは便利なんですけどね。

本記事はこのpixivさんのポストを受けて WebpackManifest というgemを紹介します。

ラクスルでのWebpackerを辞めた経緯

  • もともとWebpackerを使った管理画面プロジェクトがあった
  • そこにECサイトも乗せるようなった
  • package.jsonは管理画面、ECサイトで分けて管理したかった
  • Webpackerは1個のpackage.json、1個のwebpackコマンド、1個のmanifest.json前提の作りなので、package.json分けて複数のwebpackビルド処理系を作りたいラクスルの用途に合わなかった => 脱Webpacker

pixivさんのブログで紹介されてるとおりで、manifest.json を Rails に組み込むための view helper が必要になったので、弊社内でも lib/ 以下に小さなライブラリを作っていました。

gem化

そして、社内で他にもRailsアプリが立ち上がりだしてきて、『そろそろ、gem化せななあ』とおもっていたところにこのpixivさんの記事でしたので、本記事執筆にあたって WebpackManifest というgemにしました。rubygemsよりインストール可能です。このgemを使うとwebpackerを使わずに webpack の webpack-manifest-plugin が出力するmanifest.jsonに従ってview helperが asset のパスやscriptaタグをrenderingしてくれるようになります。

もともとの社内にあった view helperのメソッド名よりpixivさんのメソッド名のほうが適切でしたので、ヘルパー実装部分はpixivさんの実装を参考に組み込み直しました。

使い方

  • Webpacker gem のアンインストール
  • 代わりになる webpack.config.js の作成
  • 素のwebpackの webpack-manifest-plugin を用いて manifest.json を出力する
  • WebpackManifest gemをインストールし、↑のmanifest.jsonのパスをセットする(詳細はgemの README を参照する)
  • gem付属のview helperを使う

という流れになります。

不具合等ありましたらPRいただければとおもいます。

まとめ

WebpackManifest というgemを使ったWebpackerをやめる方法をご紹介しました。

ラクスルではエンジニアを絶賛募集してます

ご興味ありましたらどうぞオフィスへ遊びに来てください。