Ik heb een eigen ThreadPool gemaakt waarin ik in mijn code om een of andere voor mij erg vage rede met enige regelmaat de volgende error krijgt:
De code:
Het vreemde is dat de error niet gevangen wordt door het begin rescue end blok.
Nog vreemder is dat ik de fout niet kan reproduceren in testcode en ik helaas de omliggende code niet kan delen.
Mijn vraag is dan ook: In welke gevallen kan de sleep-method een "stack level too deep" error geven? Wat zou de oorzaak kunnen zijn? Is er een manier om een stacktrace te krijgen bij die error? Ik heb 'm nog niet weten te "vangen" met een rescue-blok
AFAIK is stack-level-too-deep alleen van toepassing bij recursieve functies, en sleep is AFAIK geen recursieve functie.
edit:
Na lang puzzelen en sterk veranderen van mijn thread_pool krijg ik opeens deze:
/gems/mechanize-2.0.1/lib/mechanize/form.rb:187: stack level too deep (SystemStackError)
... opnieuw geen backtrace, wel zelfde error.
Waarschijnlijk zit de error gewoon daarin, maar kan-ie op een of andere manier niet "gevangen" ("rescue") worden en krijg ik die error pas bij sleep
code:
1
| thread_pool.rb:44: stack level too deep (SystemStackError) |
De code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
| require "thread"
require "./color_out.rb"
Thread.abort_on_exception = true
class ThreadPool
def initialize(limit)
@queue = []
@queue_mutex = Mutex.new
@threads = []
@threads_running = 0
limit.times do @threads << (Thread.new do
begin
runnable = get_from_queue
if runnable.nil?
sleep 0.1
next
end
@threads_running += 1
begin
runnable[:prc].call *runnable[:args]
rescue => e
ColorOut.puts_red "IN THREADPOOL: <#{e.class}> #{e.message}\r\n#{e.backtrace.join "\r\n"}"
end
@threads_running -= 1
end while true
end)
end
end
def add_to_queue(*args, &block)
@queue_mutex.synchronize do
@queue << { :args => args, :prc => Proc.new(&block) }
end
end
def threads
@threads
end
def join
begin
sleep 0.1
rescue => e
ColorOut.puts_red "ThreadPool#join: <#{e.class}> #{e.message}"
retry
end while queue_length > 0 || @threads_running > 0
end
def queue_length
@queue.length
end
def get_from_queue
runnable = nil
@queue_mutex.synchronize do
runnable = @queue.shift
end
runnable
end
end |
Het vreemde is dat de error niet gevangen wordt door het begin rescue end blok.
Nog vreemder is dat ik de fout niet kan reproduceren in testcode en ik helaas de omliggende code niet kan delen.
Mijn vraag is dan ook: In welke gevallen kan de sleep-method een "stack level too deep" error geven? Wat zou de oorzaak kunnen zijn? Is er een manier om een stacktrace te krijgen bij die error? Ik heb 'm nog niet weten te "vangen" met een rescue-blok
AFAIK is stack-level-too-deep alleen van toepassing bij recursieve functies, en sleep is AFAIK geen recursieve functie.
edit:
Na lang puzzelen en sterk veranderen van mijn thread_pool krijg ik opeens deze:
/gems/mechanize-2.0.1/lib/mechanize/form.rb:187: stack level too deep (SystemStackError)
... opnieuw geen backtrace, wel zelfde error.
Waarschijnlijk zit de error gewoon daarin, maar kan-ie op een of andere manier niet "gevangen" ("rescue") worden en krijg ik die error pas bij sleep
[ Voor 10% gewijzigd door Gamebuster op 07-09-2011 21:59 ]
Let op: Mijn post bevat meningen, aannames of onwaarheden