Drb and observer pattern

Hi all and have a happy new year everybody!

I’m trying to built a set of programs that

  • may run on different machines, or as different processes on one machine
  • I’d like to have one program to notify other(s) of certain events

Now I thought that combining DRb and the Observer pattern might be the
way to go, but as I’m posting a question I apparently ran into an error.

BTW, I’m running a SuSE Linux 9.0 with ruby 1.8.1
[884] stk@tao ~/devel/util: ruby -v
ruby 1.8.1 (2003-12-25) [i686-linux]

I boiled down the server part to this:

==> File: Notifier.rb

require "drb/drb"
require “observer”

class Notifier
include Observable
def change( i )
puts "Changing: #{’%2d’ % i}"
changed( true )
notify_observers( Time.now, i )
end
end

DRb.start_service( ‘druby://localhost:4711’, Notifier.new )
puts DRb.uri
DRb.thread.join

The program using that service got shortened to this:

require ‘drb’

class Dummy
def initialize( observed )
observed.add_observer( self )
end

define update as required by the Observer module

def update( *args )
puts "!!!"
p *args
end
end

notifier = DRbObject.new( nil, ‘druby://localhost:4711’ )
d = Dummy.new( notifier )

Do something with the notifier to get d’s ‘update’ called

notifier.change( rand( 10 ) )

Now, running the notifier works fine, but starting the client leaves me
with this:

[884] stk@tao ~/devel/util: ruby dummy.rb
(druby://localhost:4711) /usr/local/lib/ruby/1.8/observer.rb:126:in
add_observer': Observer <Dummy> needs to respond to 'update'. (NoMethodError) from dummy.rb:5:ininitialize’
from dummy.rb:15:in `new’
from dummy.rb:15

{ Note that I changed the part of ‘observer.rb’ to give some information
about the observer that leads to the exception - just to be sure that
it’s an Object of class Dummy that rose the exception. }

Now, why do I get the exception? I defined ‘update’ of objects of class
Dummy, didn’t I?

Where’s my mistake? Is it that way a good way anyway?

Happy rubying!

Stephan

Stephan Kämper said:

Where’s my mistake? Is it that way a good way anyway?

Have a look at the thread starting at ruby-talk:88698.

Regards,
Andre

Andre Nathan wrote:

Have a look at the thread starting at ruby-talk:88698.

Hi all,

Andre, thanks for the link to the earlier discussion.

Now the ‘compressed’ notifier looks like this…

require ‘drb’
require ‘drb/observer’

class Notifier
include Observable
include DRb::DRbUndumped

def change( i )
puts “Changing: #{‘%2d’ % i}”
changed( true )
notify_observers( Time.now, i )
end
end

DRb.start_service( ‘druby://tao:4711’, Notifier.new )
puts DRb.uri
DRb.thread.join

…and the client like that:

require ‘drb’

class Client
include DRb::DRbUndumped

def initialize( observed )
observed.add_observer( self )
end

def update( *args )
puts “!!!”
p *args
end
end
DRb.start_service
notifier = DRbObject.new( nil, ‘druby://tao:4711’ )
d = Client.new( notifier )

notifier.change( rand( 10 ) )

Now, running both programs once works fine.

For Notifier:
[979] stk@tao ~/devel/util: ruby Notifier.rb
druby://tao:4711
Changing: 4

For Client:
[974] stk@tao ~/devel/util: ruby Client.rb
!!!
Sun Jan 04 00:32:53 CET 2004
6
Great! And thanks again for the help!

Unfortunately starting the client a second time it get an error I
(partially) don’t understand.

The Server output continues with:

Changing: 1

The Client output is this:
Sun Jan 04 00:40:11 CET 2004
4
[974] stk@tao ~/devel/util: ruby Client.rb
(druby://tao:4711) /usr/local/lib/ruby/1.8/drb/drb.rb:705:in open': druby://tao:33324 - #<Errno::ECONNREFUSED: Connection refused - connect(2)> (DRb::DRbConnError) from (druby://tao:4711) /usr/local/lib/ruby/1.8/drb/drb.rb:698:in each’
from (druby://tao:4711)
/usr/local/lib/ruby/1.8/drb/drb.rb:698:in open' from (druby://tao:4711) /usr/local/lib/ruby/1.8/drb/drb.rb:1084:in initialize’
from (druby://tao:4711)
/usr/local/lib/ruby/1.8/drb/drb.rb:1067:in new' from (druby://tao:4711) /usr/local/lib/ruby/1.8/drb/drb.rb:1067:in open’
from (druby://tao:4711)
/usr/local/lib/ruby/1.8/drb/drb.rb:1014:in method_missing' from (druby://tao:4711) /usr/local/lib/ruby/1.8/observer.rb:185:in notify_observers’
from (druby://tao:4711)
/usr/local/lib/ruby/1.8/observer.rb:184:in each' from (druby://tao:4711) /usr/local/lib/ruby/1.8/observer.rb:184:in notify_observers’
from (druby://tao:4711) Notifier.rb:11:in `change’
from Client.rb:19
[974] stk@tao ~/devel/util:

Now, why does it say >>> druby://tao:33324 <<< in the 1st line of th output?
And how can I stop this?

BTW, ‘ruby -v’ yields: ruby 1.8.1 (2003-12-25) [i686-linux].

Happy rubying!

Stephan

For Notifier:
[979] stk@tao ~/devel/util: ruby Notifier.rb
druby://tao:4711
Changing: 4

Now, why does it say >>> druby://tao:33324 <<< in the 1st line of th output?
And how can I stop this?

I take it you mean for the notifier?

Now the ‘compressed’ notifier looks like this…

require ‘drb’
require ‘drb/observer’

class Notifier
include Observable
include DRb::DRbUndumped

def change( i )
puts “Changing: #{‘%2d’ % i}”
changed( true )
notify_observers( Time.now, i )
end
end

DRb.start_service( ‘druby://tao:4711’, Notifier.new )
puts DRb.uri
^^^^
This is why

···

Stephan K?mper (Stephan.Kaemper@Schleswig-Holstein.de) wrote:

DRb.thread.join


Eric Hodel - drbrain@segment7.net - http://segment7.net
All messages signed with fingerprint:
FEC2 57F1 D465 EB15 5D6E 7C11 332A 551C 796C 9F04

Hi all, hi Eric,

thanks for your answer.

Eric Hodel - drbrain@segment7.net wrote this:

For Notifier:
[979] stk@tao ~/devel/util: ruby Notifier.rb
druby://tao:4711
Changing: 4
Now, why does it say >>> druby://tao:33324 <<< in the 1st line of
th output?
And how can I stop this?

I take it you mean for the notifier?

No, I really did mean what I wrote: It’s the client program that
complains (well, sort of) about not being able to connect.
I do understand that the connection is refused for the service
‘druby://tao:33324’. There’s just no partner running on that port.
However, I do not understand, why port 33324 is tried at all…

require ‘drb’
require ‘drb/observer’

class Notifier
include Observable
include DRb::DRbUndumped

def change( i )
puts “Changing: #{‘%2d’ % i}”
changed( true )
notify_observers( Time.now, i )
end
end

DRb.start_service( ‘druby://tao:4711’, Notifier.new )
puts DRb.uri
^^^^
This is why

Hmmm, do you really think it’s the line with the ‘puts’, that causes
the second connection to fail? As the problem remains after removing
the line you marked, the reason for the refused connection is
something else, I suspect – correct me, if I’m wrong.

DRb.thread.join

Cheers, & happay rubying
Stephan

···

Stephan K?mper (Stephan.Kaemper@Schleswig-Holstein.de) wrote: