Created
December 22, 2014 15:09
-
-
Save kares/0e68e079dd25fd21e054 to your computer and use it in GitHub Desktop.
Celluloid.stack_dump tunings on JRuby
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'celluloid/stack_dump' | |
module Celluloid | |
class StackDump | |
class ActorState | |
attr_accessor :thread_name, :thread_id | |
def dump | |
string = "" | |
string << "Celluloid::Actor 0x#{subject_id.to_s(16)}: #{subject_class}" | |
string << " [#{name}]" if name | |
if thread_id | |
string << " (##{thread_id}" | |
string << " #{thread_name}" if thread_name | |
string << ")" | |
end | |
string << "\n" | |
if status == :idle | |
string << "State: Idle (waiting for messages)\n" | |
display_backtrace backtrace, string | |
else | |
string << "State: Running (executing tasks)\n" | |
display_backtrace backtrace, string | |
string << "\tTasks:\n" | |
tasks.each_with_index do |task, i| | |
string << "\t #{i+1}) #{task.task_class}[#{task.type}]: #{task.status}\n" | |
string << "\t #{task.meta.inspect}\n" | |
display_backtrace task.backtrace, string, "\t" | |
end | |
end | |
string | |
end | |
end | |
class ThreadState | |
attr_accessor :thread_name | |
def dump | |
string = "" | |
if thread_name | |
string << "Thread (##{thread_id} #{thread_name}):\n" | |
else | |
string << "Thread 0x#{thread_id.to_s(16)}:\n" | |
end | |
display_backtrace backtrace, string | |
string | |
end | |
end | |
# attr_accessor :actors, :threads | |
# | |
# def initialize | |
# @actors = [] | |
# @threads = [] | |
# | |
# snapshot | |
# end | |
# | |
# def snapshot | |
# Celluloid.internal_pool.each do |thread| | |
# if thread.role == :actor | |
# @actors << snapshot_actor(thread.actor) if thread.actor | |
# else | |
# @threads << snapshot_thread(thread) | |
# end | |
# end | |
# end | |
def snapshot_actor(actor) | |
state = ActorState.new | |
state.subject_id = actor.subject.object_id | |
state.subject_class = actor.subject.class | |
tasks = actor.tasks | |
if tasks.empty? | |
state.status = :idle | |
else | |
state.status = :running | |
state.tasks = tasks.to_a.map { |t| TaskState.new(t.class, t.type, t.meta, t.status, t.backtrace) } | |
end | |
state.backtrace = actor.thread.backtrace if actor.thread | |
state.thread_id = real_thread_id(actor.thread) if actor.thread | |
state.thread_name = real_thread_name(actor.thread) if actor.thread | |
state | |
end | |
def snapshot_thread(thread) | |
state = ThreadState.new(thread.object_id, thread.backtrace) | |
id = real_thread_id(thread) | |
state.thread_id = id if id | |
name = real_thread_name(thread) | |
state.thread_name = name if name | |
state | |
end | |
def real_thread_name(thread) | |
if thread.is_a?(ThreadHandle) | |
if thread = thread.instance_variable_get(:@thread) | |
return thread[:name] || thread.to_java.native_thread.name | |
end | |
elsif thread.is_a?(::Thread) | |
return thread[:name] || thread.to_java.native_thread.name | |
end | |
nil | |
end | |
def real_thread_id(thread) | |
if thread.is_a?(ThreadHandle) | |
if thread = thread.instance_variable_get(:@thread) | |
return thread.object_id | |
end | |
elsif thread.is_a?(::Thread) | |
return thread.object_id | |
end | |
nil | |
end | |
def dump(output = STDERR) | |
@actors.each do |actor| | |
output.print actor.dump | |
end | |
@threads.each do |thread| | |
output.print thread.dump | |
end | |
end | |
end | |
end | |
## ROLL THIS SHIT : | |
Thread.new do | |
Thread.current[:name] = 'Celluloid.stack_dump' | |
Thread.current.to_java.native_thread.setPriority 5 + 2 | |
every = 1.0; counter = 0 | |
base = Time.now.strftime("%y-%m-%d@%H:%M:%S") | |
loop do | |
begin | |
sleep every | |
suffix = format '%04d', (counter += 1) | |
suffix << '_' << Time.now.strftime("%H:%M:%S") | |
file = "#{Rails.root}/log/celluloid_dump_#{base}.#{suffix}" | |
File.open(file, 'w') { |io| Celluloid.stack_dump(io) } | |
rescue => e | |
Logging.logger.root.error("Celluloid.stack_dump FAILED: #{e}\n #{e.backtrace.join("\n ")}") | |
end | |
end | |
end if false |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment