Gserver hogging CPU


#1

I’m running a server on Mac OS 10.5.7, Ruby 1.8.6, that’s almost exactly
the same as the one in Peter C.'s Beginning Ruby book. When I run
the Activity Monitor it shows Ruby is consuming about 98% of one of my
CPUs when there’s no client activity (I have only 3 clients, 2 in the
same computer). I need the computer for other important things, so this
concerns me.

What can I do to free up the CPU? I’ve tried adding a few sleeps, to not
avail. Here’s the code:

#!/usr/bin/env ruby

Start this server with

ruby -w GServerchat.rb <port#>

or just

GServerchat.rb <port#> if file is executable

require ‘gserver’

class ChatServer < GServer # Server class derived from GServer super
class
def initialize(*args)
super(*args)

# Keep a record of the client IDs allocated
# and the lines of chat
@@client_id = 0
@@chat = []

end

def serve(io) # Serve method handles connections

Increment the client ID so each client gets a unigue ID

  @@client_id += 1
  my_client_id = @@client_id
  my_position = @@chat.size

  io.puts("welcome, client #{@@client_id}!")

  #leave a 'joined' message on the chat queue
  @@chat << [my_client_id, "<joins the chat>"]

  loop do
  #Every 2 seconds check for data
  if IO.select([io], nil, nil, 2)
  # If so, retrieve the data and process it...
  line = io.gets

  # Write the new line to the log file
logfile = File.open('/tmp/chatlog', 'a')
logfile.puts line
logfile.close

  # If user says quit, disconnect them
  if line =~ /quit/
    @@chat << [my_client_id, "< leaves the chat>"]
    break
  end

  # Shut down the server if we hear 'shutdown'
  self.stop if line =~ /shutdown/

  # Add the client's text to the chat array along with client's ID

  @@chat << [my_client_id, line]
else
  # No data, so print any newlines from the chat stream
  @@chat[my_position..(@@chat.size - 1)].each_with_index do |line,

index|
io.puts("#{line[0]} says: #{line[1]}")
end

   #Move the position to one past array end
  my_position = @@chat.size
  end

end

end
end

##server = ChatServer.new(ARGV[0])

portnum = ARGV[0] || 50000
my_ip =
Socket::getaddrinfo(Socket.gethostname,“echo”,Socket::AF_INET)[0][3]
server = ChatServer.new(portnum, my_ip, 5, $stdout, true)

server.start # Start the server

loop do
break if server.stopped?
end


Thanks for any help-
Scott


#2

What can I do to free up the CPU? I’ve tried adding a few sleeps, to not
avail. Here’s the code:

perhaps profile it with ruby prof, perhaps try other versions of ruby
(MBARI, etc.)
-=r


#3

On Jun 2, 2009, at 7:25 PM, Scott Cole wrote:

not
require ‘gserver’
end
@@chat << [my_client_id, “”]
logfile.close
# Add the client’s text to the chat array along with client’s ID
my_position = @@chat.size
my_ip =
Socket::getaddrinfo(Socket.gethostname,“echo”,Socket::AF_INET)[0][3]
server = ChatServer.new(portnum, my_ip, 5, $stdout, true)

server.start # Start the server

loop do
break if server.stopped?
end

This last loop looks suspect. You are basically calling
server.stopped? in a loop as fast as you can. Try sleeping a bit in
that loop:

loop do
sleep 1
break if server.stopped?
end

Cheers-
Ezra Z.
removed_email_address@domain.invalid


#4

Ezra Z. wrote:

What can I do to free up the CPU? I’ve tried adding a few sleeps, to not
require ‘gserver’
end
@@chat << [my_client_id, “”]
logfile.close
# Add the client’s text to the chat array along with client’s ID
my_position = @@chat.size
my_ip =
server.stopped? in a loop as fast as you can.
Indeed.

Much better to do:

server.join

instead of using the loop.

-Justin


#5

Ezra, thanks. This worked great! My CPU usage is below 1% now, even with
sleep 0.1.

Ezra Z. wrote:

server.start # Start the server

loop do
break if server.stopped?
end

This last loop looks suspect. You are basically calling
server.stopped? in a loop as fast as you can. Try sleeping a bit in
that loop:

loop do
sleep 1
break if server.stopped?
end

Cheers-
Ezra Z.
removed_email_address@domain.invalid