Forum: JRuby [jruby-1.7.0.preview2] WebBrick: ERROR RuntimeError: can't add a new key into hash during iteration

Posted by Mark Mandel (Guest)
on 2012-08-20 04:56
(Received via mailing list)
I've got a REST webservice I've built with JRuby 1.7 p2, Sinatra and 
Mizuno.

Intermittently, and only under some load, I see the following error from 
it:

[2012-08-19 21:13:50] ERROR RuntimeError: can't add a new key into hash
during iteration
 org/jruby/RubyHash.java:905:in `[]='
/opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:205:in `register'
 /opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:161:in `register'
org/jruby/ext/thread/Mutex.java:149:in `synchronize'
 /opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:160:in `register'
/opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:232:in `timeout'
 /opt/jruby/active/lib/ruby/1.9/webrick/httprequest.rb:398:in 
`_read_data'
/opt/jruby/active/lib/ruby/1.9/webrick/httprequest.rb:409:in `read_line'
 /opt/jruby/active/lib/ruby/1.9/webrick/httprequest.rb:314:in 
`read_header'
/opt/jruby/active/lib/ruby/1.9/webrick/httprequest.rb:92:in `parse'
 /opt/jruby/active/lib/ruby/1.9/webrick/httpserver.rb:81:in `run'
/opt/jruby/active/lib/ruby/1.9/webrick/server.rb:191:in `start_thread'
NoMethodError: undefined method `<' for nil:NilClass
  initialize at /opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:181
        each at org/jruby/RubyArray.java:1612
  initialize at /opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:179
        each at org/jruby/RubyHash.java:1192
  initialize at /opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:178

It seems to be coming from inside of webrick, so I'm at a loss as to 
what I
could be doing that would be causing this?

The upstart command for Mizuno is the following:
exec su -c 'cd /home/foo/current; ./bin/mizuno >> output.log 2>&1' -l 
deploy

Any help would be appreciated in working out what is causing the error.

Thanks!

Mark





--
E: mark.mandel@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast
http://www.2ddu.com/
Posted by Keith B. (keith_b)
on 2012-08-20 13:08
(Received via mailing list)
Mark -

I've had issues like this when modifying a hash that I am already
iterating over.  So instead of:

my_hash.each_pair { ... do something that potentially modifies the hash
... }

keys = my_hash.keys
keys.each { ... do something that potentially modifies the hash ... }

(or my_hash.keys.each {}, I think would work too.)

Don't know if this is your issue, but I hope it helps.

Are you deleting a key inside the loop?  If so, I don't think the
enumerable on which the loop depends would know.  It would try to
perform an iteration on that key, that would now be missing.

If you're just adding keys, and you're iterating over the hash to which
you're adding them, you might instead want to create a temporary hash
for the additions within the loop, and then merge the two hashes after
the loop.

- Keith

--
Keith R. Bennett
http://about.me/keithrbennett
Posted by Mark Mandel (Guest)
on 2012-08-20 13:36
(Received via mailing list)
Thanks for the advice.

The only issue is, it's inside JRuby's Webrick implementation that the
error is occurring, which is not something I have control over:
https://github.com/jruby/jruby/blob/master/lib/rub...

It seems to only happen once until all the values get populated, but the
error seems to be while this loop is running:
https://github.com/jruby/jruby/blob/master/lib/rub...

Seems like a bug in the webrick implementation, no?

@timeout_info.each {} is iterating, while @timeout_info[thread] ||= 
Array.new
is adding new values to the hash.

The error stops happening once the thread pool has filled, and the hash
doesn't get iterated over anymore.  And it happens intermittently, just
because the while loop could be sleeping during that time.

I think you are right though, I could monkey patch this to use
@timeout_info.keys.each, and see if that resolves the issue, and if so,
push it back.

Thanks for your help!

Mark


On Mon, Aug 20, 2012 at 9:07 PM, Keith Bennett 
<keithrbennett@gmail.com>wrote:

>
> the additions within the loop, and then merge the two hashes after the loop.
>
>  /opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:232:in `timeout'
>   initialize at /opt/jruby/active/lib/ruby/1.9/webrick/utils.rb:179
>  Any help would be appreciated in working out what is causing the error.
> E: mark.mandel@gmail.com
> T: http://www.twitter.com/neurotic
> W: www.compoundtheory.com
>
> 2 Devs from Down Under Podcast
> http://www.2ddu.com/
>
>
>


--
E: mark.mandel@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast
http://www.2ddu.com/
Posted by Keith B. (keith_b)
on 2012-08-20 13:50
(Received via mailing list)
Mark -

My opinion is that even if the error only manifests itself
intermittently, the issue is a conceptual one (not to modify the hash
you're iterating over), and it's best to avoid it.

Cheers,
Keith

--
Keith R. Bennett
http://about.me/keithrbennett
Posted by Mark Mandel (Guest)
on 2012-08-20 13:56
(Received via mailing list)
Sorry, I'm confused - are you saying that I shouldn't be using a web
framework with a Webrick layer then?

Mark

On Mon, Aug 20, 2012 at 9:50 PM, Keith Bennett 
<keithrbennett@gmail.com>wrote:

> My opinion is that even if the error only manifests itself intermittently,
> the issue is a conceptual one (not to modify the hash you're iterating
> over), and it's best to avoid it.




--
E: mark.mandel@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast
http://www.2ddu.com/
Posted by Keith B. (keith_b)
on 2012-08-20 13:58
(Received via mailing list)
No, not at all.  I'm just saying that it's better not to iterate over
the hash, but instead get its keys, and then loop on them.

I may be misunderstanding your code, but I thought you were using
hash.each_pair or something like that.

- Keith

--
Keith R. Bennett
http://about.me/keithrbennett
Posted by Mark Mandel (Guest)
on 2012-08-20 14:03
(Received via mailing list)
I think were we are getting our wires crossed is over one specific 
point:
This is not my code. This is code that is implement in JRuby's
implementation of Webrick.

I have no control over that code whatsoever, unless I monkey patch it or
similar.

(if you look at the source links, you can see it all goes back to the
official JRuby GitHub repository).

Either way, what you were saying is making a lot of sense, and I may be
able to patch this code and push it back to JRuby (here's hoping I don't
break anything).

Mark

On Mon, Aug 20, 2012 at 9:57 PM, Keith Bennett 
<keithrbennett@gmail.com>wrote:

> Keith R. Bennetthttp://about.me/keithrbennett
>> My opinion is that even if the error only manifests itself
>
> 2 Devs from Down Under Podcast
> http://www.2ddu.com/
>
>
>


--
E: mark.mandel@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast
http://www.2ddu.com/
Posted by kristian (Guest)
on 2012-08-20 14:09
(Received via mailing list)
I guess first step is to monkey patch and see if it helps :)

that code comes from ruby stdlib - not sure where the right place for
patching JRuby problems with this though.

I just needed added my two cents to this thread :)
-Kristian
Posted by Mark Mandel (Guest)
on 2012-08-21 01:44
(Received via mailing list)
Thanks for your help.

Actual crux of my issue - my config.ru was totally not correct, and I 
was
actually just running Webrick, rather than Mizuno.

* facepalm *

Live and learn.

Mark

On Mon, Aug 20, 2012 at 10:08 PM, kristian <m.kristian@web.de> wrote:

>
>     http://xircles.codehaus.org/manage_email
>
>
>


--
E: mark.mandel@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast
http://www.2ddu.com/
Posted by Brian Walsh (bwalsh)
on 2012-11-05 18:39
(Received via mailing list)
I'm having the same problem with:

jruby 1.7.0
rails (3.2.8)

Is there a specific change to enable testing with webrick?

-b
Posted by Charles Nutter (headius)
on 2012-11-05 19:10
(Received via mailing list)
After reading through this thread, I'm not clear whether there's an
issue to be fixed here. Seems like the original reporter's issue was
due to a bad config.ru. And if there's actually anything to be fixed,
it sounds like it's something in WEBrick.

At this point, if there's an issue, please file it and we'll try to fix 
it.

- Charlie
Posted by Brian Walsh (bwalsh)
on 2012-11-05 21:25
(Received via mailing list)
Agreed.  I just tested with trinidad and did not have this problem.

Thank you
On Nov 5, 2012 10:09 AM, "Charles Oliver Nutter" <headius@headius.com>
Posted by Mark Mandel (Guest)
on 2012-11-05 22:31
(Received via mailing list)
The upshot was, for my original post:

Don't use webrick in anything in but development (which is well
documented). It tends to fall over under load.

I had a bad config.ru, and also very little knowledge of J/Ruby, and 
din't
realise this, and thought I was running Mizuno (which is fine under 
load),
when in fact all I was running was Webrick.

Mark


On Tue, Nov 6, 2012 at 7:24 AM, Brian Walsh <brian@bwalsh.com> wrote:

>>
>> > rails (3.2.8)
>> >>
>> >> Mark
>> >>> -Kristian
>> >> --
>> > ---------------------------------------------------------------------
>>
>>


--
E: mark.mandel@gmail.com
T: http://www.twitter.com/neurotic
W: www.compoundtheory.com

2 Devs from Down Under Podcast
http://www.2ddu.com/
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.