redis-session-store icon indicating copy to clipboard operation
redis-session-store copied to clipboard

Make low level session methods public

Open jsdalton opened this issue 8 years ago • 3 comments

Recently, while writing some code to access session data at a low level, we ran into an issue with RedisSessionStore because it defines the following low level session methods (and aliases) as private:

  • #get_session
  • #find_session
  • #set_session
  • #write_session
  • #destroy_session
  • #delete_session

These methods are marked as private in the various inheritance trees of RedisSessionStore (via ActionDispatch::Session::AbstractStore):

  • In Rails 4, which uses Rack 1.6, the low level session methods are defined (and marked as private) in Rack::Session::Abstract::ID
  • In Rails 5, which uses Rack 2.0 the low level session methods are defined (and marked as private) in Rack::Session::Abstract::Persisted.

So at first glance, it seems that RedisSessionStore is correct in maintaining the private visibility level.

The problem, however, is that the vast majority of real world session store implementations override the parent visibility settings and mark these low level session methods as public.

A non exhaustive list of Rack-based session stores in the wild where these methods are public, not private:

  • Rack::Session::Abstract::ID in Rack >2.0 (in https://github.com/rack/rack/blob/2.0.1/lib/rack/session/abstract/id.rb#L414-L431)
  • Rack::Session::Pool (in https://github.com/rack/rack/blob/master/lib/rack/session/pool.rb#L44-L66)
  • Rack::Session::Memcache (in https://github.com/rack/rack/blob/master/lib/rack/session/memcache.rb#L49-L76)
  • ActionDispatch::Session::CacheStore since Rails 3.2 (in https://github.com/rails/rails/blob/master/actionpack/lib/action_dispatch/middleware/session/cache_store.rb#L20-L43)
  • ActionDispatch::Session::MemcacheStore via Rack::Session::Dalli, which it inherits from (in https://github.com/petergoldstein/dalli/blob/v2.7.6/lib/rack/session/dalli.rb#L22-L34 and https://github.com/petergoldstein/dalli/blob/v2.7.6/lib/rack/session/dalli.rb#L43-L71)
  • Rack::Session::Redis, used by the redis-store gem (in https://github.com/redis-store/redis-rack/blob/master/lib/rack/session/redis.rb#L45-L71)

As a counter example, ActiveRecordSession is the one session store I could find in the wild that preserves private visibility for these methods in https://github.com/rails/activerecord-session_store/blob/master/lib/action_dispatch/session/active_record_store.rb#L68-L120)

In short, RedisSessionStore's marking these methods as private, though consistent with its inheritance tree in both recent versions of Rails, is an outlier in the real world of session store implementations, including all of the persistent stores that are bundled with Rails.

The attached PR simply moves the low-level session methods to the public area of the RedisSessionStore class definition and adjusts the tests accordingly (i.e. so that they use the now public methods instead of send).

In addition to being consistent with other session store APIs in the wild, it's very helpful to be able to have proper access to the low level session store outside the context of a specific request. 😄

jsdalton avatar Jan 03 '17 11:01 jsdalton

Hi, this is very important commit. @jsdalton can you please rebase it. With master branch of rails we are receiving error

NoMethodError (private method delete_session' called for #RedisSessionStore:0x0000555c9eed60c0):`

and making methods public resolve this.

iggant avatar Oct 02 '20 08:10 iggant

@jsdalton can you please rebase your branch and resolve conflict

iggant avatar Oct 09 '20 19:10 iggant

@Jesterovskiy can you please review and change this PR?

iggant avatar Oct 21 '20 19:10 iggant