I’ve got a small problem using gserver with multiple client connections.
Let me give some quick background on my problem:
I’m running a Ruby script on a dozen or so different machines, doing
some basic performance monitoring tasks. The script writes its output
to a local file (for buffering), then connects to a server running on
the local network. The server receives the lines from the file, writes
them to a local file for archiving, then uses dbi to write them to a
database.
Everything is working fine, unless more than one client connects at a
time. When two clients connect at once, I get numerous database errors,
and the results don’t write.
I was under the impression that gserver threaded incoming connections,
so each connection would have its own independent database connection,
but it looks like the single database handle is being shared by all
clients. Obviously, this isn’t working properly. Here’s some code to
show what I’ve tried. Any help would be greatly appreciated:
Server:
class ScriptResultsServer < GServer
def initialize(port,hostname,*args)
super(port, hostname,*args)
end
def serve(io)
test_results = []
loop do
# Check for incoming data
if IO.select([io],nil,nil,1)
line = io.gets
# After tests completed, client responds with “done”
if (line =~ /done/)
# After receiving “success”, client deletes buffer
io.puts(“success”)
break
else
test_result = []
test_result = line.split(’,’)
test_results << test_result
app_dir = Dir.getwd
logs_dir = app_dir + "/logs/"
# results[1] contains the hostname of the connected client
filename = logs_dir + results[1] + ".log"
# Write the results to the archive file
write_log(filename,line)
# Clean the old entries from the log file
clean_log(filename)
end
end
end
write_db(test_results)
end
def clean_log(filename)
Code snipped - this method opens a file, and deletes all lines
older than 30 days
end
def write_log(filename,line)
Code snipped - this method opens a file, and appends the data that
was sent to the server
end
def write_db(results)
Code snipped - this method creates a DB connection and writes
the data that was sent to the server
end
def close_db
Code snipped - this method commits changes and disconnects
end
end
Create a new instance of the server, accessible at this host on port
8050
server = ScriptResultsServer.new 8050,Socket.gethostname
Enable logging
server.audit = true
Start the server
server.start
Join the server thread to the main thread (prevent exit)
server.join
Client:
class ScriptClient
def initialize(filename)
# Open a socket to the ******* host on port 8050
@sr_server = TCPSocket.open("*********",“8050”)
@results_filename = filename
# Open the local buffer file
@results_file = File.open(filename, “r”)
end
def write
# Read each line from the buffer and send to the server
while (line = @results_file.gets)
@sr_server.puts(line)
end
end
def disconnect
# Close the buffer file
@results_file.close
# After streaming the buffer, send “done” to the server
# If “success” is received, delete the buffer file
@sr_server.puts(“done”)
# Wait up to 30 seconds for acknowledgment
if (IO.select([@sr_server],nil,nil,30))
line = @sr_server.gets
if (line =~ /success/)
File.delete(@results_filename)
end
end
end
end
Thanks again for any help!