NoMethodError in protocol.rb

Does this look familiar to anyone?

NoMethodError: undefined method +' for nil:NilClass at /usr/local/lib/ruby/1.8/net/protocol.rb:176:inwrite0’

I’m getting it sporadically during some fairly heavy XMLRPC traffic. It
doesn’t make very much sense to me, because write0 looks like this:

def write0(str)
@debug_output << str.dump if @debug_output
len = @io.write(str)
@written_bytes += len # <= line 176
len
end

The error must mean that @written_bytes is nil. It’s only called from
within a block passed to writing, which looks like this:

def writing
@written_bytes = 0
@debug_output << '<- ’ if @debug_output
yield
@debug_output << “\n” if @debug_output
bytes = @written_bytes
@written_bytes = nil
bytes
end

Is this a known thread-safety issue with a known solution, or would a
patch be in order? I’ve been testing this on 1.8.4, because that’s what
we’ve got in production. Does anyone know if it’s been addressed in
1.8.5?

Thanks,

Alex Y. wrote:

len = @io.write(str)
yield
You aren’t showing us the block to which this yield refers. Does that
block
modify @written_bytes?

@debug_output << “\n” if @debug_output
bytes = @written_bytes
@written_bytes = nil
bytes

Okay, here you are modifying the @written_bytes class variable,
assigning it
nil, and this is likely to be the problem. Can I ask why you are using
an
instance variable here rather than a method-local one? Can’t this need
be
met by a local variable?

end

Is this a known thread-safety issue with a known solution, or would a
patch be in order? I’ve been testing this on 1.8.4, because that’s what
we’ve got in production. Does anyone know if it’s been addressed in
1.8.5?

AFAICS, it’s not yet obvious to me that it is a language issue, as
opposed
to a coding issue.

On Dec 7, 2006, at 02:13 , Alex Y. wrote:

@debug_output << str.dump if @debug_output
@debug_output << '<- ’ if @debug_output
yield
@debug_output << “\n” if @debug_output
bytes = @written_bytes
@written_bytes = nil

Yes, this is going to be a problem in a multithreaded environment.

bytes
end

Is this a known thread-safety issue with a known solution, or would
a patch be in order? I’ve been testing this on 1.8.4, because
that’s what we’ve got in production.

I’ve not heard of it before.

Does anyone know if it’s been addressed in 1.8.5?

Doubtful.


Eric H. - [email protected] - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!

On Dec 7, 2006, at 02:30 , Paul L. wrote:

def write0(str)
def writing
@written_bytes = 0
@debug_output << '<- ’ if @debug_output
yield

You aren’t showing us the block to which this yield refers. Does
that block
modify @written_bytes?

Irrelevant. #write0 is the code you are looking for.

@debug_output << “\n” if @debug_output
bytes = @written_bytes
@written_bytes = nil
bytes

Okay, here you are modifying the @written_bytes class variable

There are no class variables here, only instance variables.

, assigning it nil, and this is likely to be the problem. Can I ask
why you are using an instance variable here rather than a method-
local one? Can’t this need be met by a local variable?

This is from protocol.rb. See #write0 above for why an instance
variable in necessary.


Eric H. - [email protected] - http://blog.segment7.net

I LIT YOUR GEM ON FIRE!

Eric H. wrote:

On Dec 7, 2006, at 02:13 , Alex Y. wrote:

Does this look familiar to anyone?

NoMethodError: undefined method +' for nil:NilClass at /usr/local/lib/ruby/1.8/net/protocol.rb:176:inwrite0’

bytes
Doubtful.

I’ve found a workaround for our code, anyway. I’m not quite sure why I
was surprised that the HTTP library isn’t thread-safe :slight_smile:

Thanks,