Actor Framework Discussions

cancel
Showing results for 
Search instead for 
Did you mean: 

Suggestion: Get Rid of the "Actor-to-Caller" Queue

Daklu wrote:

The observer pattern is based on events.  A subject publishes an event and all the observers choose to react or not react to it.  There are no commands because a command requires specific knowledge of the observer's api, which the subject doesn't have.  The observer pattern (in my experience) is entirely reactive, not proactive.  No actor tells another actor what to do.  If your subjects are sending commands to observers you aren't following the observer pattern.

I'm sorry, are there standard implications of "Observer Pattern" that I'm not aware of?   I have no formal CS education so I may be confusing terminology.  I'm just using a definition similar to Wikipedia's: "The observer pattern (a subset of the publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems."   I don't take this to be excluding anything, and no such exclusion is mentioned. 

Here is an example "Actor" that I posted on LAVA.  It runs a Ocean Optics USB2000 mini-spectrometer:

USB2000 Tester.png

At left are a list of command messages that it accepts, and state and event information that it publishes.  The User Interface actors are passed the USB2000 actor in the "Connect to Process" message, and the UIs send commands to the USB2000.

Gotta go, the two-year old is requiring attention...

0 Kudos
Message 21 of 24
(1,408 Views)

...Ok, she's in bed

Daklu wrote:

I disagree.  Growing up I used to sometimes wonder what the girl I would eventually marry was doing at that moment.  I knew there was "one person" who was out there, but I didn't know anything about that person other than she was female.  I wouldn't consider that specific knowledge.

Heterosexual, monogamy, marriage.   All specifications.  Though most common, not the only "design patterns" in use out there.  Limited knowledge, but still specific knowledge.

Furthermore, direct connections between two actors require they have compatible interfaces.  For an actor to be easily reusable it has to define its own inputs and outputs, not define them for interacting with a specific actor.  If you directly connect all your actors you have to make sure each actor's interface is compatible with all the other actor's interfaces.  That's fairly manageable if all the actors are application specific, but much, much, more difficult if you have a reusable actor library.

What do you do when you want to connect two actors with incompatible interfaces?  You're going to have to write application-specific glue code to do the api translation--often an adapter or a mediator.  Why give a reusable actor the ability to send messages directly to an arbitrary number of receivers when the messages are going to have to go through a custom translation layer anyway?

Well, to take my USB2000 actor as an example, which has useful reuse features like self calibration of Dark Current and ADC Readout level.  If I used it in a new program, the things it would be talking to would likely be application specific.  I would think it would be rare to connect a reuse component directly to a reuse component, except if the connection is very limited, or it's something like a Logger which accepts all messages.  Even if I did need to make a custom translation layer in some cases, why does that make me want to do the work of a custom publisher for all cases?

I've also been trying the keep my messages mostly standardized and based on simple datatypes in Variant-type messages.  This will maximize reuse such as when I have a module that publishes a "CurrentTemperature" message, and another that needs to get a "RoomTemp" message.   If they are both numerics (with units) in Variant messages, then I can easily connect the two (as the different labels are easily handled by my framework without a custom translator, as shown in this example where a "TimeString" message is relabeled "CurrentTime").

0 Kudos
Message 22 of 24
(1,408 Views)

drjdpowell wrote:
"The observer pattern (a subset of the publish/subscribe pattern) is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods. It is mainly used to implement distributed event handling systems."   I don't take this to be excluding anything, and no such exclusion is mentioned.

IMO the exclusion is implied by the nature of event handling systems.  Event messages describe things that happened in the past.  ButtonPressed, FileSaved, etc.  Command messages are instructions to do something in the future.  StartTest, SaveFile, etc.  The future might mean "as soon as you read this message," but the point is the action described by the command message hasn't occurred when the message is sent.  Maybe it sounds insignificant--I don't think so.  It actually has a large influence on which actor is responsible for deciding what to do as a result of the event, and properly dividing responsibilities among actors is a key part of software design.

GOF defines the intent of the Observer Pattern as, "Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically."  The subject is notifying the observers of the event that its state has changed--it's not telling them to do anything.  It's up to each observer to decide what to do with that information.

As seems to be the case with all computer science terminology, there's a lot of fuzziness around the edges and no clear "right" answer.  I fall back to the pattern's intent to define its key characteristics.  For the observer pattern those characteristics include dynamic binding n observers to a subject, subjects sending event-based messages, and automatic update notifications.  Maybe I'm reading more into it than most people.  It wouldn't be the first time and it probably won't be the last.

drjdpowell wrote:

I would think it would be rare to connect a reuse component directly to a reuse component...

Well yeah, because it's hard to write independent reusable actors that can connect directly to another arbitrary reusable actor.  For any direct communication between arbitrary actors at least one of them has to have specific knowledge about the other's api.  Better decoupling is achieved if only one of them has specific knowledge of the other's api.  Reusable components can't have specific knowledge about the other component's api. 

That's not to say it's necessarily rare to want reusable components to communicate with each other.  It all depends on how much functionality you're trying to reuse between applications.

0 Kudos
Message 23 of 24
(1,408 Views)

IMO the exclusion is implied by the nature of event handling systems.  Event messages describe things that happened in the past.  ButtonPressed, FileSaved, etc.  Command messages are instructions to do something in the future.  StartTest, SaveFile, etc.  The future might mean "as soon as you read this message," but the point is the action described by the command message hasn't occurred when the message is sent.  Maybe it sounds insignificant--I don't think so. ...

Sorry, I may not be being clear.   I use the Observer Register to handle my events.  I don't use it to send commands.  I HAVE commands, but these are sent explicitly, not published to unknown observers.  The "UI Test" actors in my example have the USB2000 actor passed to them, and they call "Send" on the USB2000 object itself in order to send it commands.  The UI actors receive event information from the USB2000 by registering as an observer of the USB2000 (internally, USB2000 calls "Notify Observers" on the Observer Register). 

The USB2000 is a reusable component and is not dependant on knowing anything about "UI Test".  In fact, it doesn't even have the ability to call "Send" on the UI Test actors, since it is never passed those objects.

"UI Test" is written specifically for the USB2000 and has full knowledge of all its commands and observable events/state.  It's not in any way reusable.  It has an Observer Registry, mostly used to publish any errors that occur, but USB2000 is not registered for any events from UI Test.

So I am using the "Observer Pattern" and sending commands, but I am not using the Observer Pattern to send commands.  And in general, commands go one way and events go the other, as shown by the arrows in the example diagram.

-- James

Send.png  Notify.png

"Send" to a specific actor VERSUS "Notify" registered observers (images taken from the USB2000 actor, which sends commands to the USB2000sub actor, and publishes events such as a new spectrum).

0 Kudos
Message 24 of 24
(1,408 Views)