DRb functions disappearing?

K

Kevin Brown

I will start by admitting I'm new to Ruby, but am generally a quick learner.
Anyway, I put together a simple DRb test program which works fine. I'm now
trying to do the real thing, where I need a graphical front end to
communicate with a backend on localhost for the moment, but eventually, on
another machine.

My problem is that the functions seem to disappear. If the code in my class
is like below:

DRb.start_service()
@connection = DRbObject.new(nil, 'druby://localhost:9000')
@connection.login

I get the following output:

(druby://localhost:9000) /usr/lib/ruby/1.8/drb/drb.rb:1478:in `login': wrong
number of arguments (0 for 1) (ArgumentError)
from ./dli-frontend.rb:33:in `initialize'
from ./dli-frontend.rb:62:in `new'
from ./dli-frontend.rb:62

Which is correct. login takes one argument. I then supply the argument with:

DRb.start_service()
@connection = DRbObject.new(nil, 'druby://localhost:9000')
user = User.new
@connection.login(user)

Here's the output:

(druby://localhost:9000) ./db/db.rb:999:in `login': undefined method `login'
for #<DRb::DRbUnknown:0xb72c2fec> (NoMethodError)
from (druby://localhost:9000) ./listener.rb:31:in `login'
from ./dli-frontend.rb:33:in `initialize'
from ./dli-frontend.rb:62:in `new'
from ./dli-frontend.rb:62

If there's more info I need to provide, please let me know... Otherwise, any
ideas as to what I'm doing wrong?
 
E

Eric Hodel

I will start by admitting I'm new to Ruby, but am generally a quick
learner.
Anyway, I put together a simple DRb test program which works fine.
I'm now
trying to do the real thing, where I need a graphical front end to
communicate with a backend on localhost for the moment, but
eventually, on
another machine.

My problem is that the functions seem to disappear. If the code in
my class
is like below:

DRb.start_service()
@connection = DRbObject.new(nil, 'druby://localhost:9000')
@connection.login

I get the following output:

(druby://localhost:9000) /usr/lib/ruby/1.8/drb/drb.rb:1478:in
`login': wrong
number of arguments (0 for 1) (ArgumentError)
from ./dli-frontend.rb:33:in `initialize'
from ./dli-frontend.rb:62:in `new'
from ./dli-frontend.rb:62

Which is correct. login takes one argument. I then supply the
argument with:

DRb.start_service()
@connection = DRbObject.new(nil, 'druby://localhost:9000')
user = User.new
@connection.login(user)

Here's the output:

(druby://localhost:9000) ./db/db.rb:999:in `login': undefined
method `login'
for #<DRb::DRbUnknown:0xb72c2fec> (NoMethodError)

^^^
Looks like you're missing a DRbUndumped somewhere.
from (druby://localhost:9000) ./listener.rb:31:in `login'
from ./dli-frontend.rb:33:in `initialize'
from ./dli-frontend.rb:62:in `new'
from ./dli-frontend.rb:62

If there's more info I need to provide, please let me know...
Otherwise, any
ideas as to what I'm doing wrong?

How about some code?
 
K

Kevin Brown

^^^
Looks like you're missing a DRbUndumped somewhere.

How about some code?

Your wish is my command.

Here's the backend code:
--START--
require 'db/db'
require 'listener'
require 'drb'

# Initialize Database Connection
db = DB.new

# Start Listener
listener = Listener.new(db)
listener.extend DRb::DRbUndumped
DRb.start_service('druby://localhost:9000', listener)

puts "DLI server is up and running...\n"

DRb.thread.join
--END--

DB is a database abstraction layer, listener maps calls to it, only allowing
access to login for now.

Here's listener, not like it matters much:
--START--
require 'db/db'
require 'thread'

class Listener

#---------------------------------------------------------------------------
# Method: initialize
# Purpose: Prepare listener to be able to direct behavior of backend
# Pre: Listener has none of the objects it needs to control the backend
# Post: Listener is prepped for use
#---------------------------------------------------------------------------
def initialize(db)
@db = db
@mutex = Mutex.new
end

#---------------------------------------------------------------------------
# Method: login
# Purpose: Allow user to login to the system
# Pre: User is not logged in
# Post: User is logged in and returned, or error is raised.
#---------------------------------------------------------------------------
def login(user)
@db.login(user)
end
end
--END--

And the client code is in a KDE app, so I won't bore you all with the pile
there:
--START--
require 'Korundum'
require 'drb'
require 'errors'
require 'login'

class Dli < KDE::MainWindow
attr_reader :connection

slots 'newUser()'

def initialize(name)
super(nil, name)

# Prepare messenger to get to backend.
DRb.start_service()
@connection = DRbObject.new(nil, 'druby://localhost:9000')
user = User.new
@connection.login(user)
--END--
The connection.login is the "disappearing" method... And that's all the code
that has to do with that. :)

Thanks for the quick reply!
 
E

Eric Hodel

Your wish is my command.

Here's the backend code:
--START--
require 'db/db'
require 'listener'
require 'drb'

# Initialize Database Connection
db = DB.new

# Start Listener
listener = Listener.new(db)
listener.extend DRb::DRbUndumped
DRb.start_service('druby://localhost:9000', listener)

puts "DLI server is up and running...\n"

DRb.thread.join
--END--

DB is a database abstraction layer, listener maps calls to it, only
allowing
access to login for now.

Here's listener, not like it matters much:

The listener isn't involved in the failure, right?
--START--
require 'db/db'
require 'thread'

class Listener

def initialize(db)
@db = db
@mutex = Mutex.new
end

def login(user)
@db.login(user)
end
end
--END--

And the client code is in a KDE app, so I won't bore you all with
the pile
there:
--START--
require 'Korundum'
require 'drb'
require 'errors'
require 'login'

I don't see require 'db/db' here, so you'll need to add 'include
DRbUndumped' to db/db if you don't want db/db to live here.
 
K

Kevin Brown

I don't see require 'db/db' here, so you'll need to add 'include
DRbUndumped' to db/db if you don't want db/db to live here.

If I don't want db/db to live here? It's a seperate process...? I'm totally
lost as to A) Why that class would exist here, and B) Why it existing here
would cause DRb to not be able to call one of my methods in the listener
class?
 
K

Kevin Brown

Server code now looks like:
require 'db/db'
require 'listener'
require 'drb'

# Initialize Database Connection
db = DB.new

# Start Listener
db.extend DRb::DRbUndumped
listener = Listener.new(db)
listener.extend DRb::DRbUndumped
DRb.start_service('druby://localhost:9000', listener)

puts "DLI server is up and running...\n"

DRb.thread.join

And it's still showing the same behavior...
 
E

Eric Hodel

Server code now looks like:
require 'db/db'
require 'listener'
require 'drb'

# Initialize Database Connection
db = DB.new

# Start Listener
db.extend DRb::DRbUndumped
listener = Listener.new(db)
listener.extend DRb::DRbUndumped
DRb.start_service('druby://localhost:9000', listener)

puts "DLI server is up and running...\n"

DRb.thread.join

And it's still showing the same behavior...

Looking again, maybe its User in the KDE process... Its hard to tell
when I can't run it :(
 
E

Eric Hodel

If I don't want db/db to live here? It's a seperate process...?

db/db may be a huge object that you wouldn't want sent across the
wire, or its a lot of code that doesn't need to be loaded.
I'm totally lost as to A) Why that class would exist here, and B)
Why it existing here would cause DRb to not be able to call one of
my methods in the listener
class?

A) DRb tries to marshal objects when communicating. If DRb can't
marshal the object, it sends a DRbObject proxy instead.

B) When DRb is trying to send marshaled objects back and forth, both
sides need the class definition or the object needs to be undumpable.
 
K

Kevin Brown

db/db may be a huge object that you wouldn't want sent across the
wire, or its a lot of code that doesn't need to be loaded.

Ok, that makes sense... I don't want it marshalled, just need proxy objects,
and that's why I've been using the undumped...
A) DRb tries to marshal objects when communicating. If DRb can't
marshal the object, it sends a DRbObject proxy instead.

Exactly what I want. :)
B) When DRb is trying to send marshaled objects back and forth, both
sides need the class definition or the object needs to be undumpable.

Ok, DB is a gigantic class, that depends on a large pile of subclasses. The
part that's getting me is that the DRb proxy object is obviously correctly
associated with the Listener class. The error comes from the call inside the
listener when it calls @db.login(user). The user I'm passing in was just to
reproduce the error, but if it did execute correctly, an error would be
raised from my code. I know the User is fine as far as the listener call is
concerned.

So, my confusion now lies in the fact that I really just want DRb to send the
message to the server, and back off while that happens. It still seems to
want to do it on the client side via marshalling, but I'm new enough to this
I could be on total crack. :)
 
E

Eric Hodel

Ok, that makes sense... I don't want it marshalled, just need
proxy objects,
and that's why I've been using the undumped...


Exactly what I want. :)


Ok, DB is a gigantic class, that depends on a large pile of
subclasses. The
part that's getting me is that the DRb proxy object is obviously
correctly
associated with the Listener class. The error comes from the call
inside the
listener when it calls @db.login(user). The user I'm passing in
was just to
reproduce the error, but if it did execute correctly, an error
would be
raised from my code. I know the User is fine as far as the
listener call is
concerned.

Its hard to say what exactly is wrong without being able to tinker
with it :( Did you see my other email about adding DRbUndumped to
the User class?

Even if you mark a class as Undumped, objects generated by the class
may be marshaled and returned across the wire.
So, my confusion now lies in the fact that I really just want DRb
to send the
message to the server, and back off while that happens. It still
seems to
want to do it on the client side via marshalling, but I'm new
enough to this
I could be on total crack. :)

If you could reduce your failure to something that is easily
distributable, I could help more.
 
K

Kevin Brown

Its hard to say what exactly is wrong without being able to tinker
with it :( Did you see my other email about adding DRbUndumped to
the User class?

Nope, but I'll give it a shot.
Even if you mark a class as Undumped, objects generated by the class
may be marshaled and returned across the wire.

Hmmm... Maybe I'm simply using the wrong technology? I really just need
messages sent, and exceptions tossed back if they happen. Would this be
better suited to TCP/IP directly by chance?
If you could reduce your failure to something that is easily
distributable, I could help more.

That's definitely not out of the question. I'll see if I can hack it down to
something reasonable that shows the behavior, and if so, I'll send it your
way.
 
E

Eric Hodel

Hmmm... Maybe I'm simply using the wrong technology? I really
just need
messages sent, and exceptions tossed back if they happen. Would
this be
better suited to TCP/IP directly by chance?

If you want messages and exceptions, you may end up implementing half
of DRb to get what you want, depending on what features you want to
support.

Your problem seems to be that something is marked as shared that
shouldn't be. Remember both sides of the connection attempt to
Marshal things. DRb is best described as server-server rather than
client-server.
 
K

Kevin Brown

If you want messages and exceptions, you may end up implementing half
of DRb to get what you want, depending on what features you want to
support.

Your problem seems to be that something is marked as shared that
shouldn't be. Remember both sides of the connection attempt to
Marshal things. DRb is best described as server-server rather than
client-server.

You totally win. I sat down to start dinking with it, marked User as
DRbUndumped, and life was good.

THANK YOU!!!
 

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

Similar Threads


Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top