Loading ...
Sorry, an error occurred while loading the content.

393Re: [soaplite] Object variables on server, methods on client

Expand Messages
  • Douglas Bonar
    May 21, 2001
    • 0 Attachment
      Paul Kulchenko wrote:
      >
      > Hi, Douglas!
      >
      > While idea is right and valid, it may not work as planned for SOAP
      > implementation. Here is why. First, I don't have a proper way to
      > serialize reference to scalar (I'm using subelements right now), so
      > it'll be deserialized as hash. I'm working on finding the right way,
      > but it seems like other languages don't have direct analogies and
      > other XML serializers in Perl don't do SCALAR refs.

      Oops. I didn't know that. So, instead of a scalar
      ref you'ld need to actually bless and pass back a hash ref
      with just one key/value pair { 'PackageId' => $addr }. Then the
      method calls would have to be changed slightly as well. That's
      not as efficient, but not much of a change. Certainly passing
      back the one key/value pair is much better than passing back
      a very large hash/object.


      > Second problem is
      > that object will be destroyed on server side right after
      > serialization, so when it'll come back from client side proper
      > element from %Data won't be there anymore. That's why you need to
      > manage it based on different approach. The same problem as with any
      > other session management for stateless protocol. I would like to
      > build o-b-r based on Apache::Session, so you'll be able to get access
      > and manage sessions based on way you like (thru the different
      > interfaces).
      >

      I guess I was looking at that as a separate problem. Working
      with the handle (scalar or slim hash) rather than the full body (actual
      data hash) is a way to avoid passing large amounts of data in each
      message. Yes, it requires you to think of object lifetimes and session
      management. As you say, if you don't hold onto a local (server-side)
      reference to the object you're passing back you'll loose it right after
      sending it off. The simplest fix is not using the DESTROY method
      (so it isn't cleaned automatically) and putting a release method into
      your interface.

      I like the 2 layered idea in standard Perl modules, but
      I'm not sure about it for SOAP. If I pass you back an object that
      is really just a key to identify an object living on the server,
      all your interactions with that object are over the wire. As long
      as the interface is suitably large grained, that's not so bad.
      But certainly you wouldn't want to be acting with an object like
      we're often accustomed to (accessor/mutator methods, lots of method
      calls). And, if the interface really is large grained, maybe
      you shouldn't think of it as an object you keep the identity
      of, but more like a singleton that you tell to do things occasionally.

      At the same time, by having the client process hold onto
      the identify of an object on the server, you're building in the
      a fair amount of complexity. The server (probably) has to try to
      keep track of whether you're still around. There probably has
      to be logic to account for remaking the object if the server thought
      you went away, but it was wrong, or if the original server goes down
      and the client wants to talk to a backup.

      Just my thoughts. Though I really like the transparency
      that SOAP::Lite gives, I'm wary of trying to build on that to
      change from function calls to distributed objects.

      Doug

      > Best wishes, Paul.
      >
      > --- Douglas Bonar <Doug.Bonar@...> wrote:
      > > Paul Kulchenko wrote:
      > > >
      > > > Hi, Nicolas!
      > > >
      > > > Store it as a class data on server side:
      > > >
      > > > package My;
      > > >
      > > > my %huge_hash = (
      > > > a => 1,
      > > > );
      > > >
      > > > sub new {
      > > > my $proto = shift;
      > > > my $class = ref($proto) || $proto;
      > > > bless {} => $class;
      > > > }
      > > >
      > > > sub access_hash {
      > > > #... do something with %huge_hash
      > > > }
      > > >
      > > > And do NOT include reference to this hash in object (blessed
      > > ref).
      > > > This example will work if you have the same hash for all objects.
      > > >
      > > > If you hash is different for different objects, but you don't
      > > want to
      > > > transfer them anyway, then take a look into object-by-reference.
      > >
      > > In some sense the case of a different hash for each object
      > > isn't that much different from the one big hash. It is a nice
      > > model to use for OO Perl tasks. You might call this a
      > > 'handle/body'
      > > or 'double reference' technique.
      > >
      > > The following is the (rough) idea typed in from memory.
      > > The object you are passing back to the user is just a reference
      > > to a scalar. The value of that scalar is the pointer to the
      > > actual data location (it only matters that it is a unique string
      > > value associated with the real data hash), and at the same time
      > > the key for the internal (private) %Data hash. Then rather than
      > > the standard '1st argument is a hash reference' template in your
      > > methods, you add the extra line that the '1st argument is the key
      > > to retrieve the hash reference'.
      > >
      > > The 2 subtleties seem to be:
      > > * It is built on a closure which some people are scared of. That
      > > just means you need to define all of your methods inside
      > > the scope including %Data.
      > > * There needs to be a destructor in the package. When the scalar
      > > object goes out of scope, we need to clean out the private
      > > %Data hash. The internal %data hash created in the constructor
      > > would otherwise always hang around because the %Data hash has
      > > a reference to it.
      > >
      > >
      > > Blame me for the faults in the presentation or details.
      > > The good idea came to me from Damian Conway's excellent OOPerl
      > > book.
      > >
      > > Doug
      > >
      > >
      > >
      > > my Package;
      > > { my %Data;
      > >
      > > sub new {
      > > my $class = shift;
      > > my %data = @_; # assuming an array for simplicity
      > > my $addr = ref \%data;
      > > $Data{$addr} = \%data;
      > > return bless \$addr, ref $class || $class;
      > > }
      > >
      > > sub method {
      > > my ($self, @args) = @_;
      > > $self = $Data{$$self};
      > > # do something with the data, working with $self just as usual
      > > }
      > >
      > > sub DESTROY {
      > > delete $Data{${$_[0]}};
      > > }
      > >
      > > }
      > >
      > > To unsubscribe from this group, send an email to:
      > > soaplite-unsubscribe@yahoogroups.com
      > >
      > >
      > >
      > > Your use of Yahoo! Groups is subject to
      > > http://docs.yahoo.com/info/terms/
      > >
      > >
      >
      > __________________________________________________
      > Do You Yahoo!?
      > Yahoo! Auctions - buy the things you want at great prices
      > http://auctions.yahoo.com/
      >
      > To unsubscribe from this group, send an email to:
      > soaplite-unsubscribe@yahoogroups.com
      >
      >
      >
      > Your use of Yahoo! Groups is subject to http://docs.yahoo.com/info/terms/
    • Show all 6 messages in this topic