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

inFablic

Fablic開発者ブログ

大江戸Ruby会議06参加レポート

イベントレポート Ruby

去る2017-03-20、Fablic社員数名で、大江戸Ruby会議06に参加してきました!

twitter.com

今回は、Rubyの地域コミュニティ中でも最高レベルに重鎮が集うこの大江戸Ruby会議06参加レポートをお送りします。

  • 大江戸Ruby会議とは
  • 午前の部
    • Docker時代の分散RSpec環境の作り方 / 橋立友宏 @joker1007
    • My Open Source Journey / Juanito Fatas @JuanitoFatas
    • Text Editing in Ruby / 前田修吾 @shugomaeda
    • 招待講演 / Ruby考古学II 1993-1997 / 石塚圭樹 @keiju_ishitsuka
  • 昼食
  • 午後の部
    • 多相型、推論、Ruby / 松本宗太郎 @soutaro
    • esaとRubyistと私(仮)/ 赤塚 妙子 @ken_c_lo
    • Rationalを(もうちょっと)最適化してみた / 斎藤ただし @tad
    • フルタイム コミッター大戦 / 中田伸悦 @n0kada Urabe Shyouhei @shyouhei 笹田耕一 @ko1 Kenta Murata @mrkn
    • 高濃度雑談 / Tatsuhiro Ujihisa @ujm
    • Ruby 2.4 Internals / 笹田耕一 @ko1
    • 如何にして若き天才コミッタは生まれるのか / Sho Kusano @rosylilly
    • Keynote / Sorah Fukumori @sora_h
  • おまけ: 懇親会の様子
  • FablicでのRuby

文責: id:ujihisa and 岸

続きを読む

Railsにおけるレコード作成時のレースコンディションについて

エンジニアリング

こんにちは。サーバサイドエンジニアの @yamy です。

フリルでは商品情報など様々なレコードが作成されています。 今回は、レコード作成時にレースコンディションが発生した件についてお話しします。

レースコンディションとは

「レースコンディション(競合状態、Race Condition)」とは、並列で走る複数の処理(プロセスやスレッド)が、共有のリソースへほぼ同時にアクセスしたとき、処理のタイミングによって想定外の結果をもたらすことをレースコンディションと呼びます。

一般的なレースコンディションの例を以下に記載します。

  • スレッドAが17を取得
  • スレッドBもほぼ同時に17を取得
  • スレッドAが18にインクリメントして保存
  • スレッドBも18にインクリメントして保存(オーバーライト)
  • 期待した19ではなく18として保存されてしまう

f:id:infablic:20170315130020p:plain

フリルでのケース

あるトランザクション内において、レコード作成処理と関連リソースの更新処理があるとします。

def create
  ActiveRecord::Base.transaction do
    return unless creatable?

    # レコード作成処理
    Product.create!(
      foo: 'bar',
    )

    # 更新処理
    ...
  end
end

creatable? は、Productレコードの存在をチェックし、以降の処理をすべきかの判定をするものとします。 ここで、複数プロセスA,Bが同時に処理された場合、creatable?のブロック条件に該当するはずのところ、レースコンディションによりすり抜けてしまい、以下のようなエラーになる可能性があります。ユニーク制約をかけているので Duplicate entry となっています。

A> BEGIN
B> BEGIN
A> INSERT INTO `products` (`foo`) VALUES ('bar')
B> INSERT INTO `products` (`foo`) VALUES ('bar') <- Duplicate entry 'bar' for key 'index_products_on_foo'

Productの重複登録は避けれていますが、プロセスBにはプロセスAの処理を待ってから処理してほしいところです。

楽観的ロック

レースコンディションへの対応として、Railsでは「楽観的ロック」「悲観的ロック」と呼ばれる排他制御が提供されています。

「楽観的ロック」とは、「競合は多分起きないだろう」という前提で、データの更新時に競合をチェックする方法です。ActiveRecordでは、lock_versionというバージョン管理向けのカラムを追加するだけで楽観的ロックを利用できます。

レコードの更新時に1づつインクリメントし、更新時にデータ取得時のロックバージョンと異なっている場合、競合が発生したと判断し ActiveRecord::StaleObjectError を発生させます。

カラム追加の必要があるため、フリルでは利用を見送りましたが、以下に簡単な利用方法を記載します。Productsモデルを例にしています。

マイグレーションファイルの追加

rails g migration add_lock_version_to_products lock_version:integer
class AddLockVersionToProducts < ActiveRecord::Migration
  def change
    add_column :products, :lock_version, :integer, default: 0, null: false
  end
end

マイグレーションの実行

rake db:migrate

これで、Productsモデルで自動的に楽観的ロックが行われるようになります。

悲観的ロック

「悲観的ロック」とは、「競合が発生する可能性が十分ある」という状況に向いた排他的なロック手法です。SELECT … FOR UPDATE によりレコード取得時にロックを行い、ロックされたレコードを更新できないようにする仕組みです。

def create
  ActiveRecord::Base.transaction do
    item.lock!
    return unless creatable?

    # レコード作成処理
    Product.create!(
      foo: 'bar',
    )

    # 更新処理
    item.update!(
      status: 2,
    )
    ...
  end
end

ここで、共有リソースのitemという更新対象のオブジェクトがあるとします。トランザクションの冒頭で共有リソースに対してitem.lock!を実行しています。モデルオブジェクトのインスタンスメソッドのlock!は、そのオブジェクトのテーブルレコードに対しての悲観的ロックを取得します。

あるプロセスAとBがほぼ同時に処理を開始し、プロセスAが一瞬早く呼び出された場合、プロセスBは共有リソースであるitem.lock!のところで待たされるため、プロセスAのトランザクションが完了するまで先へは進めません。 これにより、レースコンディションを防ぐことが可能となります。

なお、トランザクション内から別メソッド呼び出しでlock!を行なっている場合、想定したロックが掛からないケースがあるので、テストケースなど十分な検証が必要です。

まとめ

レコード作成時にレースコンディションが発生した件についてお話ししました。同時アクセスなどによる非常に検出しづらい問題ではありますが、Railsのメソッドとしてロック機構が提供されているので、そこまでの手間を掛けずに対応することが出来ました。

参考

Fablicでよく利用されるデザインの検証手段

f:id:kurechon:20170308182821j:plain

こんにちは!デザイナーのくれちょんです。

2016年の末に株式会社basicさんで行われたNextstage Design Niteというイベントにて、チームを動かすデザイナーというタイトルで登壇させていただきました!Fablicでのデザイナーの働き方についてをメインにご紹介させていただきましたが、時間の都合上詳しくお話ししきれなかったデザインの検証手段についてこの記事でより詳しくご紹介させていただこうと思います。

続きを読む

Android版フリルにおけるMaterial Designへの対応とガイドラインの捉え方

Android

こんにちは。Androidエンジニアの @nakamuuu です。

1月24日(火)に株式会社Loco Partnersさんのオフィスで行われた App Talk Night by Relux に参加させていただきました。このイベントはGoogle Playの「ベストオブ 2016」に選出されたアプリデベロッパー5社から開発体制や受賞に至るまでの裏側についてお話しさせていただくというものでした。

自分からは 「Android版フリルにおけるMaterial Designへの対応とガイドラインの捉え方」 というテーマで、フリルでは早期からMaterial Design対応を進めてきたこと、そしてその過程で僕らが感じてきたMaterial design guidelinesに準拠することのメリットを紹介させていただきました。

続きを読む

Android版フリルでの商品画面リニューアルにおけるCollapsingToolbarLayoutを用いたレイアウト構築

Android

この記事はFablic Advent Calendar 22日目の記事です。 http://qiita.com/advent-calendar/2016/fablic

こんにちは。Androidエンジニアの @nakamuuu です。

フリルは2016年10月、ロゴやアイコン、アプリ全体のカラーリングの変更を含む大規模なリニューアルを行いました。

Android版フリルではリニューアルに合わせ、商品画面の改修もしています。今回はこの商品画面でのCollapsingToolbarLayoutを用いたレイアウト構築、特に各Viewに指定されている fitsSystemWindows のパラメータの役割について実装時に少し掘り下げて調べてみたので書いていきたいと思います。

f:id:nakamuuu-muuu:20161222111315j:plain

続きを読む

デザイナーが1人でキャンペーンを設計から運用までしてみて良かったこと

f:id:kobachicchi:20161222180151j:plain

こんにちは。Fablicのデザイナーのkobachiです。 現在は主にキャンペーンの運用をしています。

この記事は、 Fablic Advent Calender 2016 20日目の記事です。

Fablicでは、デザイナーも1からキャンペーンを設計・実装・運用を行います。 1から…と聞くと大変そうに聞こえるかもしれませんが、 やってみて良かった点がいくつかあるので、ぜひ紹介したいと思います。

続きを読む

Fablicでの Codenize.tools を使ったインフラ管理について

この記事はFablic Advent Calendar 19日目の記事です。 http://qiita.com/advent-calendar/2016/fablic

こんにちは、Fablicでサーバーサイドエンジニアをやっている yutadayo です。

今回は AWS の環境設定をコードで管理できる Codenize.tools の紹介と弊社での運用事例についてご紹介しようと思います。

続きを読む

Railsログを美しく Beautiful::Log

この記事はFablic Advent Calendar 15日目の記事です。 http://qiita.com/advent-calendar/2016/fablic

はじめまして、Fablicでサーバーサイドエンジニアをやっている岸と申します。

今年の6月、Fablicにジョインして初めてRuby/Railsに触りました。

それまでJavaがメインだった*1僕にとってはRailsは気がきいて柔軟性がハンパないので、超楽しく開発しています。その一方で、Atom/Vimとターミナルでの開発は、立派な無償IDEであるeclipseと比べるといささか心もとない気がしました。*2

一番に気になったのはログ周りでした。Logger/Appenderのことにも触れていきたいのですが、一番身近なのは開発中や不具合調査中のコンソールログ

これをキレイにするgem、beautiful-logを作ってみたのでご紹介します。

https://github.com/nogahighland/beautiful-log

*1:GroovyというRubyを参考にしたJVM言語と、Railsを参考にしたGrailsというフレームワークも一応使っていたんですよ

*2:RubyMineとかもっと良いのかもしれませんが、有償IDEにまだ抵抗あり使ったことない…

続きを読む

フリルのiOSアプリ開発におけるエンジニアとデザイナーの作業分担について

こちらはFablic Advent Calendar 2016の記事です。

こんにちは。FablicのiOSエンジニア、shobyです。

iOSエンジニアの皆さんは、デザイナーとどういった形で仕事を進めているでしょうか。

iOSアプリの開発はWebの開発と異なり、UIとロジックを完全に分離することが困難なため、エンジニアとデザイナーの責任範囲が曖昧です。 どこまでエンジニアが担当し、どこまでをデザイナーが担当するかは悩みが多いと思います。

現在、フリルのiOSアプリ開発は、デザイナーがSketchでデザインし、エンジニアがSketchファイルを見ながらUIを実装する方式で進めています。

フリルではこの方式を取り入れることで、デザイナーにStoryboard上でのUI調整を任せていた時期に比べ、開発速度が向上するメリットが得られました。

この記事では、フリルのiOSアプリ開発における、エンジニアとデザイナーの作業分担を、どのように行ってきたかお話しします。

続きを読む

芯を通すリブランディング -デザインに入るまで- (@wariemon)

f:id:wariemon:20161214114759p:plain

こんにちは。Fablicのデザイナーのわりえもん (@wariemon) です。
この記事は Fablic Advent Calender 2016 の記事です。
 
フリルのリブランディングを担当した際に、新規のブランドつくりと違うチェックポイントが存在することに気づきました。
その上でリブランディングにおいて、非常に重要な「デザインに入るまでのプロセス」についてお話させていただきます。