Class: HotTub::Sessions

Inherits:
Object
  • Object
show all
Includes:
KnownClients, Reaper::Mixin
Defined in:
lib/hot_tub/sessions.rb

Constant Summary collapse

MissingSession =
Class.new(Exception)

Constants included from KnownClients

KnownClients::KNOWN_CLIENTS

Instance Attribute Summary collapse

Attributes included from Reaper::Mixin

#reap_timeout, #reaper, #shutdown

Instance Method Summary collapse

Methods included from Reaper::Mixin

#kill_reaper, #spawn_reaper

Methods included from KnownClients

#clean_client, #close_client, #reap_client?

Constructor Details

#initialize(opts = {}, &default_client) ⇒ Sessions

HotTub::Sessions simplifies managing multiple Pools in a single object and using a single Reaper.

Example:

sessions = HotTub::Sessions(:size => 10) do |url|
uri = URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
http.start
http
end

# Every time we pass a url that lacks a entry in our
# sessions, a new HotTub::Pool is added for that url
# using the &default_client.
#
sessions.run("https://www.google.com"") do |conn|
p conn.get('/').code
end

sessions.run("https://www.yahoo.com"") do |conn|
p conn.get('/').code
end

# Lazy load a non-default connection

excon_url = "http://somewebservice2.com"

sessions.stage(excon_url,{:size => 5}) {
Excon.new(excon_url, :thread_safe_socket => false)
}

# Excon connection is created on the first call to `.run`
sessions.run(excon_url) do |conn|
p conn.head.code
end


# Add a connection, which returns a HotTub::Pool instance

excon_url2 = "http://somewebservice2.com"

MY_CON = sessions.add(excon_url2,{:size => 5}) {
Excon.new(excon_url2, :thread_safe_socket => false)
}

# Uses Excon
MY_CON.run(excon_url) do |conn|
p conn.head.code
end

OPTIONS

&default_client
An optional block for a default client for your pools. If your block accepts a
parameters, they session key is passed to the block. Your default client
block will be overridden if you pass a client block to get_or_set

[:pool_options]
Default options for your HotTub::Pools. If you pass options to #get_or_set those options
override :pool_options.

[:name]
A string representing the name of your sessions used for logging.

[:reaper]
If set to false prevents a HotTub::Reaper from initializing for these sessions.

[:reap_timeout]
Default is 600 seconds. An integer that represents the timeout for reaping the pool in seconds.


80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/hot_tub/sessions.rb', line 80

def initialize(opts={}, &default_client)
  @name                 = (opts[:name] || self.class.name)
  @reaper               = opts[:reaper]
  @reap_timeout         = (opts[:reap_timeout] || 600)
  @default_client       = default_client
  @pool_options         = (opts[:pool_options] || {})

  @_staged              = {}
  @_staged.taint
  
  @_sessions            = {}
  @_sessions.taint

  @mutex                = Mutex.new
  @shutdown             = false

  at_exit {shutdown!}
end

Instance Attribute Details

#default_clientObject

Returns the value of attribute default_client.



6
7
8
# File 'lib/hot_tub/sessions.rb', line 6

def default_client
  @default_client
end

#nameObject

Returns the value of attribute name.



6
7
8
# File 'lib/hot_tub/sessions.rb', line 6

def name
  @name
end

Instance Method Details

#clean!Object



172
173
174
175
176
177
178
179
180
181
# File 'lib/hot_tub/sessions.rb', line 172

def clean!
  HotTub.logger.info "[HotTub] Cleaning #{@name}!" if HotTub.logger
  @mutex.synchronize do
    @_sessions.each_value do |pool|
      break if @shutdown
      pool.clean!
    end
  end
  nil
end

#delete(key) ⇒ Object

Deletes and shutdowns the pool if its found.



144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/hot_tub/sessions.rb', line 144

def delete(key)
  deleted = false
  pool = nil
  @mutex.synchronize do
    pool = @_sessions.delete(key)
  end
  if pool
    pool.shutdown!
    deleted = true
    HotTub.logger.info "[HotTub] #{key} was deleted from #{@name}." if HotTub.logger
  end
  deleted
end

#drain!Object



183
184
185
186
187
188
189
190
191
192
# File 'lib/hot_tub/sessions.rb', line 183

def drain!
  HotTub.logger.info "[HotTub] Draining #{@name}!" if HotTub.logger
  @mutex.synchronize do
    @_sessions.each_value do |pool|
      break if @shutdown
      pool.drain!
    end
  end
  nil
end

#fetch(key) ⇒ Object Also known as: []



158
159
160
161
162
163
# File 'lib/hot_tub/sessions.rb', line 158

def fetch(key)
  unless pool = get(key, &@default_client)
    raise MissingSession, "A session could not be found for #{key.inspect} #{@name}"
  end
  pool
end

#get(key) ⇒ Object

Returns a HotTub::Pool for the given key. If a session is not found and the is a default_client set, a session will be created for the key using the default_client.



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/hot_tub/sessions.rb', line 111

def get(key)
  pool = @_sessions[key]
  unless pool
    @mutex.synchronize do
      unless @shutdown
        @reaper = spawn_reaper if @reaper.nil?
        unless pool = @_sessions[key]
          settings = @_staged[key]
          clnt_blk = (settings[1] || @default_client)
          op = @pool_options.merge(settings[0])
          op[:sessions_key] = key
          op[:name] = "#{@name} - #{key}"
          pool = @_sessions[key] = HotTub::Pool.new(op, &clnt_blk)
        end
      end
    end
  end
  pool
end

#get_or_set(key, pool_options = {}, &client_block) ⇒ Object Also known as: add

Adds session unless it already exists and returns the session



133
134
135
136
137
138
139
140
# File 'lib/hot_tub/sessions.rb', line 133

def get_or_set(key, pool_options={}, &client_block)
  unless @_staged[key]
    @mutex.synchronize do
      @_staged[key] ||= [pool_options,client_block]
    end
  end
  get(key)
end

#reap!Object

Remove and close extra clients



221
222
223
224
225
226
227
228
229
230
# File 'lib/hot_tub/sessions.rb', line 221

def reap!
  HotTub.logger.info "[HotTub] Reaping #{@name}!" if HotTub.log_trace?
  @mutex.synchronize do
    @_sessions.each_value do |pool|
      break if @shutdown
      pool.reap!
    end
  end
  nil
end

#reset!Object



194
195
196
197
198
199
200
201
202
203
# File 'lib/hot_tub/sessions.rb', line 194

def reset!
  HotTub.logger.info "[HotTub] Resetting #{@name}!" if HotTub.logger
  @mutex.synchronize do
    @_sessions.each_value do |pool|
      break if @shutdown
      pool.reset!
    end
  end
  nil
end

#run(key, &run_block) ⇒ Object



167
168
169
170
# File 'lib/hot_tub/sessions.rb', line 167

def run(key, &run_block)
  pool = fetch(key)
  pool.run(&run_block)
end

#shutdown!Object



205
206
207
208
209
210
211
212
213
214
215
216
217
218
# File 'lib/hot_tub/sessions.rb', line 205

def shutdown!
  @shutdown = true
  HotTub.logger.info "[HotTub] Shutting down #{@name}!" if HotTub.logger
  begin
    kill_reaper
  ensure
    @mutex.synchronize do
      @_sessions.each_value do |pool|
        pool.shutdown!
      end
    end
  end
  nil
end

#stage(key, pool_options = {}, &client_block) ⇒ Object

Sets arguments / settings for a session that will be lazy loaded, returns nil because pool is not created



101
102
103
104
105
106
# File 'lib/hot_tub/sessions.rb', line 101

def stage(key, pool_options={}, &client_block)
  @mutex.synchronize do
    @_staged[key] = [pool_options,client_block]
  end
  nil
end