Bug #2158
closedKB cache recalculator: undefined method write
0%
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?
Updated by Evgeny Novikov almost 13 years ago
- 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?
Updated by Alexey Khoroshilov almost 13 years ago
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.
Updated by Alexey Khoroshilov almost 13 years ago
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.
Updated by Alexey Khoroshilov almost 13 years ago
- Status changed from Feedback to Resolved
Updated by Evgeny Novikov almost 13 years ago
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
Updated by Alexey Khoroshilov almost 13 years ago
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.
Updated by Evgeny Novikov almost 13 years ago
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").
Updated by Vadim Mutilin almost 13 years ago
TODO: use Condition Variables (www.rubycentral.com/pickaxe/tut_threads.html) instead of busy wait on init_guard variable
Updated by Evgeny Novikov almost 13 years ago
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).
Updated by Evgeny Novikov almost 13 years ago
Alexey, please close the issue if you haven't any objections.
Updated by Evgeny Novikov over 12 years ago
- Status changed from Resolved to Closed