Gserver hogging CPU

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 Cooper'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
--
Posted via http://www.ruby-forum.com/.

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

···

--
Posted via http://www.ruby-forum.com/.

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 Zygmuntowicz
ez@engineyard.com

···

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

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 Cooper'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

Ezra Zygmuntowicz wrote:

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 Cooper'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

    This last loop looks suspect. You are basically calling server.stopped? in a loop as fast as you can.

Indeed.

Much better to do:

  server.join

instead of using the loop.

-Justin

···

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

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

Ezra Zygmuntowicz 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 Zygmuntowicz
ez@engineyard.com

--
Posted via http://www.ruby-forum.com/.