# GServer Miultiple Clients - Collisions

**URL:** <https://www.ruby-forum.com/t/gserver-miultiple-clients-collisions/188599>\
**Category:** Ruby\
**Created:** [May 14, 2010, 5:16pm UTC](https://www.ruby-forum.com/t/gserver-miultiple-clients-collisions/188599 "2010-05-14T17:16:12Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![eudeyrn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a5b964/32.png) [@eudeyrn](https://www.ruby-forum.com/u/eudeyrn)\
**Post date:** [May 14, 2010, 5:16pm UTC](https://www.ruby-forum.com/t/gserver-miultiple-clients-collisions/188599/1 "2010-05-14T17:16:12Z")

</div>

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!

---

<div class="post-metadata">

**Author:** ![eudeyrn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a5b964/32.png) [@eudeyrn](https://www.ruby-forum.com/u/eudeyrn)\
**Post date:** [May 15, 2010, 12:08am UTC](https://www.ruby-forum.com/t/gserver-miultiple-clients-collisions/188599/2 "2010-05-15T00:08:00Z")

</div>

> 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

---

<div class="post-metadata">

**Author:** ![eudeyrn](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/a5b964/32.png) [@eudeyrn](https://www.ruby-forum.com/u/eudeyrn)\
**Post date:** [May 17, 2010, 10:42pm UTC](https://www.ruby-forum.com/t/gserver-miultiple-clients-collisions/188599/3 "2010-05-17T22:42:57Z")

</div>

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.
