> I recall that my original one had the objects > subscribe to specific services and then the routing object would only send > messages to objects looking for them.
Yes, that makes sense. What I showed yesterday does much the same. You want to avoid excessive broadcasting when the recipient is going to throw away the message as of no interest. > > But in this case it sends the message to any object that subscribes and if > the object is interested it dos whatever it needs to do. If not it ignores it. > So I think I’ll start with your approach this time and see how that works > first. I think it will be more than enough. If I catch what you're thinking about correctly, you sound inclined to make the message broker smarter. That's a solid plan, if the extra complexity can pay for itself. I didn't talk about this aspect of the design or even drop in the relevant slides (they make no sense out of context.) Backing up, the MessageHub in my example does a few things: -- Hold service definitions and subscription data. -- Distribute messages. So, if a service publishes 100 messages, each subscriber gets a copy of each of those 100 messages. This is fine in a 4D app like the one I showed. More than fine, actually. The underlying CALL FORM/CALL WORKER implementation seems to perform *really* well. It's very, very fast. You can stack up ridiculous numbers and messages and 4D can then chew through them quite quickly. I mention this as someone (I think it was Tim) said "Hey, what about speed?" So there it is: Speed is fantastic, in my experience. Anyway, we've got 100 messages going to a 100 subscribers, so 10,000 messages. If you were working with a distributed/network message queue, it would (or absolutely should) add some more smarts into the message hub/broker/center. The main tasks remain the same: -- Hold service definitions and subscription data. -- Distribute messages. ..but "service and subscription data" needs to be augmented. When a subscriber expresses interest in a service, you need a filter syntax. Say you have a service that sends out updates every hour, but you only want them every other hour. You might have a filter syntax that lets you say: Send message if hour is divisible by two. That way, you only get half as many messages along that subscription line. Instead of distributing copies of the message to every subscriber and having them decide "Nah, nil interest, dump" - you move some of that logic up into the broker. To make this work and keep the tidiness of the design...and to make sure that "the thing knows about itself", you don't want special-case code up in the broker. Instead, you want a generalized expression testing language so that subscribers can inject the filter rules and the broker can interpret the rules *abstractly* without understanding the particulars of the service, message, or subscriber. This last point is key. If you violate that rule, then you're messing up the clean "separation of concerns" that divides up the publisher-broker-subscriber into the most loosely coupled, but effectively connected arrangement. It's a trap! Don't do it. Yeah, that's more work. In a busy network context? It makes sense - but those systems are dealing, sometimes, with genuinely overwhelming message flows. Millions of messages. Saving 1% of a million is a lot - and you could save a lot more. in the case of a one-machine 4D system? I didn't think it would be wort the trouble. Tip: You can get much the same result with the simpler broker design by adding more 'services'. What I called 'services' is what is often called a 'channel'. So, you could make a channel that is itself less chatty and more specific. You could have multiple channels so that people dial into more exactly what they want. This is less efficient than putting filter rules in the broker because the publisher has to send multiple messages to the message broker, but it allows you to eliminate the excess broadcasting out of the broker. It's not as strong a design as the smarter broker, but it's easier, less complex and probably more than enough for any 4D-local application. Picking up on another question I got off-line: "You didn't really talk about pre-emptive [thread-safe] coding at all." Correctish. I said the main thing: CALL FORM / CALL WORKER are only peripherally connected to multi-core programming from *our* point of view. From 4D's point of view: -- It seems to be why they decided to add these features. -- These features help solve some problems in pre-emptive threads for which there was no existing, sensible option. So, it's how they got there. So what? That's a historical note and has nothing to do with using the commands...unless you are using them for those very specific reasons. In those cases, yeah, the interactions and rules for pre-emptive processing matter. Laurent E. did a decent Summit presentation on this subject that I'd recommend watching, if you're interested. Just note that the naive/idealized claims about the benefits of parallelization are rarely achievable in the real world. One reason the examples are always running nonsense calculations with no output other than screen redraws is that it is *hard* to come up with a compelling example. (Off-loading logging to disk files is my go to example, but there's a bit of a crashing bug there potentially, so...) There are compute tasks that *can* be parallelized almost ideally. Chances are they're running on your GPU, not CPU, already. You can get some great results from mutli-core programming, but not task/cores level improvement. Check the last slides in the set I sent to Brent for some diagrams and references on this. ********************************************************************** 4D Internet Users Group (4D iNUG) FAQ: http://lists.4d.com/faqnug.html Archive: http://lists.4d.com/archives.html Options: http://lists.4d.com/mailman/options/4d_tech Unsub: mailto:[email protected] **********************************************************************

