Bug #2158
closed
KB cache recalculator: undefined method write
Added by Alexey Khoroshilov almost 13 years ago.
Updated over 12 years ago.
Description
На falcon:
Killing KB cache recalculator...
KB cache recalculator is (hopefully) dead.
/home/tester/ldv/opt/ldv-manager/upload_utils.rb:66:in `block in push': undefined method `write' for nil:NilClass (NoMethodError)
from <internal:prelude>:10:in `synchronize'
from /home/tester/ldv/opt/ldv-manager/upload_utils.rb:64:in `push'
from /home/tester/ldv/opt/bin/ldv-upload:37:in `block in <main>'
from /home/tester/ldv/opt/bin/ldv-upload:682:in `[]'
from /home/tester/ldv/opt/bin/ldv-upload:682:in `<main>'
Что-то надо доставить? Или проблемы с ruby-1.9?
- Category set to Infrastructure
- Status changed from New to Feedback
I saw source:ldv-manager/upload_utils.rb and found out that the problem is related with null pointer dereference that occurs either because of missed initialization or some race. May be there are some other error messages in log, can you examine or attach the full log?
There are no other error messages even with LDV_DEBUG=100.
But it looks like the code inside @thread = Thread.new does work at all.
The reason is a race condition. The new thread does not start before the first push, so it has no chance to lock the mutex.
I have pushed a fix to qa.
- Status changed from Feedback to Resolved
Cool! I have just one assumption. May be we should move
# The mutex will block "write" until everything is initialized
@pipe_guard.lock
outside a new thread execution instead of creating additional
init_guard flag? In this case at the beginning of initialization
write will be blocked untill a new thread creates pipes. After creature this thread unlocks
write:
# Unlock "write" call
@pipe_guard.unlock
Evgeny Novikov wrote:
Cool! I have just one assumption. May be we should move
[...]
outside a new thread execution instead of creating additional init_guard flag? In this case at the beginning of initialization write will be blocked untill a new thread creates pipes. After creature this thread unlocks write:
[...]
As far as I understand, mutex in Ruby have to be locked and unlocked by the same thread. That is why lock have to be left in the new thread.
Alexey Khoroshilov wrote:
As far as I understand, mutex in Ruby have to be locked and unlocked by the same thread. That is why lock have to be left in the new thread.
I have tried and found out that this is true. That's why mutexes are useless in this case at all and we should remove them completely. Also I found a workaround for it here (it's similar to your, but may be nicer). I tried it:
require 'thread'
q = Queue.new
@input_pipe = nil
@thread = Thread.new do
sleep(1)
@input_pipe = "abc"
q.push(:dummy)
end
q.pop
print @input_pipe
and found out that it works (the program prints "abc").
Vadim Mutilin wrote:
TODO: use Condition Variables (www.rubycentral.com/pickaxe/tut_threads.html) instead of busy wait on init_guard variable
Does this belong to the given issue or to the separate one? It seems to me, that the given issue should be closed (may be just take into account comment 8).
Alexey, please close the issue if you haven't any objections.
- Status changed from Resolved to Closed
Also available in: Atom
PDF