home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / lang / cplus / 20106 < prev    next >
Encoding:
Internet Message Format  |  1993-01-29  |  6.1 KB

  1. Xref: sparky comp.lang.c++:20106 comp.std.c++:2149
  2. Path: sparky!uunet!spool.mu.edu!howland.reston.ans.net!paladin.american.edu!darwin.sura.net!mlb.semi.harris.com!travis.csd.harris.com!amber!bill
  3. From: bill@amber.csd.harris.com (Bill Leonard)
  4. Newsgroups: comp.lang.c++,comp.std.c++
  5. Subject: Re: Callbacks -- suggested approaches??
  6. Date: 28 Jan 1993 22:41:49 GMT
  7. Organization: Harris CSD, Ft. Lauderdale, FL
  8. Lines: 108
  9. Distribution: ssd
  10. Message-ID: <1k9nfdINN56n@travis.csd.harris.com>
  11. References: <DAVIDM.93Jan25171343@consilium.com> <rmartin.728090477@stripe>
  12. NNTP-Posting-Host: amber.ssd.csd.harris.com
  13.  
  14. In article <rmartin.728090477@stripe>, rmartin@stripe.Rational.COM (Bob Martin) writes:
  15. > Passing messages between processes is always a challenge, especially
  16. > when what you really want to do is pass messages between two objects
  17. > which happen to live in different processes.  It would be very nice if
  18. > the sending and receiving objects did not know that the message was
  19. > crossing a process boundary.  Below is described a technique for
  20. > achieving this.
  21. > Unfortunately, theB lives in another process.  No problem.  Create an
  22. > abstract class called AbstractB.  It contains a set of pure virtual
  23. > functions defining all the messages that B can receive.  B will
  24. > inherit from AbstractB.  So will another class called BSurrogate.
  25. > BSurrogate knows which process the real B object lives in and knows
  26. > how to convert the message into a packet and ship it to that process.
  27. > The packet will contain all the arguments to X, an identifier denoting
  28. > that it represents an X message and the identifier of the B object to
  29. > which the message should be sent.
  30. > When the process receives the it looks up the name of the object in a
  31. > dictionary.  The dictionary associates the name with a derivative of
  32. > the class Reciever.  BReceiver is derived from Receiver, and knows how
  33. > to unpack the X packet.  It also knows where the B object is (Probably
  34. > it contains a pointer to it), so it unpacks all the arguments and then
  35. > sends the message to its B object.  
  36.  
  37. We have implemented a scheme very much like this in a project here, with
  38. some minor differences.  In so doing we have learned some lessons that
  39. I will pass on for what they're worth.  First, a brief description of
  40. our scheme:
  41.  
  42. For each class of object that needs to implement inter-process
  43. communication, we define 3 classes: There's the AbstractB as Bob says
  44. above, there's the BSurrogate derived from AbstractB, and there's also the
  45. BReal derived from AbstractB.  AbstractB just defines the interface to the
  46. B class of objects.  BSurrogate implements the interface by passing
  47. messages to another process.  BReal is the actual implementation of the
  48. functionality of B.
  49.  
  50. We also define a class called Router (similar to Bob's Receiver class).
  51. For each class B, there is a BRouter class, derived from Router, that
  52. receives the messages that BSurrogate sent and calls the appropriate
  53. function using a pointer to a BReal object.
  54.  
  55. By the way, we don't "look up the object in a dictionary".  We just pass
  56. the address of the BRouter object as part of the message; the generic
  57. message handler casts that value to a Router * and calls a virtual function
  58. using the resulting pointer.  (More on this below...)
  59.  
  60. Now, the lessons learned:
  61.  
  62.   1. Adding a function to the interface to B is a real pain!  You must add
  63.      the function signature in 3 places: AbstractB, BSurrogate, and BReal.
  64.      You generally also have to invent a new type of message, which entails
  65.      adding code to BRouter to know how to interpret that new message.
  66.  
  67.   2. Getting these objects created is often non-trivial.  Someone has to
  68.      create the BReal object in the process where he is to reside.  That
  69.      someone must typically also create the BRouter object, who needs to
  70.      keep a pointer to the BReal object around so he can call member
  71.      functions of it.  Then the BSurrogate object must be created in the
  72.      other process, and he needs to know some ID for the BRouter object so
  73.      that messages he sends get to the right place.
  74.  
  75.      We've had a few cases where the BSurrogate and BReal objects each
  76.      needed to talk to the other.  That further complicates the creation,
  77.      usually entailing having one of the objects send a message to the
  78.      other one telling him the address he should use if he wants to
  79.      initiate messages in the other direction.
  80.  
  81.   3. Destroying these objects is likewise tricky.
  82.  
  83.   4. If, for some reason, you need to make copies of a B object, then that
  84.      entails having BSurrogate implement a copy constructor that can send a
  85.      message over to BReal telling him to make a copy of himself and his
  86.      BRouter.
  87.  
  88.   5. If I had to do this over, I would make the BReal object use multiple
  89.      inheritance, deriving it from both the AbstractB class and the Router
  90.      class.  That way, the BReal object can be its *own* Router, thus
  91.      eliminating the need to create an extra object and coordinating its
  92.      creation and destruction.
  93.  
  94.   6. If you ever screw up a message and pass the wrong Router pointer, you
  95.      will get very bizarre and hard-to-track-down bugs.  This method has
  96.      the advantage of being fast, but we still talk about adding some kind
  97.      of dictionary so that we can at least verify that the Router pointer
  98.      we have is valid.
  99.  
  100. We made a small attempt at automating the creation of the BSurrogate and
  101. BRouter classes, with no success, but that doesn't mean it couldn't be
  102. done.  If I had to do this for a very large number of classes and
  103. functions, I'd probably develop a very-high-level language of some kind to
  104. describe the interface, so that I could automate at least parts of this.
  105.  
  106. Well, hope this helps somebody...
  107.  
  108. -- 
  109. Bill Leonard
  110. Harris Computer Systems Division
  111. 2101 W. Cypress Creek Road
  112. Fort Lauderdale, FL  33309
  113. bill@ssd.csd.harris.com
  114.  
  115. These opinions and statements are my own and do not reflect the opinions or
  116. positions of Harris Corporation.
  117. ---------------------------------------------------------------------------
  118. Prism: A place for light waves that commit minor refractions.
  119. ---------------------------------------------------------------------------
  120.