STOMP Client on JRuby
July 16, 2010
I recently needed to make use of our ActiveMQ message queue service to scale up write performance of CouchDB. However, there seemed to be a bug with JRuby that kills off the STOMP subscriber every 5 seconds. Digging a bit deeper into the STOMP source, I figured out a way to get around the bug by removing the timeout line.
ActiveMQ let me scale CouchDB writes from 10req/sec to 128req/sec. Huge performance win with very little effort.
STOMP Library Monkey Patch:
# for stomp subscriber if defined?(JRUBY_VERSION) module Stomp class Connection def _receive( read_socket ) @read_semaphore.synchronize do line = read_socket.gets return nil if line.nil? # If the reading hangs for more than 5 seconds, abort the parsing process #Timeout::timeout(5, Stomp::Error::PacketParsingTimeout) do # Reads the beginning of the message until it runs into a empty line message_header = '' begin message_header += line begin line = read_socket.gets rescue p read_socket end end until line =~ /^\s?\n$/ # Checks if it includes content_length header content_length = message_header.match /content-length\s?:\s?(\d+)\s?\n/ message_body = '' # If it does, reads the specified amount of bytes char = '' if content_length message_body = read_socket.read content_length[1].to_i raise Stomp::Error::InvalidMessageLength unless parse_char(read_socket.getc) == "\0" # Else reads, the rest of the message until the first \0 else message_body += char while read_socket.ready? && (char = parse_char(read_socket.getc)) != "\0" end # If the buffer isn't empty, reads the next char and returns it to the buffer # unless it's a \n if read_socket.ready? last_char = read_socket.getc read_socket.ungetc(last_char) if parse_char(last_char) != "\n" end # Adds the excluded \n and \0 and tries to create a new message with it Message.new(message_header + "\n" + message_body + "\0") end #end end end end end
Hi Victor,
I am using the stomp 1.2.2 with jruby 1.6.7 and my stomp publisher works fine but the consumer doesn’t,it returns nil data even if the destination queue contains messages.Same code if i run in ruby 1.9.3 everything works fine.Any idea what could be wrong? I dont get timeout error,consumer doesn’t wait,it exits immediately, i think read_socket.gets itself returns nil in my case(referring above code)
HM i agree to with bharat…
awosome