I'm trying to implement this pattern on a "smart building" system design (using STL library). Various "sensors" placed in rooms, floors etc, dispatch signals that are handled by "controllers" (also placed in different rooms, floors etc.). The problem I'm facing is that the controller's subscription to an event isn't just event based, it is also location based.
For example, controller A can subscribe to a fire signal from room #1 in floor #4 and to a motion signal in floor #5. A floor-based subscription means that controller A will get an motion event about every room in the floor he's subscribed to (assuming the appropriate sensor is placed there). There's also a building-wide subscription for that matter.
The topology of the system is read from a configuration file at start up, so I don't want to map the whole building, just the relevant places that contain sensors and controllers.
What I've managed to think of :
Option 1: MonitoredArea class that contains the name of the area (Building1, Floor 2, Room 3) and a vector where the vector's index is an enumerated event type each member of the vector contains a list of controllers that are subscribed to this event. The class will also contain a pointer to a parent MonitoredArea, in the case it is a room in a floor, or a floor in a building.
A Sensor class will dispatch an Event to a center hub along with the sensor's name. The hub will run it through his sensor-name-to-location map, acquire the matching MonitoredArea and will alert all the controllers in the vector.
Cons:
Coupling of the location to the controller
Events are enumerated and are hard coded in the MonitoredArea class, adding future events is difficult.
Option 2:
Keeping all the subscriptions in the Controller class.
Cons:
Very inefficient. Every event will make the control center to iterate through all the controller and find out which are subscribed to this particular event.
Option 3:
Event based functionality. Event class (ie. FireEvent) will contain all the locations it can happen in (according to the sensor's setup) and for every location, a list of the controllers that are subscribed to it.
Cons:
A map of maps
Strong data duplication
No way to alert floor-based subscriptions about events in the various rooms.
As you can see, I'm not happy with any of the mentioned solutions. I'm sure I've reached the over-thinking stage and would be happy for a feedback or alternative suggestions as to how I approach this. Thanks.
There is design pattern (sort of speak) used a lot in game development called "Message Bus". And it is sometimes used to replace event based operations.
"A message bus is a connection between one or more senders and/or receivers. Think of it like a connection between computers in a bus topology: Every node can send a message by passing it to the bus, and all connected nodes will receive that message. If the node is processed and if a reply is sent is completely up to each receiver itself.
Having modules connected to a message bus gives us some advantages:
Every module is isolated, it does not need to know of any others.
Every module can react to any message that’s being sent to the bus; that means you get extra flexibility for free, without increasing dependencies at all.
It’s much easier to follow the YAGNI workflow: For example you’re going to add weapons. At first you implement the physics, then you add visuals in the renderer, and then playing sounds. All of those features can be implemented independently at any time, without interrupting each other.
You save yourself from thinking a lot about how to connect certain modules to each other. Sometimes it takes a huge amount of time, including drawing diagrams/dependency graphs."
Sources:
http://gameprogrammingpatterns.com/event-queue.html
http://www.optank.org/2013/04/02/game-development-design-3-message-bus/
Related
First, i understand that being spoon-fed answers will absolutely hurt me in the long run and that is not what i'm looking for. That being said, here is the main point of the assignment:
"We are going to model a simple island-hopping attack on a small corporate network. The
attacker will compromise a computer in the network and use that as the launching point for other
attacks. Our attack model is simplified so that each attack takes a set amount of time and
succeeds with some probability. Periodically, the attacker and each compromised machine will
attempt to compromise a random machine in the network. Attacks crossing the intrusion
detection system will have a certain percentage chance of being caught. The sysadmin will
react (with some delay) to fix machines with 100% certainty.
The topology of the network is a tree. At the root of the tree is the IDS, with all connected
components as children. The IDS is also the network gateway.
Two switches (not agents) are direct children on the IDS.
The remaining computers are split evenly as children between the two switches.
Every event from the attacker crosses the IDS. Only attacks from computers under one switch
to computers under the other switch can be detected by the IDS
The sysadmin is an agent in the simulation that is not attached to the network. It can only
receive simulation notification from the intrusion detection system."
There are 3 event types: attack, fix, and notify. I know that the events are to be stored in the queue, which is fine, but i'm not sure how to implement these events. Create a virtual class Event and a bunch of subclasses defining all the events? One class for all events? Who knows?
There are also 3 agents that respond to or produce events: the attacker, the computers, and the IDS. Again-- should i implement these all in separate classes or would it be sufficient to use one main class.
My program is to be given 3 inputs: number of computers, percent success of the attack, and percent detected across the IDS.
What i'm having real trouble with is the organization of the whole simulation, which makes it rather difficult to begin the design and implementation. I can't seem to wrap my head around the structure of the event, and my coding is rather rusty i'm afraid to admit. A nudge in the right direction would be greatly appreciated.
I have an actor system that at the moment accepts commands/messages. The state of these actors is persisted Akka.Persistance. We now want to build the query system for this actor system. Basically our problem is that we want to have a way to get an aggregate/list of all the states of these particular actors. While I'm not strictly subscribing to the CQRS pattern I think that it might be a neat way to go about it.
My initial thoughts was to have an actor for querying that holds as part of its state an aggregation of the states of the other actors that are doing the "data writes". And to do this this actor will subscribe to the actors its interested to and these actors would just send the query actor their states when they undergo some sort of state change. Is this the way to go about this? is there a better way to do this?
My recommendation for implementing this type of pattern is to use a combination of pub-sub and push-and-pull messaging for your actors here.
For each "aggregate," this actor should be able to subscribe to events from the individual child actors you want to query. Whenever a child's state changes, a message is pushed into all subscribed aggregates and each aggregate's state is updated automatically.
When a new aggegrate comes online and needs to retrieve state it missed (from before it existed) it should be able to pull the current state from each child and use that to build its current state, using incremental updates from children going forward to keep its aggregated view of the children's state consistent.
This is the pattern I use for this sort of work and it works well locally out of the box. Over the network, you may have to ensure deliverability guarantees and that's generally easy to do. You can read a bit more on how to do that there: https://petabridge.com/blog/akkadotnet-at-least-once-message-delivery/
Some of Akka.Persistence backends (i.e. those working with SQL) also implement something known as Akka.Persistence.Query. It allows you to subscribe to a stream of events that are produced, and use this as a source for Akka.Streams semantics.
If you're using SQL-journals you'll need Akka.Persistence.Query.Sql and Akka.Streams packages. From there you can create a live (that means continuously updated) source of events for a particular actor and use it for any operations you like i.e print them:
using (var system = ActorSystem.Create("system"))
using (var materializer = system.Materializer())
{
var queries = Sys.ReadJournalFor<SqlReadJournal>(SqlReadJournal.Identifier)
queries.EventsByPersistenceId("<persistence-id>", 0, long.MaxValue)
.Select(envelope => envelope.Event)
.RunForEach(e => Console.WriteLine(e), materializer);
}
I'm currently trying to write (as a part of "simple multiplayer game as an example of real time client-server application" assignment) multiplayer game server for simple fast-paced game for few players (less than 20 i think). I'm using TCP sockets for packets that require guaranteed delivery (ie.: chat messages, login and logout requests, ping packets, etc) and UDP for everything that does not necessarily need to be delivered since only the last packet that got through is important (ie.: user input, game world and objects updates, etc).
I should mention here, how my game world looks like. Every object server side has its id, role and owner members. Id is basically identifier for clients so, once I send them object updates they know which object to update on their side. Owner is information about object owner, ie.: player which controls the actor. I use it to remove orphaned objects once player loses connection / logs out. Most objects however has this value set to Server. And finally role determines whether object is important to clients. This can be set to ServerSide (for objects that do not need to be replicated to clients as they are only used in server side game state calculation), RelevantToOwner (this objects get replicated only to their owner, ie.: player private inventory does not need to be replicated to everyone), RelevantToList (object gets replicated to all players from list, ie.: i have list of players to whom the object is visible and i replicate only to them) and RelevantToAll (replicate to everyone).
When user sends login packet I check whether I have free slot and if yes, then I replicate world to him (send current world state - every object that does not have role set as ServerSide or RelevantToList - unless of course the client is on the list for that object).
Then after each iteration of server game state update loop I send exactly same thing - whole world state.
When users send logout packet I remove him from logged in clients, free slot, and remove all orphaned objects from game world (objects that had this user as owner).
Here are my questions:
Is this model suitable for real-time multiplayer game or am I doing it horribly wrong?
Is there a way to reduce amount of packets sent after the initial world replication (ie.: updating only objects which state has changed since last iteration. I've given it a thought and so far I've encountered one huge problem with this approach - if UDP packet from previous iteration is lost and state of the object haven't changed in subsequent iterations, the object will not be updated on the player side.)
How can i pack multiple object updates into one packet (I'm currently sending one object / packet which is inefficient and also probably horribly wrong.
Could someone point me to some working example (source would be nice) of simple Client/Server game so I can see how professionals do it? C++ or C would be nice but Java / C# / Python are fine too.
This depends a lot so much on what type of game you're talking about - example: Im doing roughly the same thing in a text based muck game.. My updates are simple, on arrival, send room details. On change, send messages to say people/object came/went. Done.
UDP is how most online games work just because they need to deal ith 100k+ connectios. UDP loss is often why players "warp" in game. If you're doing 20 people and you can guarentee that, then sticking with tcp will help.
do you need to send them the whole world? Is your world not made of zones/rooms. Normally you send the smaller area. It also depends on how much data on the objects within that you should send, for example. If a player has an inventory, no point sending that to all the other players unless they specifically ask for it - items worn (if a visual game then yes you need to or it draws them wrong)
Just because we have much faster connections these days doesnt mean we shouldnt take into consideration some people dont. You should try and send updates only and have the client maintain its own state, and then, when you change zones, and reload the area, you ensure sync.
To pack object changes in a packet, most likely Im guessing its location changes, eg co-ordinates, and availability, eg, person picks up item. Have an upate structure, item_id, update_type, update_values[], then you can send a chunk of updates.
Are you after text based or more mmorg type? text based I can say google tinymuck, or tinymush, tinymud, there are plenty, graphics ones? thats harder, you could lookup some of the old EQ code and WoW emulators maybe..
Observer pattern:
There are 2 variants of it.
Where Subjects informs all the observers as an when an event occurs
The observer can query the subject, if an event occured or not.
I am thinking of any real-world examples, which are applicable for option 2 ?
I have used option 1, in one of my projects where there is any particular event (on my socket), all the observers which are registered for that event, gets notified.
The second version isn't an observer at all. That's simply polling.
What the Design Patterns book actually described, and what you maybe meant, is this:
Whenever the subject changes, the changed values get pushed to the observer (as arguments to the 'notify' call).
Whenever the subject changes, the observer pulls the new state from the subject as needed (no arguments to the 'notify' call).
A use case for the second approach:
The subject is a set of address book records. Whenever the address book is updated, the observers should be notified. However, the amount of changed data could potentially be rather large and not each of the observers needs all the data. So instead of pushing all the data, you just notify all observers (possibly passing the 'this' pointer of the subject as an argument in case the observers should be able to listen to multiple subjects at once) and then provide the new state via getters - that way, each observer can fetch just the information it needs. Like the observer which updates the 'Number of addresses' field in your GUI - it's not interested in the actual names, just in the number of items.
i think not all the subject event insterested by the observers,so if use "push",some observers may not need to know the event,but use "pull",the observers know what they want to get.
Thinks about mobile email clients. You can have data pushed to your phone (push) or you can only get the emails when you check the mail (pull). The later being the case you are asking about. Usually these are options you can configure when setting up or editing the account.
Another example...
Triggered ajax web request. If you have a weather app on a webpage that only updates when the page is refreshed, or the event happens, this page/app is pulling the data from a server. On the other hand you can use services like Pusher App which can push the data to your page/app for real time updates.
Pulling data allows your Observer to stand alone but still get support from the Observable.
I have a situation where I have a single Emitter object and a set of Receivers. The receivers are of the same class, and actually represent a set of devices of the same type. I'm using the Qt framework.
The Emitter itself first gets a signal asking for information from one of the devices.
In the corresponding slot, the Emitter has to check to see which of the Receivers are 'ready', and then send its own signal to request data to one of the devices (whichever is ready first).
The Emitter receives signals very quickly, on the order of milliseconds. There are three ways I can think of safely requesting data from only one of the devices (the devices live in their own threads, so I need a thread-safe mechanism). The number of devices isn't static, and can change. The total number of devices is quite small (definitely under 5-6).
1) Connect to all the devices when they are added or removed. Emit the one request and have the devices objects themselves filter out whether the request is for them using some specific device tag. This method is nice because the request slot where the check occurs will execute in a dedicated thread's context, but wasteful as the number of devices go up.
2) Connect and disconnect from the object within the Emitter on the fly when it's necessary to send a request.
3) Use QMetaObject::invokeMethod() when its necessary to send a request.
Performance is important. Does anyone know which method is the 'best', or if there's a better one altogether?
Regards
Pris
Note: To clarify: Emitter gets a signal from the application, to get info by querying the device. Crazy ASCII art go:
(app)<---->(emitter)<------>(receivers)<--|-->physical devices
Based on the information you have provided I would still recommend a Reactor implementation. If you don't use ACE then you can implement your own. The basic architecture is as follows:
use select to wake up when signal or data is received from the App.
If there is a socket ready on the sending list then you just pick one and send it data
When data is sent the Receiver removes itself from the set of sockets/handlers that are available
When data is processed the Reciever re-registers itself to the list of available recipients.
The reason I suggested ACE is because it has one of the simplest to use implementations of the Reactor pattern.
I'm amusing here this is multi thread environment.
If you are restricted to Qt signal / slot system between then the answer for your specific questions:
1) is definitely not the way to go. On an emit from the Emitter a total number of events equal to the number of Receivers will be queued for the thread(s) event loops of the devices, then the same number of slot calls will occur once the thread(s) reach those event. Even if most of the lost just if(id!=m_id) return; on their first line, its a significant amount of things going on in the core of Qt. Place a breakpoint in one of your slots that is evoked by a Qt::QueuedConnection signal and validate this looking at the actual stack trace. Its usually at least 4 call deep from the xyEventLoop::processEvents(...), so "just returning" is definitely not "free" in terms of time.
2) Not sure how Qt's inner implementation actually is, but from what I know connecting and disconnecting most likely include inserting and removing the sender and receiver into some lists, which are most likely accessed with QMutex locking. - might also be "expensive" time-wise, and rapidly connecting and disconnecting is definitely not a best practice.
3) Probably the least "expensive time-wise" solution you can find that is still using Qt's singnal-slot system.
optionally) Take a look at QSignalMapper. It is designed exactly for what you planned to do in option 1).
There are more optimal solutions to communicate between your Emitter and Receivers, but as a best practice I'd first choose the option that is most easy to use and fast to implement, yet has a chance of being fast enough run-time (that is option 3). ). Then, when its done, see if it meets your performance requirements. If it does not, and only then, consider using shared memory with mutexes in a data provider - data consumer architecture (Emitter thread rapidly post request data in a circular list, while the Receiver thread(s) reads them whenever have time, then post results back a similar way, while the Emitter thread constantly polls for done results.)