[Ruby] Avoid the problem that session cannot be acquired when upgrading from Rails 4.2.x to 5.0.x when releasing canary.

1 minute read

Introduction

  • Canary release is a deployment method that releases a new version of the application to only a part of multiple servers
  • When upgrading from Rails 4.2.x to 5.0.x, doing a canary release, that is, creating a environment where Rails 4.2.x and 5.0.x applications are mixed, there is a problem that session can not be acquired, so avoid this Want to

I don’t know if anyone would upgrade to Rails 5.0.x (and with a canary release in between) at this time, but I hope someone can help :pray:

Since it is intended for those who are familiar with Ruby and Rails to some extent, basic explanations such as session and rack in Rails are omitted.

Solution

  • Fix the rack gem version to 2.0.7

Cause in one word

Due to Rails 4.2.x -> 5.0.x upgrade, rack gem is updated to 2.0.8 or above. (There is a breaking change in session_id generation logic in rack 2.0.7 -> 2.0.8)

See. https://github.com/rack/rack/blob/master/CHANGELOG.md#208—2019-12-08

Explanation

[Lib/rack/session/abstract/ of rack 2.0.7…2.0.8 difference Looking around id.rb, lib/rack/session/memcache.rb` is very easy to understand.

  • Until rack 2.0.7, _session_id (Rails side naming)wasusedasthekeyofthesessionstore(Redis,Memcached,etc.)
  • From rack 2.0.8, the value of _session_id Digest::SHA256.hexdigest is used as a key (the code is here,public_idequals_session_id)
  • Each session store gem has a method for fallback called #get_session_with_fallback (for redis-rack,ForMemcache), so you can get session data generated by an older version of rack from a newer version of rack, but not vice versa

From the above, there is no problem if you deploy a new version of rack gem to all servers at once, but if you have an environment (canary release environment) in which rack gems of 2.0.7 or lower and 2.0.8 or higher are mixed on each server, session Cannot be obtained.