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