rsence 2.0.0.3.pre → 2.0.0.4.pre

Sign up to get free protection for your applications and to get access to all the features.
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|