Class: RightSupport::Rack::SharedEnvironment

Inherits:
Object
  • Object
show all
Defined in:
lib/right_support/rack/shared_environment.rb

Overview

provides shared access to the Rack request environment hash for any method executing on the request thread without needing to pass the hash explicitly. explicit parameter passing is preferred when writing new code, of course, but it can be difficult to update old code with new parameters going several layers deep. this middleware attempts to simplify those changes.

note that only the request thread receives the environment hash so any threads spawned by the request thread will need to explicitly reference any needed hash values and/or the entire hash using the accessors.

Constant Summary collapse

ENVIRONMENT_HASH_SYMBOL =

the symbol that represents the Rack request environment hash in TLS.

:rack_request_environment_hash

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(app, options = {}) ⇒ SharedEnvironment

Returns a new instance of SharedEnvironment.

Parameters:

  • app (Object)

    to call

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :fiber_local (TrueClass|FalseClass)

    as false to set the environment hash visible to all fibers of the current thread (default) or true to set a fiber-local environment hash. if your app does not attempt to use fibers then either will work as every thread has a root fiber. if your app creates fibers while handling requests then the default of thread-local is probably best because the environment hash is shared with all fibers. keep in mind that the thread and its root fiber keep distinct hashes so you must reference one or the other.



49
50
51
52
53
54
55
# File 'lib/right_support/rack/shared_environment.rb', line 49

def initialize(app, options = {})
  options = {
    fiber_local: false
  }.merge(options)
  @app = app
  @fiber_local = !!options[:fiber_local]
end

Class Method Details

.get_environment_hash(fiber_local = false) ⇒ Hash

gets the environment hash for current thread or fiber.

Returns:

  • (Hash)

    environment hash or empty



85
86
87
88
89
90
91
92
93
94
95
# File 'lib/right_support/rack/shared_environment.rb', line 85

def self.get_environment_hash(fiber_local = false)
  current = ::Thread.current
  if fiber_local
    # note that in ruby 1.8 this would have referred to thread-local storage
    # but in ruby 1.9+ it refers to fiber-local storage.
    current[ENVIRONMENT_HASH_SYMBOL] || {}
  else
    # in ruby 1.9+ you must explicitly call for thread-local variables.
    current.thread_variable_get(ENVIRONMENT_HASH_SYMBOL) || {}
  end
end

.set_environment_hash(env, fiber_local = false) ⇒ TrueClass

sets the environment hash for current thread or fiber.

Parameters:

  • env (Hash)

    as environment hash or nil or empty

Returns:

  • (TrueClass)

    always true



102
103
104
105
106
107
108
109
# File 'lib/right_support/rack/shared_environment.rb', line 102

def self.set_environment_hash(env, fiber_local = false)
  current = ::Thread.current
  if fiber_local
    current[ENVIRONMENT_HASH_SYMBOL] = env
  else
    current.thread_variable_set(ENVIRONMENT_HASH_SYMBOL, env)
  end
end

Instance Method Details

#call(env) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/right_support/rack/shared_environment.rb', line 57

def call(env)
  # sanity check in case the application developer is unaware that the
  # execution model is using fibers instead of threads, etc.
  fail 'Environment hash is already set.' unless get_environment_hash.empty?
  set_environment_hash(env)
  return @app.call(env)
ensure
  # only intended for use by the application; middleware already has env
  # available on each call. reset to nil before falling back.
  # also note that there is no such animal as thread_variable_delete, etc.
  set_environment_hash(nil)
end

#get_environment_hashHash

Returns environment hash or empty.

Returns:

  • (Hash)

    environment hash or empty



71
72
73
# File 'lib/right_support/rack/shared_environment.rb', line 71

def get_environment_hash
  return self.class.get_environment_hash(@fiber_local)
end

#set_environment_hash(env) ⇒ TrueClass

Returns always true.

Parameters:

  • env (Hash)

    as environment hash or nil or empty

Returns:

  • (TrueClass)

    always true



78
79
80
# File 'lib/right_support/rack/shared_environment.rb', line 78

def set_environment_hash(env)
  return self.class.set_environment_hash(env, @fiber_local)
end