GServer Miultiple Clients - Collisions

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!

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:

I’m not too familiar with it, but GServer probably threads incoming
connections. It appears from your code that each incoming connection
has its own private db connection, which is good. Maybe it’s a database
or database driver issue.
If I were you I’d put a mutex around the database portion so only one
thread can write at once.
@@go = Mutex.new
@@go.synchronize {}

GL.
-rp

Bah, what a silly problem:

filename = logs_dir + results[1] + “.log”

“results” does not exist. I was missing it, because the exception was
being raised and caught in an unrelated bit of code. So far, gserver is
working perfectly for the task at hand.