Accessing Ruby Object in Memory

B

Bryan Richardson

Hello all,

I have a long running Ruby simulation in which data is stored to Ruby
hashes throughout the simulation. I'd like to be able to access the
hashes in memory from another Ruby script while the simulation is still
running to see what the progress of the simulation is (rather than
printing to the screen, using log4r, etc. Is this possible? If so, any
suggestions how to do so?
 
T

Thomas B.

Bryan said:
Hello all,

I have a long running Ruby simulation in which data is stored to Ruby
hashes throughout the simulation. I'd like to be able to access the
hashes in memory from another Ruby script while the simulation is still
running to see what the progress of the simulation is (rather than
printing to the screen, using log4r, etc. Is this possible? If so, any
suggestions how to do so?

Hello. I guess this is not possible, and even if it is, it is not a good
idea to do this. Probably a much better idea would be to start a TCP
server in the daemon, and connect to it from the other program, and
communicate using some simple protocol. Another idea could be to write
some progress info into a file, and open the file from the other
process, but then you'll have to handle some concurrency problems (not
very hard, I guess, it will be enough to wait a moment and retry on file
opening failure). But still I think the server is a better and more
standard way to do this. Have a look at TCPServer and TCPSocket in
'socket', it is not hard.

TPR.
 
J

Joel VanderWerf

Thomas said:
Hello. I guess this is not possible, and even if it is, it is not a good
idea to do this. Probably a much better idea would be to start a TCP
server in the daemon, and connect to it from the other program, and
communicate using some simple protocol. Another idea could be to write
some progress info into a file, and open the file from the other
process, but then you'll have to handle some concurrency problems (not
very hard, I guess, it will be enough to wait a moment and retry on file
opening failure). But still I think the server is a better and more
standard way to do this. Have a look at TCPServer and TCPSocket in
'socket', it is not hard.

DRb is the canonical way of doing this if both processes are ruby
programs. For example:

== server.rb ==
require 'drb'

uri = "drbunix:/tmp/my-simulation.sock" # use "localhost:4444" on win
h = {1=>2, 3=>4}
DRb.start_service(uri, h)
DRb.thread.join

== client.rb ==
require 'drb'

uri = "drbunix:/tmp/my-simulation.sock" # use "localhost:4444" on win
DRb.start_service(nil, nil)
server_object = DRbObject.new(nil, uri)

p server_object.keys
server_object.each do |k, v|
p [k, v]
end

================
Output:

[1, 3]
[1, 2]
[3, 4]
 
R

Robert Klemme

I have a long running Ruby simulation in which data is stored to Ruby
hashes throughout the simulation. I'd like to be able to access the
hashes in memory from another Ruby script while the simulation is still
running to see what the progress of the simulation is (rather than
printing to the screen, using log4r, etc. Is this possible? If so, any
suggestions how to do so?

Please look into DRb. For pure status updates I would push the current
state to the other process as opposed to pulling it because this does
not need synchronization in the simulation. You can find a working toy
example attached.

Kind regards

robert


#!/bin/env ruby

require 'drb'
require 'monitor'

URI = "druby://127.0.0.1:13344"

class Status

def initialize
self.extend MonitorMixin
self.finished = 0
end

def finished
synchronize do
@finished
end
end

def finished=(f)
synchronize do
@finished = f
end
end

def done
self.finished = 100
end
end

fork do
status = Status.new
DRb.start_service URI, status

loop do
st = status.finished
printf "Finished %5.1f%%\n", st
break if st >= 100
sleep 2
end
DRb.stop_service
puts 'client done'
end

DRb.start_service
st = DRbObject.new nil, URI

100.times do |i|
sleep((rand(100) + 1) / 100.0)
st.finished = i
end
st.done

puts 'server done'
DRb.stop_service
 
J

Joel VanderWerf

Two addenda:

1. if the comm seems slow, try setting

Socket.do_not_reverse_lookup = true

2. the url for windows (and other tcp) should be:

uri = "druby://localhost:4444"


So here's the example again:

== server.rb ==
require 'drb'

Socket.do_not_reverse_lookup = true

uri = "druby://localhost:4444"
h = {1=>2, 3=>4}
DRb.start_service(uri, h)
DRb.thread.join

== client.rb ==
require 'drb'

Socket.do_not_reverse_lookup = true

uri = "druby://localhost:4444"
DRb.start_service(nil, nil)
server_object = DRbObject.new(nil, uri)

p server_object.keys
server_object.each do |k, v|
p [k, v]
end
 

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

No members online now.

Forum statistics

Threads
474,262
Messages
2,571,059
Members
48,769
Latest member
Clifft

Latest Threads

Top