mongo_rack 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -15,17 +15,17 @@ require 'mongo_rack'
15
15
  task :default => 'spec:run'
16
16
 
17
17
  PROJ.name = 'mongo_rack'
18
+ PROJ.version = "0.0.3"
18
19
  PROJ.authors = 'Fernand Galiana'
19
20
  PROJ.email = 'fernand.galiana@gmail.com'
20
21
  PROJ.url = 'http://github.com/derailed/mongo_rack'
21
22
  PROJ.summary = "Rackable mongoDB based session management"
22
- PROJ.version = "0.0.2"
23
23
  PROJ.ruby_opts = %w[-W0]
24
24
  PROJ.readme = 'README.rdoc'
25
25
  PROJ.rcov.opts = ["--sort", "coverage", "-T"]
26
26
  PROJ.spec.opts << '--color'
27
27
 
28
28
  # Dependencies
29
- depend_on "rack" , ">= 1.0.0"
30
- depend_on "mongo" , ">= 0.18.1"
31
- depend_on "mongo_ext", ">= 0.18.1"
29
+ depend_on "rack" , ">= 1.0.1"
30
+ depend_on "mongo" , ">= 0.18.2"
31
+ depend_on "mongo_ext", ">= 0.18.2"
data/aa.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'rubygems'
2
+ require 'yaml'
3
+ require 'json'
4
+
5
+ class Fred
6
+ attr_accessor :blee, :duh, :zob
7
+
8
+ def initialize( blee, duh )
9
+ @blee = blee
10
+ @duh = duh
11
+ @zob = 100
12
+ end
13
+ end
14
+
15
+ f = Fred.new( 10, "Hello" )
16
+
17
+ buff = f.to_yaml
18
+
19
+ nf = YAML.load( buff )
20
+
21
+ puts nf.inspect
22
+
data/fred.rb ADDED
@@ -0,0 +1,26 @@
1
+ # tnum = 10
2
+ # r = Array.new(tnum) do
3
+ # Thread.new do
4
+ # puts "Making request"
5
+ # 10
6
+ # end
7
+ # end.reverse.map{|t| puts t.inspect;t.join; puts t.value }
8
+ #
9
+ # r.each do |res|
10
+ # puts "Checking request #{res}"
11
+ # end
12
+
13
+
14
+ a = Array.new( 10 ) do
15
+ Thread.new( 20 ) do |run|
16
+ puts "Blee + #{run}"
17
+ 20
18
+ end
19
+ end
20
+
21
+ puts a.inspect
22
+
23
+ b = a.reverse.map{ |t| t.join.value }
24
+
25
+ puts "Here"
26
+ puts b.inspect
@@ -2,6 +2,8 @@ require 'rack/session/abstract/id'
2
2
  require 'mongo'
3
3
  require File.expand_path( File.join( File.dirname(__FILE__), %w[mongo_rack session_hash.rb] ) )
4
4
  require File.expand_path( File.join( File.dirname(__FILE__), %w[core_ext hash.rb] ) )
5
+ require 'yaml'
6
+ require 'logger'
5
7
 
6
8
  module Rack
7
9
  module Session
@@ -19,10 +21,13 @@ module Rack
19
21
  # :pool_timeout ::
20
22
  # The connection pool timeout. see mongo-ruby-driver docs for settings.
21
23
  # Defaults to 1 sec.
24
+ # :logging ::
25
+ # Set to true to enable logger. Default is false
22
26
  DEFAULT_OPTIONS = Abstract::ID::DEFAULT_OPTIONS.merge \
23
27
  :server => 'localhost:27017/mongo_session/sessions',
24
28
  :pool_size => 1,
25
- :pool_timeout => 1.0
29
+ :pool_timeout => 1.0,
30
+ :log_level => :fatal
26
31
 
27
32
  # Initializes mongo_rack. Pass in options for default override.
28
33
  def initialize(app, options={})
@@ -31,13 +36,18 @@ module Rack
31
36
  host, port, db_name, cltn_name = parse_server_desc( @default_options[:server] )
32
37
 
33
38
  @mutex = Mutex.new
34
- @connection = ::Mongo::Connection.new( host, port,
39
+ @connection = ::Mongo::Connection.new(
40
+ host,
41
+ port,
35
42
  :pool_size => @default_options[:pool_size],
36
43
  :timeout => @default_options[:pool_timeout] )
37
44
  @db = @connection.db( db_name )
38
45
  @sessions = @db[cltn_name]
46
+
47
+ @logger = Logger.new( $stdout )
48
+ @logger.level = set_log_level( @default_options[:log_level] )
39
49
  end
40
-
50
+
41
51
  # Fetch session with optional session id. Retrieve session from mongodb if any
42
52
  def get_session( env, sid )
43
53
  return _get_session( env, sid ) unless env['rack.multithread']
@@ -85,35 +95,57 @@ module Rack
85
95
  raise "Invalid host:port description" unless server_desc.size == 2
86
96
  return server_desc.first, server_desc.last.to_i, tokens[1], tokens[2]
87
97
  end
88
-
98
+
99
+ # Use YAML to store session objects
100
+ def serialize( ses )
101
+ YAML::dump( ses )
102
+ end
103
+
104
+ # Session object stored in YAML
105
+ def deserialize( buff )
106
+ YAML::load( buff )
107
+ end
108
+
89
109
  # fetch session with optional session id
90
110
  def _get_session(env, sid)
111
+ logger.debug "Getting session info for #{sid.inspect}"
91
112
  if sid
92
113
  ses_obj = sessions.find_one( { :_id => sid } )
93
- session = MongoRack::SessionHash.new( ses_obj['data'] ) if ses_obj and fresh?( ses_obj )
114
+ if ses_obj
115
+ logger.debug "Found session object on #{sid.inspect}"
116
+ else
117
+ logger.debug "Unable to find session object #{sid.inspect}"
118
+ end
119
+ session = MongoRack::SessionHash.new( deserialize(ses_obj['data']) ) if ses_obj and fresh?( ses_obj )
94
120
  end
95
121
 
96
122
  unless sid and session
97
- env['rack.errors'].puts("Session '#{sid.inspect}' not found, initializing...") if $VERBOSE and not sid.nil?
98
- session = {}
123
+ logger.warn "Session ID not found - #{sid.inspect} - Creating new session"
124
+ session = MongoRack::SessionHash.new
99
125
  sid = generate_sid
100
- ret = sessions.save( { :_id => sid, :data => session } )
126
+ ret = sessions.save( { :_id => sid, :data => serialize(session) } )
101
127
  raise "Session collision on '#{sid.inspect}'" unless ret
102
128
  end
103
- session.instance_variable_set( '@old', MongoRack::SessionHash.new.merge(session) )
104
- return [sid, session]
105
- rescue => boom
106
- warn "#{self} is unable to find server."
107
- warn $!.inspect
108
- return [ nil, {} ]
129
+ merged = MongoRack::SessionHash.new.merge(session)
130
+ logger.debug "Setting old session #{merged.inspect}"
131
+ session.instance_variable_set( '@old', merged )
132
+ return [sid, session]
133
+ rescue => boom
134
+ logger.error "#{self} Hoy! something bad happened loading session data"
135
+ logger.error $!.inspect
136
+ boom.backtrace.each{ |l| logger.error l }
137
+ return [ nil, MongoRack::SessionHash.new ]
109
138
  end
110
139
 
111
140
  # update session information with new settings
112
141
  def _set_session(env, sid, new_session, options)
142
+ logger.debug "Setting session #{new_session.inspect}"
113
143
  ses_obj = sessions.find_one( { :_id => sid } )
114
144
  if ses_obj
115
- session = MongoRack::SessionHash.new( ses_obj['data'] )
145
+ logger.debug "Found existing session for -- #{sid.inspect}"
146
+ session = MongoRack::SessionHash.new( deserialize( ses_obj['data'] ) )
116
147
  else
148
+ logger.debug "Unable to find session for -- #{sid.inspect}"
117
149
  session = MongoRack::SessionHash.new
118
150
  end
119
151
 
@@ -124,37 +156,67 @@ module Rack
124
156
  sessions.insert( {:_id => sid, :data => {} } )
125
157
  end
126
158
  old_session = new_session.instance_variable_get('@old') || MongoRack::SessionHash.new
159
+ logger.debug "Setting old session -- #{old_session.inspect}"
127
160
  merged = merge_sessions( sid, old_session, new_session, session )
128
161
 
129
162
  expiry = options[:expire_after]
130
163
  expiry = expiry ? Time.now + options[:expire_after] : 0
131
164
 
132
165
  # BOZO ! Use upserts here if minor changes ?
133
- sessions.save( { :_id => sid, :data => merged, :expire => expiry } )
166
+ logger.debug "Updating session -- #{merged.inspect}"
167
+ sessions.save( { :_id => sid, :data => serialize( merged ), :expire => expiry } )
134
168
  return sid
135
- rescue => boom
136
- warn "#{self} is unable to find server."
137
- warn $!.inspect
169
+ rescue => boom
170
+ logger.error "#{self} Hoy! Something went wrong. Unable to persist session."
171
+ logger.error $!.inspect
172
+ boom.backtrace.each{ |l| logger.error l }
138
173
  return false
139
174
  end
140
175
 
141
176
  # merge old, new to current session state
142
177
  def merge_sessions( sid, old_s, new_s, cur={} )
143
178
  unless Hash === old_s and Hash === new_s
144
- warn 'Bad old or new sessions provided.'
179
+ logger.error 'Bad old or new sessions provided.'
145
180
  return cur
146
181
  end
147
-
182
+
148
183
  delete = old_s.keys - new_s.keys
149
- warn "//@#{sid}: delete #{delete*','}" if $VERBOSE and not delete.empty?
184
+ logger.info "//@#{sid}: delete #{delete*','}" if not delete.empty?
150
185
  delete.each{ |k| cur.delete(k) }
151
186
 
152
- update = new_s.keys.select{ |k| new_s[k] != old_s[k] }
153
- warn "//@#{sid}: update #{update*','}" if $VERBOSE and not update.empty?
154
- update.each{ |k| cur[k] = new_s[k] }
187
+ update = new_s.keys.select do |k|
188
+ logger.debug "Update #{k}-#{new_s[k] != old_s[k]}? #{new_s[k].inspect} - #{old_s[k].inspect}";
189
+ new_s[k] != old_s[k]
190
+ end
155
191
 
192
+ logger.info "//@#{sid}: update #{update*','}" if not update.empty?
193
+ update.each{ |k| cur[k] = new_s[k] }
156
194
  cur
157
195
  end
196
+
197
+ # Logger handle
198
+ def logger
199
+ @logger
200
+ end
201
+
202
+ # Set the log level
203
+ def set_log_level( level )
204
+ case level
205
+ when :fatal
206
+ Logger::FATAL
207
+ when :error
208
+ Logger::ERROR
209
+ when :warn
210
+ Logger::WARN
211
+ when :info
212
+ Logger::INFO
213
+ when :debug
214
+ Logger::DEBUG
215
+ else
216
+ Logger::INFO
217
+ end
218
+ end
219
+
158
220
  end
159
221
  end
160
222
  end
@@ -1,10 +1,11 @@
1
- require File.expand_path( File.join( File.dirname(__FILE__), %w[spec_helper] ) )
1
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[spec_helper]))
2
+ require 'core_ext/hash'
2
3
 
3
4
  describe Rack::Session::Mongo do
4
5
  before :all do
5
6
  @session_key = 'rack.session'
6
7
  @session_match = /#{@session_key}=[0-9a-fA-F]+;/
7
- @db_name = 'mongo_test'
8
+ @db_name = 'mongo_rack_test'
8
9
  @cltn_name = 'sessions'
9
10
 
10
11
  @con = Mongo::Connection.new
@@ -45,9 +46,11 @@ describe Rack::Session::Mongo do
45
46
  req = Rack::MockRequest.new( @pool )
46
47
  res = req.get("/", 'rack.multithread' => false )
47
48
  cookie = res["Set-Cookie"]
48
- req.get("/", "HTTP_COOKIE" => cookie, 'rack.multithread' => false ).body.should == '{"counter"=>2}'
49
+ res = req.get("/", "HTTP_COOKIE" => cookie, 'rack.multithread' => false )
50
+ res.body.should == '{"counter"=>2}'
49
51
  mongo_check( res, :counter, 2 )
50
- req.get("/", "HTTP_COOKIE" => cookie, 'rack.multithread' => false ).body.should == '{"counter"=>3}'
52
+ res = req.get("/", "HTTP_COOKIE" => cookie, 'rack.multithread' => false )
53
+ res.body.should == '{"counter"=>3}'
51
54
  mongo_check( res, :counter, 3 )
52
55
  end
53
56
 
@@ -157,6 +160,7 @@ describe Rack::Session::Mongo do
157
160
  res3.body.should == '{"counter"=>4}'
158
161
  end
159
162
 
163
+ # BOZO !! Review...
160
164
  it "multithread: should cleanly merge sessions" do
161
165
  pending do
162
166
  @pool = Rack::Session::Mongo.new( @incrementor, :server => "localhost:27017/#{@db_name}/#{@cltn_name}", :pool_size => 10 )
@@ -182,7 +186,7 @@ describe Rack::Session::Mongo do
182
186
  drop_counter = proc do |env|
183
187
  env['rack.session'].delete 'counter'
184
188
  env['rack.session']['foo'] = 'bar'
185
- [200, {'Content-Type'=>'text/plain'}, [env['rack.session'].inspect]]
189
+ [200, {'Content-Type'=>'text/plain'}, env['rack.session'].inspect]
186
190
  end
187
191
  tses = Rack::Utils::Context.new @pool, drop_counter
188
192
  treq = Rack::MockRequest.new( tses )
@@ -198,11 +202,52 @@ describe Rack::Session::Mongo do
198
202
  res.body.should include('"foo"=>"bar"')
199
203
  end
200
204
 
201
- session = @pool.sessions.find_one( {:_id => sess_id } )
202
- session['data'].size.should == 1
203
- session['data']['counter'].should be_nil
204
- session['data'].should == {"foo"=>"bar"}
205
+ result = @pool.sessions.find_one( {:_id => sess_id } )
206
+ result.should_not be_nil
207
+ session = YAML.load( result['data'] )
208
+ session.size.should == 1
209
+ session['counter'].should be_nil
210
+ session['foo'].should == 'bar'
205
211
  end
206
- end
212
+ end
213
+ end
214
+
215
+ describe "serialization" do
216
+ before( :all ) do
217
+ @pool = Rack::Session::Mongo.new( @incrementor, :server => "localhost:27017/#{@db_name}/#{@cltn_name}" )
218
+ @env = {}
219
+ @opts = {}
220
+ end
221
+
222
+ it "should store a hash in session correctly" do
223
+ sid = 10
224
+ ses = { 'a' => 1, 'b' => 2 }
225
+ @pool.send(:_set_session, @env, sid, ses, @opts )
226
+ results = @pool.send(:_get_session, @env, sid )
227
+ results.last.should == ses
228
+ end
229
+
230
+ it "should store an object in session correctly" do
231
+ sid = 11
232
+ fred = Fred.new( 10, "Hello" )
233
+ ses = { :fred => fred }
234
+ @pool.send(:_set_session, @env, sid, ses, @opts )
235
+ results = @pool.send(:_get_session, @env, sid )
236
+ [:fred, 'fred'].each do |key|
237
+ results.last[key].blee.should == 10
238
+ results.last[key].duh.should == "Hello"
239
+ results.last[key].zob.should == 100
240
+ end
241
+ end
207
242
  end
243
+
244
+ class Fred
245
+ attr_accessor :blee, :duh, :zob
246
+ def initialize( blee, duh )
247
+ @blee = blee
248
+ @duh = duh
249
+ @zob = 100
250
+ end
251
+ end
252
+
208
253
  end
@@ -1,5 +1,4 @@
1
- require File.expand_path( File.join( File.dirname(__FILE__), %w[spec_helper] ) )
2
- require File.expand_path( File.join( File.dirname(__FILE__), %w[.. lib core_ext hash] ) )
1
+ require File.expand_path(File.join(File.dirname(__FILE__), %w[spec_helper]))
3
2
 
4
3
  describe MongoRack::SessionHash do
5
4
  before :all do
@@ -2,6 +2,7 @@ require 'rubygems'
2
2
  require 'rack'
3
3
  require 'rack/test'
4
4
  require 'rack/response'
5
+ require 'yaml'
5
6
 
6
7
  require File.expand_path( File.join( File.dirname(__FILE__), %w[.. lib mongo_rack] ) )
7
8
 
@@ -10,9 +11,10 @@ end
10
11
 
11
12
  def mongo_check( res, key, val )
12
13
  session_id = res['Set-Cookie'].match( /^#{@session_key}=(.*?);.*?/ )[1]
13
- ses = @sessions.find_one( { :_id => session_id } )
14
- ses.should_not be_nil
15
- ses['data'][key.to_s].should == val
14
+ result = @sessions.find_one( { :_id => session_id } )
15
+ result.should_not be_nil
16
+ ses = YAML.load( result['data'] )
17
+ ses[key.to_s].should == val
16
18
  end
17
19
 
18
20
  def clear_sessions
@@ -50,7 +50,7 @@ class GemPackageTask < Rake::PackageTask
50
50
  task :package => ['gem:prereqs', "#{package_dir_path}/#{gem_file}"]
51
51
  file "#{package_dir_path}/#{gem_file}" => [package_dir_path] + package_files + bones_files do
52
52
  when_writing("Creating GEM") {
53
- chdir(package_dir_path) do
53
+ chdir(package_dir_path) do
54
54
  Gem::Builder.new(gem_spec).build
55
55
  verbose(true) {
56
56
  mv gem_file, "../#{gem_file}"
@@ -1,4 +1,5 @@
1
1
  require 'rake/rdoctask'
2
+ # require 'darkfish-rdoc'
2
3
 
3
4
  namespace :doc do
4
5
 
@@ -26,8 +27,8 @@ namespace :doc do
26
27
 
27
28
  rd.options << "-t #{title}"
28
29
  rd.options << "-SHN"
29
- # rd.options << "-f"
30
- # rd.options << "darkfish"
30
+ rd.options << "-f"
31
+ # rd.options << "darkfish"
31
32
  rd.options.concat(rdoc.opts)
32
33
  end
33
34
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mongo_rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Fernand Galiana
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-05 00:00:00 -07:00
12
+ date: 2010-02-03 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -20,7 +20,7 @@ dependencies:
20
20
  requirements:
21
21
  - - ">="
22
22
  - !ruby/object:Gem::Version
23
- version: 1.0.0
23
+ version: 1.0.1
24
24
  version:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: mongo
@@ -30,7 +30,7 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.18.1
33
+ version: 0.18.2
34
34
  version:
35
35
  - !ruby/object:Gem::Dependency
36
36
  name: mongo_ext
@@ -40,7 +40,17 @@ dependencies:
40
40
  requirements:
41
41
  - - ">="
42
42
  - !ruby/object:Gem::Version
43
- version: 0.18.1
43
+ version: 0.18.2
44
+ version:
45
+ - !ruby/object:Gem::Dependency
46
+ name: bones
47
+ type: :development
48
+ version_requirement:
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: 2.5.1
44
54
  version:
45
55
  description: ""
46
56
  email: fernand.galiana@gmail.com
@@ -54,6 +64,8 @@ files:
54
64
  - HISTORY
55
65
  - README.rdoc
56
66
  - Rakefile
67
+ - aa.rb
68
+ - fred.rb
57
69
  - lib/core_ext/hash.rb
58
70
  - lib/mongo_rack.rb
59
71
  - lib/mongo_rack/session_hash.rb