Fixed race condition in Sessions.create().
This commit is contained in:
parent
d8d506ea44
commit
6d5a02fd80
1 changed files with 54 additions and 39 deletions
|
@ -10,8 +10,7 @@ module Sessions
|
|||
end
|
||||
|
||||
# get working directories
|
||||
@path = @root + '/tmp/websocket'
|
||||
@pid = @root + '/tmp/pids/sessionworker.pid'
|
||||
@path = "#{@root}/tmp/websocket"
|
||||
|
||||
# create global vars for threads
|
||||
@@client_threads = {}
|
||||
|
@ -29,18 +28,27 @@ returns
|
|||
=end
|
||||
|
||||
def self.create( client_id, session, meta )
|
||||
path = @path + '/' + client_id.to_s
|
||||
FileUtils.mkpath path
|
||||
path = "#{@path}/#{client_id}"
|
||||
path_tmp = "#{@path}/tmp/#{client_id}"
|
||||
session_file = "#{path_tmp}/session"
|
||||
|
||||
# collect session data
|
||||
meta[:last_ping] = Time.new.to_i.to_s
|
||||
data = {
|
||||
user: session,
|
||||
meta: meta,
|
||||
}
|
||||
content = data.to_s
|
||||
File.open( path + '/session', 'wb' ) { |file|
|
||||
content = data.to_json
|
||||
|
||||
# store session data in session file
|
||||
FileUtils.mkpath path_tmp
|
||||
File.open( session_file, 'wb' ) { |file|
|
||||
file.write content
|
||||
}
|
||||
|
||||
# move to destination directory
|
||||
FileUtils.mv( path_tmp, path )
|
||||
|
||||
# send update to browser
|
||||
if session && session['id']
|
||||
self.send(
|
||||
|
@ -66,7 +74,7 @@ returns
|
|||
=end
|
||||
|
||||
def self.sessions
|
||||
path = @path + '/'
|
||||
path = "#{@path}/"
|
||||
|
||||
# just make sure that spool path exists
|
||||
if !File::exist?( path )
|
||||
|
@ -75,7 +83,10 @@ returns
|
|||
|
||||
data = []
|
||||
Dir.foreach( path ) do |entry|
|
||||
next if entry == '.' || entry == '..' || entry == 'spool'
|
||||
next if entry == '.'
|
||||
next if entry == '..'
|
||||
next if entry == 'tmp'
|
||||
next if entry == 'spool'
|
||||
data.push entry.to_s
|
||||
end
|
||||
data
|
||||
|
@ -153,7 +164,7 @@ returns
|
|||
=end
|
||||
|
||||
def self.destory( client_id )
|
||||
path = @path + '/' + client_id.to_s
|
||||
path = "#{@path}/#{client_id}"
|
||||
FileUtils.rm_rf path
|
||||
end
|
||||
|
||||
|
@ -171,7 +182,7 @@ returns
|
|||
|
||||
def self.destory_idle_sessions(idle_time_in_sec = 240)
|
||||
list_of_closed_sessions = []
|
||||
clients = Sessions.list
|
||||
clients = Sessions.list
|
||||
clients.each { |client_id, client|
|
||||
if !client[:meta] || !client[:meta][:last_ping] || ( client[:meta][:last_ping].to_i + idle_time_in_sec ) < Time.now.to_i
|
||||
list_of_closed_sessions.push client_id
|
||||
|
@ -196,10 +207,11 @@ returns
|
|||
def self.touch( client_id )
|
||||
data = self.get(client_id)
|
||||
return false if !data
|
||||
path = @path + '/' + client_id.to_s
|
||||
path = "#{@path}/#{client_id}"
|
||||
data[:meta][:last_ping] = Time.new.to_i.to_s
|
||||
content = data.to_json
|
||||
File.open( path + '/session', 'wb' ) { |file|
|
||||
file.write data.to_json
|
||||
file.write content
|
||||
}
|
||||
true
|
||||
end
|
||||
|
@ -225,12 +237,12 @@ returns
|
|||
=end
|
||||
|
||||
def self.get( client_id )
|
||||
session_dir = @path + '/' + client_id.to_s
|
||||
session_file = session_dir + '/session'
|
||||
data = nil
|
||||
session_dir = "#{@path}/#{client_id}"
|
||||
session_file = "#{session_dir}/session"
|
||||
data = nil
|
||||
if !File.exist? session_file
|
||||
self.destory(client_id)
|
||||
puts "ERROR: missing session file for '#{client_id.to_s}', remove session."
|
||||
puts "ERROR: missing session file for '#{client_id}', remove session."
|
||||
return
|
||||
end
|
||||
begin
|
||||
|
@ -266,14 +278,14 @@ returns
|
|||
=end
|
||||
|
||||
def self.send( client_id, data )
|
||||
path = @path + '/' + client_id.to_s + '/'
|
||||
filename = 'send-' + Time.new().to_f.to_s# + '-' + rand(99999999).to_s
|
||||
check = true
|
||||
count = 0
|
||||
path = "#{@path}/#{client_id}/"
|
||||
filename = "send-#{ Time.new().to_f }"
|
||||
check = true
|
||||
count = 0
|
||||
while check
|
||||
if File::exist?( path + filename )
|
||||
count += 1
|
||||
filename = filename + '-' + count
|
||||
filename = "#{filename}-#{count}"
|
||||
else
|
||||
check = false
|
||||
end
|
||||
|
@ -361,15 +373,16 @@ returns
|
|||
=end
|
||||
|
||||
def self.queue( client_id )
|
||||
path = @path + '/' + client_id.to_s + '/'
|
||||
data = []
|
||||
path = "#{@path}/#{client_id}/"
|
||||
data = []
|
||||
files = []
|
||||
Dir.foreach( path ) {|entry|
|
||||
next if entry == '.' || entry == '..'
|
||||
next if entry == '.'
|
||||
next if entry == '..'
|
||||
files.push entry
|
||||
}
|
||||
files.sort.each {|entry|
|
||||
filename = path + '/' + entry
|
||||
filename = "#{path}/#{entry}"
|
||||
if /^send/.match( entry )
|
||||
data.push Sessions.queue_file_read( path, entry )
|
||||
end
|
||||
|
@ -378,10 +391,9 @@ returns
|
|||
end
|
||||
|
||||
def self.queue_file_read( path, filename )
|
||||
file_old = path + filename
|
||||
file_new = path + 'a-' + filename
|
||||
file_old = "#{path}#{filename}"
|
||||
file_new = "#{path}a-#{filename}"
|
||||
FileUtils.mv( file_old, file_new )
|
||||
data = nil
|
||||
all = ''
|
||||
File.open( file_new, 'rb' ) { |file|
|
||||
all = file.read
|
||||
|
@ -390,15 +402,17 @@ returns
|
|||
JSON.parse( all )
|
||||
end
|
||||
|
||||
def self.spool_cleanup
|
||||
path = @path + '/spool/'
|
||||
def self.cleanup
|
||||
path = "#{@path}/spool/"
|
||||
FileUtils.rm_rf path
|
||||
path = "#{@path}/tmp/"
|
||||
FileUtils.rm_rf path
|
||||
end
|
||||
|
||||
def self.spool_create( msg )
|
||||
path = @path + '/spool/'
|
||||
path = "#{@path}/spool/"
|
||||
FileUtils.mkpath path
|
||||
file = Time.new.to_f.to_s + '-' + rand(99_999).to_s
|
||||
file = "#{Time.new.to_f}-#{rand(99_999)}"
|
||||
File.open( path + '/' + file, 'wb' ) { |file|
|
||||
data = {
|
||||
msg: msg,
|
||||
|
@ -409,20 +423,21 @@ returns
|
|||
end
|
||||
|
||||
def self.spool_list( timestamp, current_user_id )
|
||||
path = @path + '/spool/'
|
||||
path = "#{@path}/spool/"
|
||||
FileUtils.mkpath path
|
||||
data = []
|
||||
data = []
|
||||
to_delete = []
|
||||
files = []
|
||||
files = []
|
||||
Dir.foreach( path ) {|entry|
|
||||
next if entry == '.' || entry == '..'
|
||||
next if entry == '.'
|
||||
next if entry == '..'
|
||||
files.push entry
|
||||
}
|
||||
files.sort.each {|entry|
|
||||
filename = path + '/' + entry
|
||||
filename = "#{path}/#{entry}"
|
||||
next if !File::exist?( filename )
|
||||
File.open( filename, 'rb' ) { |file|
|
||||
all = file.read
|
||||
all = file.read
|
||||
spool = JSON.parse( all )
|
||||
begin
|
||||
message_parsed = JSON.parse( spool['msg'] )
|
||||
|
@ -433,7 +448,7 @@ returns
|
|||
|
||||
# ignore message older then 48h
|
||||
if spool['timestamp'] + (2 * 86_400) < Time.now.to_i
|
||||
to_delete.push path + '/' + entry
|
||||
to_delete.push "#{path}/#{entry}"
|
||||
next
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue