rsence 2.0.0.3.pre → 2.0.0.4.pre

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/lib/conf/default.rb CHANGED
@@ -68,7 +68,7 @@ class Configuration
68
68
  wizard_config_data = ConfigWizard.new(config).run( wizard_conf_file )
69
69
  config.merge!( wizard_config_data )
70
70
  end
71
- def initialize(args)
71
+ def initialize( args, dont_expand_path=false )
72
72
  ## Paths for log and pid files
73
73
  pidpath = File.join( args[:env_path], 'run' )
74
74
  logpath = File.join( args[:env_path], 'log' )
@@ -138,10 +138,11 @@ class Configuration
138
138
  end
139
139
  end
140
140
 
141
- env_plugins_path = File.join( args[:env_path], 'plugins' )
141
+ env_plugins_path = File.expand_path( 'plugins', args[:env_path] )
142
142
  unless config[:plugin_paths].include? env_plugins_path
143
143
  config[:plugin_paths].push( env_plugins_path )
144
144
  end
145
+ puts "plugin paths: #{config[:plugin_paths].inspect}" if args[:debug]
145
146
 
146
147
  config[:trace] = true if args[:trace_js]
147
148
  config[:debug_mode] = true if args[:debug]
@@ -154,12 +155,9 @@ class Configuration
154
155
  config[:daemon][:pid_fn] = File.join(pidpath, "rsence.pid") unless config[:daemon].has_key?(:pid_fn)
155
156
  config[:daemon][:log_fn] = File.join(logpath, "rsence") unless config[:daemon].has_key?(:log_fn)
156
157
 
157
- if config[:database][:ses_db].start_with?('sqlite://')
158
- db_url = config[:database][:ses_db].split('sqlite://')[1]
159
- unless db_url.start_with?('/')
160
- db_url = File.join( args[:env_path], db_url )
161
- config[:database][:ses_db] = "sqlite://#{db_url}"
162
- end
158
+ if config[:database][:ses_db].start_with?('sqlite://') and not dont_expand_path
159
+ db_url = File.expand_path( config[:database][:ses_db].split('sqlite://')[1], args[:env_path] )
160
+ config[:database][:ses_db] = "sqlite://#{db_url}"
163
161
  end
164
162
 
165
163
  ## Broker configuration
data/lib/daemon/daemon.rb CHANGED
@@ -106,6 +106,18 @@ module Daemon
106
106
  return RSence::SIGComm.wait_signal_response( pid, pid_fn, signal, timeout, debug_pre, debug_suf, sleep_secs )
107
107
  end
108
108
 
109
+ def self.trap_windows_signals( daemon )
110
+ ['INT'].each do | signal |
111
+ Signal.trap( signal ) do
112
+ puts "RSence killed with signal #{signal.inspect}" if RSence.args[:verbose]
113
+ daemon.usr1
114
+ daemon.stop
115
+ puts "Shutdown complete."
116
+ exit
117
+ end
118
+ end
119
+ end
120
+
109
121
  # Traps common kill signals
110
122
  def self.trap_signals( daemon )
111
123
 
@@ -164,6 +176,7 @@ module Daemon
164
176
  write_pid( daemon, pid )
165
177
  return pid
166
178
  else
179
+ trap_windows_signals( daemon )
167
180
  return false
168
181
  end
169
182
  end
@@ -321,8 +334,7 @@ class HTTPDaemon
321
334
 
322
335
  # Called by Controller#stop, contains RSence-specific operations
323
336
  def stop
324
- @transporter.plugins.shutdown
325
- @transporter.sessions.shutdown
337
+ @transporter.shutdown
326
338
  end
327
339
 
328
340
  # Called on USR1 signals (save data)
@@ -332,10 +344,13 @@ class HTTPDaemon
332
344
 
333
345
  # Save state
334
346
  def save
335
- puts "Saving."
347
+ puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} -- Saving state..."
348
+ transporter_state = @transporter.online?
349
+ @transporter.online = false
336
350
  @transporter.plugins.delegate(:flush)
337
351
  @transporter.sessions.store_sessions
338
- puts "Saved."
352
+ @transporter.online = transporter_state
353
+ puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} -- State saved."
339
354
  end
340
355
 
341
356
  # Called on USR2 signals ("Alive?")
data/lib/http/broker.rb CHANGED
@@ -30,6 +30,17 @@ require 'http/request'
30
30
  class Broker
31
31
 
32
32
  def call(env)
33
+ sleep @@ping_sim if @@ping_sim
34
+ unless @@transporter.online?
35
+ puts "#{Time.now.strftime('%Y-%m-%d %H:%M:%S')} -- Server busy."
36
+ headers = {
37
+ 'Retry-After' => '2',
38
+ 'Content-Type' => 'text/plain',
39
+ 'Refresh' => "2; #{env['REQUEST_URI']}",
40
+ 'Content-Length' => '4'
41
+ }
42
+ return [ 503, headers, 'BUSY' ]
43
+ end
33
44
  request = Request.new(env)
34
45
  response = Response.new
35
46
  request_method = request.request_method.downcase
@@ -58,6 +69,13 @@ class Broker
58
69
  else
59
70
  @@ping_sim = conf/1000.0
60
71
  end
72
+ Thread.new do
73
+ Thread.pass
74
+ until RSence.argv.test_port( port, host )
75
+ sleep 0.1
76
+ end
77
+ @@transporter.online = true
78
+ end
61
79
  handler.run( Rack::Lint.new(self.new), :Host => host, :Port => port )
62
80
  end
63
81
 
@@ -79,8 +97,6 @@ class Broker
79
97
 
80
98
  puts "post: #{@request.fullpath}" if RSence.args[:verbose]
81
99
 
82
- sleep @@ping_sim if @@ping_sim
83
-
84
100
  not_found unless @@transporter.servlet( :post, @request, @response )
85
101
 
86
102
  end
@@ -90,8 +106,6 @@ class Broker
90
106
 
91
107
  puts "get: #{@request.fullpath}" if RSence.args[:verbose]
92
108
 
93
- sleep @@ping_sim if @@ping_sim
94
-
95
109
  not_found unless @@transporter.servlet( :get, @request, @response )
96
110
 
97
111
  end
@@ -79,9 +79,7 @@ module PluginUtil
79
79
  if prefix
80
80
  path = File.join( prefix, path )
81
81
  end
82
- if path[0].chr != '/' and path[0..1] != '..'
83
- path = File.join( @path, path )
84
- end
82
+ path = File.expand_path( path, @path )
85
83
  return path
86
84
  end
87
85
 
@@ -121,7 +121,10 @@ class PluginManager
121
121
  if File.exists?( File.join( bundle_path, 'disabled' ) )
122
122
  if @registry.has_key?( bundle_name.to_sym )
123
123
  puts "Disabling bundle #{bundle_name}..."
124
+ online_status = @transporter.online?
125
+ @transporter.online = false
124
126
  unload_bundle( bundle_name.to_sym )
127
+ @transporter.online = online_status
125
128
  if RSence.args[:say]
126
129
  Thread.new do
127
130
  Thread.pass
@@ -132,8 +135,11 @@ class PluginManager
132
135
  else
133
136
  if not @registry.has_key?( bundle_name.to_sym )
134
137
  puts "Loading bundle #{bundle_name}..."
138
+ online_status = @transporter.online?
139
+ @transporter.online = false
135
140
  load_bundle( bundle_path, bundle_name.to_sym, bundle_name+'.rb' )
136
141
  call( bundle_name.to_sym, :open )
142
+ @transporter.online = online_status
137
143
  if RSence.args[:say]
138
144
  Thread.new do
139
145
  Thread.pass
@@ -145,9 +151,12 @@ class PluginManager
145
151
  info = @info[bundle_name.to_sym]
146
152
  if info[:reloadable] and plugin_changed?( bundle_name.to_sym )
147
153
  puts "Bundle #{bundle_name} has changed, reloading..."
154
+ online_status = @transporter.online?
155
+ @transporter.online = false
148
156
  unload_bundle( bundle_name.to_sym )
149
157
  load_bundle( bundle_path, bundle_name.to_sym, bundle_name+'.rb' )
150
158
  call( bundle_name.to_sym, :open )
159
+ @transporter.online = online_status
151
160
  if RSence.args[:say]
152
161
  Thread.new do
153
162
  Thread.pass
@@ -162,6 +171,7 @@ class PluginManager
162
171
  end
163
172
 
164
173
  def unload_bundle( bundle_name )
174
+ puts "unloading bundle: #{bundle_name.inspect}" if RSence.args[:debug]
165
175
  if @registry.has_key?( bundle_name )
166
176
  call( bundle_name, :flush )
167
177
  call( bundle_name, :close )
@@ -194,11 +204,6 @@ class PluginManager
194
204
  @info = {}
195
205
  @aliases = {}
196
206
  @servlets = []
197
- # @types = {
198
- # :gui => [],
199
- # :plugin => [],
200
- # :servlet => []
201
- # }
202
207
  @plugin_paths.each do |path|
203
208
  next unless File.directory? path
204
209
  scan_plugindir( path )
@@ -219,10 +224,8 @@ class PluginManager
219
224
  # - Skips bundles containing a file or directory named 'disabled'
220
225
  def scan_plugindir( path )
221
226
  Dir.entries(path).each do |bundle_name|
222
- # puts "bundle_name: #{bundle_name}"
223
227
  next if bundle_name[0].chr == '.'
224
228
  bundle_path = File.expand_path( File.join( path, bundle_name ) )
225
- # puts "#{File.stat(bundle_path).inspect}"
226
229
  next unless File.directory?( bundle_path )
227
230
  bundle_file = bundle_name+'.rb'
228
231
  if not File.exists?( File.join( bundle_path, bundle_file ) )
@@ -306,7 +309,7 @@ class PluginManager
306
309
 
307
310
  # Loads a plugin bundle.
308
311
  def load_bundle( bundle_path, bundle_name, bundle_file )
309
-
312
+ puts "loading bundle: #{bundle_name.inspect}" if RSence.args[:debug]
310
313
  if @registry.has_key?( bundle_name.to_sym )
311
314
  warn "Warning: Bundle #{bundle_name} already loaded."
312
315
  return
@@ -331,10 +334,6 @@ class PluginManager
331
334
  @@bundle_info = bundle_info
332
335
  @@plugin_manager = plugin_manager
333
336
  def m.bundle_path; @@bundle_path; end
334
- # puts "using eval"
335
- # m::module_eval( File.read(src_path) )
336
- # puts "using require"
337
- # require src_path[0..-4]
338
337
  puts "using load"
339
338
  load src_path
340
339
  end
@@ -350,18 +349,14 @@ class PluginManager
350
349
  end
351
350
 
352
351
  unless bundle_info[:inits_self]
353
- # puts "#{bundle_name}: #{module_ns.constants.inspect}"
354
352
  module_ns.constants.each do |module_const_name|
355
353
  module_const = module_ns.const_get( module_const_name )
356
354
  if module_const.class == Class
357
- # puts "is class"
358
355
  module_const.ancestors.each do |ancestor|
359
- # puts "ancestor: #{ancestor.to_s.inspect}"
360
356
  if ancestor.to_s == "Servlet"
361
357
  module_const.new
362
358
  break
363
359
  elsif ancestor.to_s == "Plugin"
364
- puts "bundle_name: #{bundle_name}"
365
360
  module_const.new.register( bundle_name )
366
361
  break
367
362
  elsif ancestor.to_s == "Object"
@@ -51,7 +51,14 @@ class SessionStorage
51
51
 
52
52
  @db_uri = ::RSence.config[:database][:ses_db]
53
53
 
54
- db_init
54
+ if db_test
55
+ @db_avail = true
56
+ db_init
57
+ else
58
+ @db_avail = false
59
+ puts "Warning: Session database is not available. Can't use persistent sessions."
60
+ @id_counter = 0
61
+ end
55
62
 
56
63
  @accept_requests = true
57
64
 
@@ -60,15 +67,34 @@ class SessionStorage
60
67
  attr_reader :accept_requests
61
68
 
62
69
  def db_test
63
- if @db.table_exists?(:rsence_test)
70
+ begin
71
+ db_open
72
+ if @db.table_exists?(:rsence_test)
73
+ @db.drop_table(:rsence_test)
74
+ end
75
+ @db.create_table(:rsence_test) { primary_key :id; String :test }
76
+ test_id = @db[:rsence_test].insert( :test => 'TestFoo' )
77
+ @db[:rsence_test].filter( :id => test_id ).update( :test => 'TestFoo2' )
78
+ @db[:rsence_test].filter( :id => test_id ).delete
79
+ @db[:rsence_test].delete
64
80
  @db.drop_table(:rsence_test)
81
+ db_close
82
+ return true
83
+ rescue => e
84
+ if RSence.args[:debug]
85
+ err_msg = [
86
+ "ERROR: SssionStorage couldn't open database",
87
+ "#{e.class.to_s}, #{e.message}",
88
+ "Backtrace:",
89
+ "\t"+e.backtrace.join("\n\t")
90
+ ].join("\n")+"\n"
91
+ $stderr.write( err_msg )
92
+ elsif RSence.args[:verbose]
93
+ puts "Failed to open database '#{@db_uri}'."
94
+ puts "Run RSence in debug mode for full error output."
95
+ end
96
+ return false
65
97
  end
66
- @db.create_table(:rsence_test) { primary_key :id; String :test }
67
- test_id = @db[:rsence_test].insert( :test => 'TestFoo' )
68
- @db[:rsence_test].filter( :id => test_id ).update( :test => 'TestFoo2' )
69
- @db[:rsence_test].filter( :id => test_id ).delete
70
- @db[:rsence_test].delete
71
- @db.drop_table(:rsence_test)
72
98
  end
73
99
 
74
100
  def db_close
@@ -76,26 +102,14 @@ class SessionStorage
76
102
  end
77
103
 
78
104
  def db_open
79
- @db = Sequel.connect(@db_uri)
105
+ # work-around for windows (drive letters causing confusion)
106
+ if @db_uri.start_with?('sqlite://')
107
+ @db = Sequel.sqlite( @db_uri.split('sqlite://')[1] )
108
+ else
109
+ @db = Sequel.connect(@db_uri)
110
+ end
80
111
  end
81
112
 
82
- # def db_open
83
- # ## Tests if database has sufficient privileges
84
- # begin
85
- # @db = Sequel.connect(@db_uri)
86
- # db_test
87
- # db_close
88
- # @db = Sequel.connect(@db_uri)
89
- # rescue => e
90
- # $stderr.write( "SessionStorage: error #{e.inspect}\nReverting to default database.\n" )
91
- # @db_uri = "sqlite://#{File.join(SERVER_PATH,'var','db','rsence_ses.db')}"
92
- # @db = Sequel.connect(@db_uri)
93
- # db_test
94
- # db_close
95
- # @db = Sequel.connect(@db_uri)
96
- # end
97
- # end
98
-
99
113
  ## Creates the 'rsence_session' table, if necessary
100
114
  ## This table is used to store sessions
101
115
  def create_session_table
@@ -181,6 +195,10 @@ class SessionStorage
181
195
 
182
196
  ## Deletes all rows from rsence_session as well as rsence_uploads
183
197
  def reset_sessions
198
+ unless @db_avail
199
+ puts "Warning: Can't reset sessions: No database!" if RSence.args[:verbose]
200
+ return
201
+ end
184
202
  db_open
185
203
  @db[:rsence_session].delete if @db.table_exists?(:rsence_session)
186
204
  @db[:rsence_uploads].delete if @db.table_exists?(:rsence_uploads)
@@ -189,6 +207,10 @@ class SessionStorage
189
207
 
190
208
  ## Restores all saved sessions from db to ram
191
209
  def restore_sessions
210
+ unless @db_avail
211
+ puts "Warning: Can't restore sessions: No database!" if RSence.args[:verbose]
212
+ return
213
+ end
192
214
  puts "Restoring sessions..." if RSence.args[:verbose]
193
215
  db_open
194
216
  @db[:rsence_session].all do |ses_row|
@@ -211,6 +233,10 @@ class SessionStorage
211
233
 
212
234
  ## Stores all sessions to db from ram
213
235
  def store_sessions
236
+ unless @db_avail
237
+ puts "Warning: Can't store sessions: No database!" if RSence.args[:verbose]
238
+ return
239
+ end
214
240
  puts "Storing sessions..." if RSence.args[:verbose]
215
241
  db_open
216
242
  @sessions.each_key do |ses_id|
@@ -241,6 +267,10 @@ class SessionStorage
241
267
 
242
268
  ## Returns a new, unique session identifier by storing the params to the database
243
269
  def new_ses_id( cookie_key, ses_key, timeout_secs, user_id=0 )
270
+ unless @db_avail
271
+ @id_counter += 1
272
+ return @id_counter
273
+ end
244
274
  db_open
245
275
  new_id = @db[:rsence_session].insert(
246
276
  :cookie_key => cookie_key,
@@ -286,10 +316,12 @@ class SessionStorage
286
316
  @clone_targets.delete( ses_id ) if @clone_targets.has_key?( ses_id )
287
317
  end
288
318
 
289
- db_open
290
- # Deletes the session's row from the database
291
- @db[:rsence_session].filter(:id => ses_id).delete
292
- db_close
319
+ if @db_avail
320
+ db_open
321
+ # Deletes the session's row from the database
322
+ @db[:rsence_session].filter(:id => ses_id).delete
323
+ db_close
324
+ end
293
325
 
294
326
  end
295
327
 
@@ -30,16 +30,38 @@ class Transporter
30
30
 
31
31
  def initialize
32
32
  @config = ::RSence.config[:transporter_conf]
33
-
33
+ @accept_req = false
34
34
  @valuemanager = ValueManager.new
35
35
  @sessions = SessionManager.new( self )
36
- @plugins = PluginManager.new( ::RSence.config[:plugin_paths], self, RSence.args[:autoreload] )
36
+ @plugins = PluginManager.new( ::RSence.config[:plugin_paths], self, RSence.args[:autoupdate] )
37
37
  if RSence.launch_pid != Process.pid
38
38
  Process.kill( 'TERM', RSence.launch_pid )
39
39
  end
40
40
  end
41
41
 
42
+ def online?
43
+ @accept_req
44
+ end
45
+
46
+ def online=(state)
47
+ if RSence.args[:verbose]
48
+ if state
49
+ puts "RSence is online now."
50
+ else
51
+ puts "RSence is offline now."
52
+ end
53
+ end
54
+ @accept_req = state
55
+ end
56
+
57
+ def shutdown
58
+ online=false
59
+ @plugins.shutdown
60
+ @sessions.shutdown
61
+ end
62
+
42
63
  def servlet( request_type, request, response )
64
+
43
65
  broker_urls = ::RSence.config[:broker_urls]
44
66
  uri = request.fullpath
45
67
 
@@ -326,11 +326,7 @@ class ClientPkgBuild
326
326
  # make sure the src_dirs contain only absolute paths.
327
327
  # if not, use current working dir as a logical prefix
328
328
  @src_dirs.map! do |src_dir|
329
- if src_dir[0].chr == '/'
330
- src_dir
331
- else
332
- File.join( File.expand_path( Dir.pwd ), src_dir )
333
- end
329
+ File.expand_path( src_dir )
334
330
  end
335
331
 
336
332
  @src_dirs.each do |src_dir|