interacting with ruby program

N

Navindra Umanee

Hi,

Are there any nice or existing solutions for attaching to a running
Ruby process and changing the code on the fly from the console?

Like, say I want to update a variable or modify a method for a Ruby
program that is already running. I guess maybe the Ruby program would
have to allocate a thread/socket for eval requests... it would be
nice if someone already solved this.

Thanks,
Navin.
 
R

Robert Klemme

Navindra Umanee said:
Hi,

Are there any nice or existing solutions for attaching to a running
Ruby process and changing the code on the fly from the console?

Like, say I want to update a variable or modify a method for a Ruby
program that is already running. I guess maybe the Ruby program would
have to allocate a thread/socket for eval requests... it would be
nice if someone already solved this.

Didn't solve this yet, but you could certainly cook something up quite
easily with webrick: just throw out a form with a field for code to enter
and when pressing the button the code is executed and the result is sent
back. That way you can use any browser to access it.

Just my 0.02EUR...

Kind regards

robert
 
N

Navindra Umanee

Robert Klemme said:
Didn't solve this yet, but you could certainly cook something up quite
easily with webrick: just throw out a form with a field for code to enter
and when pressing the button the code is executed and the result is sent
back. That way you can use any browser to access it.

Hmmm, yeah, not yet sure if webrick is an option for me. Need to be
robust and Apache will have to remain on the frontline for other
reasons as well... but I guess it could proxy to webrick.

Thanks for the pointer. I'm still interested in non-webrick based
solutions if anyone has them.

Cheers,
Navin.
 
R

Robert Klemme

Navindra Umanee said:
Hmmm, yeah, not yet sure if webrick is an option for me. Need to be
robust and Apache will have to remain on the frontline for other
reasons as well... but I guess it could proxy to webrick.

Thanks for the pointer. I'm still interested in non-webrick based
solutions if anyone has them.

Didn't know that you have a webserver already. Of course you can use that
(CGI with a proxy script that connects via DRB for example). If that
webserver is publicly available you better make sure that no malicious
code is executed.

Kind regards

robert
 
M

Matt Mower

Are there any nice or existing solutions for attaching to a running
Ruby process and changing the code on the fly from the console?

I don't know if this is possible or not but I seem to remember that
irb has job control. Could you maybe start your app from within irb,
either as a background job or maybe by spawning it in a thread?

Regards,

Matt
 
F

Florian Gross

Navindra said:
Are there any nice or existing solutions for attaching to a running
Ruby process and changing the code on the fly from the console?

Like, say I want to update a variable or modify a method for a Ruby
program that is already running. I guess maybe the Ruby program would
have to allocate a thread/socket for eval requests... it would be
nice if someone already solved this.

This would be possible by using a secondary thread that keeps spawning
up breakpoints. E.g.:

require 'breakpoint'
Thread.new do
loop do
begin
breakpoint
rescue Exception
end
end
end

After that you could use the breakpoint_client to get a live shell where
you could change and check basically everything.

If you want to execute the breakpoints in a different context you can
use breakpoint(nil, TOPLEVEL_BINDING) or breakpoint(nil,
obj.send:)binding)).
 
M

Martin DeMello

Navindra Umanee said:
Hmmm, yeah, not yet sure if webrick is an option for me. Need to be
robust and Apache will have to remain on the frontline for other
reasons as well... but I guess it could proxy to webrick.

Why not just run webrick on an entirely separate port?

martin
 
N

Navindra Umanee

Matt Mower said:
I don't know if this is possible or not but I seem to remember that
irb has job control. Could you maybe start your app from within irb,
either as a background job or maybe by spawning it in a thread?

Oh. I can't figure out how to run something as a background job:

irb(main):001:0> irb # new job
irb#1(main):001:0> booga = "booga"
=> "booga"
irb#1(main):002:0> while true; p booga; sleep 2; end
"booga"
"booga"
"booga"
"booga"
IRB::Abort: abort then interrupt!!
from /usr/lib/ruby/1.8/irb.rb:81
irb#1(main):003:0>

It's in the foreground and if I press Control-C, it aborts. Control-Z
suspends the IRB process itself. Is there some way of backgrounding a
job so that variables can be modified?

I can run it in a new thread like this:

irb(main):001:0> booga = "booga"
=> "booga"
irb(main):002:0> x = Thread.new { while true; p booga; sleep 2; end }
"booga"=> #<Thread:0x402caab0 run>
irb(main):003:0>
"booga"
"booga"

irb(main):004:0* jobs
=> #0->irb on main (#<Thread:0x4029f798>: running)
irb(main):005:0> booga = "blah"
=> "blah"
irb(main):006:0> "blah"
"blah"

That seems to work. Is irb a robust solution?

Thanks,
Navin.
 
D

Dick Davies

* Navindra Umanee said:
Hi,

Are there any nice or existing solutions for attaching to a running
Ruby process and changing the code on the fly from the console?

Like, say I want to update a variable or modify a method for a Ruby
program that is already running. I guess maybe the Ruby program would
have to allocate a thread/socket for eval requests... it would be
nice if someone already solved this.

This sounds a lot like the breakpoint console in Rails - if you haven't
seen that yet, have a look.
 
N

Navindra Umanee

Florian Gross said:
This would be possible by using a secondary thread that keeps spawning
up breakpoints. E.g.:

Interesting. Thanks for this easy looking solution!
require 'breakpoint'

I can't seem to find this in: ruby 1.8.2 (2004-12-25) [i586-linux-gnu]

Is this an external package?
Thread.new do
loop do
begin
breakpoint
rescue Exception
end
end
end

Do you think this would be expensive or does breakpoint simply block
until it gets a connection?
After that you could use the breakpoint_client to get a live shell where
you could change and check basically everything.

If you want to execute the breakpoints in a different context you can
use breakpoint(nil, TOPLEVEL_BINDING) or breakpoint(nil,
obj.send:)binding)).

Thank you very much!

Martin: Yup, that's what I meant by proxy to webrick.

Cheers,
Navin.
 
F

Florian Gross

Navindra said:
require 'breakpoint'

I can't seem to find this in: ruby 1.8.2 (2004-12-25) [i586-linux-gnu]

Is this an external package?

Yup, it's available as part of the Rails package, but I can also mail it
to you privately.
Do you think this would be expensive or does breakpoint simply block
until it gets a connection?

It simply blocks so it ought to be reasonably cheap.
 
N

Navindra Umanee

Florian Gross said:
Yup, it's available as part of the Rails package, but I can also mail it
to you privately.

Thanks. I installed gems and rails. I see you're the author of
breakpoint. It's just beautiful!

I have to admit I'm rather disappointed in gems though. It seems
exceedingly ugly that you have to do:

require 'rubygems'
require_gem 'rails'

to use anything that is gem-installed.

Can't seem to get breakpoint_client working yet, my client hangs but
if I telnet to the drb port, the server seems to be active. Without
"Breakpoint.activate_drb", it works as expected from standard
input/output.

require 'rubygems'
require_gem 'rails'
require 'breakpoint'

Breakpoint.activate_drb

Thread.new do
loop do
begin
breakpoint
rescue Exception
end
end
end

boo="boo"
while true
p boo
sleep 2
end

[vinata] [/tmp] telnet localhost 42531
Trying 127.0.0.1...
Connected to localhost (127.0.0.1).
Escape character is '^]'.
boo
Fo:DRb::DRbConnError:bt[?"//usr/lib/ruby/1.8/drb/drb.rb:570:in `load'"7/usr/lib/ruby/1.8/drb/drb.rb:600:in `recv_request'"7/usr/lib/ruby/1.8/drb/drb.rb:899:in `recv_request'"</usr/lib/ruby/1.8/drb/drb.rb:1453:in `init_with_client'"9/usr/lib/ruby/1.8/drb/drb.rb:1465:in `setup_message'"3/usr/lib/ruby/1.8/drb/drb.rb:1435:in `perform'"5/usr/lib/ruby/1.8/drb/drb.rb:1512:in `main_loop'"0/usr/lib/ruby/1.8/drb/drb.rb:1508:in `loop'"5/usr/lib/ruby/1.8/drb/drb.rb:1508:in `main_loop'"1/usr/lib/ruby/1.8/drb/drb.rb:1504:in `start'"5/usr/lib/ruby/1.8/drb/drb.rb:1504:in `main_loop'"//usr/lib/ruby/1.8/drb/drb.rb:1371:in `run'"1/usr/lib/ruby/1.8/drb/drb.rb:1368:in `start'"//usr/lib/ruby/1.8/drb/drb.rb:1368:in `run'"6/usr/lib/ruby/1.8/drb/drb.rb:1293:in `initialize'"//usr/lib/ruby/1.8/drb/drb.rb:1549:in `new'"9/usr/lib/ruby/1.8/drb/drb.rb:1549:in `start_service'"T/usr/lib/ruby/gems/1.8/gems/rails-0.9.5/lib/breakpoint.rb:371:in `activate_drb'"test.rb:5: mesg" too large packet 1651470093Conn!
ection closed by foreign host.
Exit 1
[vinata] [/tmp] ruby breakpoint_client.rb
No connection to breakpoint service at druby://localhost:42531 (Interrupt)
Tries to connect will be made every 3 seconds...
breakpoint_client.rb:189:in `sleep': Interrupt
from breakpoint_client.rb:189
from breakpoint_client.rb:147:in `loop'
from breakpoint_client.rb:147
Exit 1

Thanks,
Navin.
 
Z

Zach Dennis

Navindra said:
Thanks. I installed gems and rails. I see you're the author of
breakpoint. It's just beautiful!

I have to admit I'm rather disappointed in gems though. It seems
exceedingly ugly that you have to do:

require 'rubygems'
require_gem 'rails'

to use anything that is gem-installed.

You don't anymore, now you can just say:

require "rubygems"
require "rails"

Zach
 
F

Florian Gross

Navindra said:
Thanks. I installed gems and rails. I see you're the author of
breakpoint. It's just beautiful!

Thank you, always nice to get positive feedback. :)
I have to admit I'm rather disappointed in gems though. It seems
exceedingly ugly that you have to do:

require 'rubygems'
require_gem 'rails'

to use anything that is gem-installed.

Lately they seem to be munging RUBYOPT which causes other problems.
Personally I think the best way of doing this is the RPA way which just
adds its custom library directory to Ruby's library load path.

Anyway, I'd suggest just copying the breakpoint files to your
application directly for now as loading the whole Rails library seems to
be a bit too much overhead.

I'll do stand-alone releases of the breakpointing library in the future
via RubyGems and RPA so the process will get a bit easier. Right now I'm
however still investigating a few odd bugs.
Can't seem to get breakpoint_client working yet, my client hangs but
if I telnet to the drb port, the server seems to be active. Without
"Breakpoint.activate_drb", it works as expected from standard
input/output.

You have to use the breakpoint_client (also available from Rails) as the
underlying protocol is DRb and not Telnet. It was a bit easier to code
that way.
 
N

Navindra Umanee

Florian Gross said:
You have to use the breakpoint_client (also available from Rails) as the
underlying protocol is DRb and not Telnet. It was a bit easier to code
that way.

I am. The telnet was just a test to see if the server was running.
If you look at the end of the previous email you'll see I copied what
happened when I run breakpoint_client (it just hangs until I press
Ctl-C):

[vinata] [/tmp] ruby breakpoint_client.rb
No connection to breakpoint service at druby://localhost:42531 (Interrupt)
Tries to connect will be made every 3 seconds...
breakpoint_client.rb:189:in `sleep': Interrupt
from breakpoint_client.rb:189
from breakpoint_client.rb:147:in `loop'
from breakpoint_client.rb:147

Thanks,
Navin.
 
N

Navindra Umanee

Navindra Umanee said:
I am. The telnet was just a test to see if the server was running.
If you look at the end of the previous email you'll see I copied what
happened when I run breakpoint_client (it just hangs until I press
Ctl-C):

I added some debug statements. The client gets up to:

service.eval_handler = Handlers.method:)eval_handler)

but it hangs on that. I'm not sure why or where to go from there.
Maybe it's a drb issue.

Cheers,
Navin.
 
F

Florian Gross

Navindra said:
I added some debug statements. The client gets up to:

service.eval_handler = Handlers.method:)eval_handler)

but it hangs on that. I'm not sure why or where to go from there.
Maybe it's a drb issue.

It's the first method invocation. So it still seems to be some kind of
connectivity problem. I'm not 100%ly sure, though.
 
N

Navindra Umanee

Florian Gross said:
It's the first method invocation. So it still seems to be some kind of
connectivity problem. I'm not 100%ly sure, though.

Thanks for your help in solving this by private email!

Turns out the server was binding to localhost by default, but the
client was trying to bind to my machine name's IP. That latter didn't
work because my machine wasn't on the local network, and so that
IP/interface was inactive.

Solution is to either force the client to use localhost or to update
my hosts file. :)

Cheers,
Navin.
 
F

Florian Gross

Navindra said:
Thanks for your help in solving this by private email!

Turns out the server was binding to localhost by default, but the
client was trying to bind to my machine name's IP. That latter didn't
work because my machine wasn't on the local network, and so that
IP/interface was inactive.

Solution is to either force the client to use localhost or to update
my hosts file. :)

I'll also have a look at trying to bind to druby://localhost:42530 and
falling back to the current behavior if that fails. I'm not yet sure how
to detect the failure, but I'm pretty sure it is doable somehow.

Thanks again for finding out about this issue.
 
C

Csaba Henk

Are there any nice or existing solutions for attaching to a running
Ruby process and changing the code on the fly from the console?

Like, say I want to update a variable or modify a method for a Ruby
program that is already running. I guess maybe the Ruby program would
have to allocate a thread/socket for eval requests... it would be
nice if someone already solved this.

I work on something like this. I just named my app interact.rb, which
sounds hopefully, eh?

Now it's by-and-large useable, but needs some cleanup, and I have things
to do with higher priority than this (both ruby-related and
non-ruby-related), so I don't yet feel like making it public, and won't
feel like that tomorrow either. (I hope I'll be able to get a grasp on
it in one or two weeks or so).

If you'd like to take a look at it, drop me a line to

"(e-mail address removed)".sub(/rubbish/,"math")

Csaba
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top