Efficiently pass notifications between decoupled design layers - c++

I am upgrading a design where data was lightly coupled with the UI:
class Object {
UI * ui;
};
class UI {
Object * object;
};
It was fairly straightforward to push update notifications to the ui through the UI pointer, but new requirements for data to be entirely separated from UI and also for different objects to have multiple different UI representations, so a single UI pointer no longer does it nor is allowed to be part of the data layer whatsoever.
It is not possible to use something like QObject and signals due to its overhead because of the high object count (in the range of hundreds of millions) and QObject is several times larger than the biggest object in the hierarchy. For the UI part it doesn't matter that much, because only a portion of the objects are visible at a time.
I implemented a UI registry, which uses a multihash to store all UIs using the Object * as a key in order to be able to get the UI(s) for a given object and send notifications, but the lookup and the registration and deregistration of UIs presents a significant overhead given the high object count.
So I was wondering if there is some design pattern to send notifications between decoupled layers with less overhead?
A clarification: most changes are done on the UI side, the UI elements keep a pointer to the related object, so that's not an issue. But some changes made to some objects from the UI side results in changes which occur in related objects in the data layer which can't be predicted in order to request update of the affected object's UIs. In fact a single change on the UI made to one object can result in a cascade of changes to other objects, so I need to be able to notify their eventual UI representations to update to reflect those changes.

One generic mechanism for decoupled communication is the publish-subscribe pattern. In this situation, the updated objects would post a notification to a message queue, and then the message queue is responsible for informing the UI components who have registered with the queue an interest in accepting that particular class of notification.
This is similar, in principle, to the UI registry that you have already tried. The main difference is that UI components to update are identified not purely by their referenced Objects, but rather by the notification type.
This allows a trade off between specificity and state keeping: if the model is set up such that every UI component associated with an Object obj gets notified by every update of obj, then it's equivalent to the UI registry. On the other hand, the model could be arranged such that some UI components are notified whenever a certain sub-category of Object posts an update, and then each component can check for itself if it needs to modify its state based on the content of the notification. Carried to the extreme, every UI object could be notified by any message posted by any Object, which would be equivalent to a global 'update-UI-state' approach.
The publish-subscribe model encompasses both these extremes, but also the range in between, where you may be able to find a suitable compromise.

I managed to come up with a immensely more efficient solution.
Instead of tracking all UIs using a "UI registry" I created a Proxy object and replaced the UI registry with a Proxy registry.
The Proxy object is created for each object that has any visual representation. It itself extends QObject and implements an interface to access the properties of the underlying Object, wrapping them in Qt style properties.
Then the Proxy object is used as a property for each UI to read and write the underlying Object properties, so it works "automatically" for every UI that might be referencing the particular proxy.
Which means there is no need to track every particular UI for every Object, instead the lifetime of the Proxy is managed simply by counting the number of UIs which reference it.
I also managed to eliminate all the look-ups which would not yield a result by adding a single bit hasProxy flag (had a few free bits left from the other flags) which is toggled for every object when a proxy is created or destroyed. This way in the actual Object's members I can quickly check if the object has a proxy without a look-up in the registry, if not use the "blind" data routines, if so look-up the proxy and manipulate the object through it. This limits registry look-ups to only the few which will actually get a result and eliminates a tremendous amount of those which would be pretty much in vain, just to realize the object has no visual representation at all.
In short, to summarize the improvements over the previous design:
the registry is now much smaller, from having to store a pointer for the object itself and a vector of all associated UIs I am now down to 8 bytes for the Proxy - the pointer to the object and a counter for any number of associated UIs
notifications are automated, only the proxy needs to be notified, it automatically notifies all UIs which reference it
the functionality previously bestowed to the UIs is now moved to the proxy and shared between all UIs, so the UIs themselves are lighter and easier to implement, in fact I've gone from having to specialize a unique QQuickItem for each object type to being able to use a generic QML Item without having to implement and compile any native classes for the UI
stuff I previously had to manage manually, both the actual notifications and the objects, responsible for them are now managed automatically
the overhead in both memory usage and CPU cycles has been reduced tremendously. The previous solution sacrificed CPU time for less memory usage relative to the original design, but the new design eliminates most of the CPU overhead and decreases memory usage further, plus makes the implementation much easier and faster.
It's like having a cake and eating it too :)

Related

Many instances vs. many std::shared_ptr

I just want to know if it makes a performance-difference while copying objects in C++ if I use many instances of a class or use std::shared_ptr.
Background: I have some structures which are delivered through a signals&slot mechanism (Qt). (I know that instances are copied while sending a signal) These delivering can occur many times so it has to be fast with low memory usage.
edit (add some details):
I write an embedded application (yeah, Qt is not the fastest for embedded backend I know) which can have a dynamic number of "modules". Each module has its own functionality. Every module has a signal and a slot. Which module receive emitted signals is freely configurable. So it could be that many signals are emitted in a very small time. In this case the signals has to be delivered as fast as possible. The delivered structure has some module-specific data and the data which has to be delivered to the other modules. I cannot say how large the delivered data will be because on the future there will be many more modules which maybe delivers much data.
BTW: I abuse std::shared_ptrin this case. I do not use I for really sharing the ownership. Qt just treat references and instances the same way in signals&slots, it copies the object. So to have the benefits of both, easy memory management of instance and lower memory usage of reference, I thought of using a std::shared_ptr.
Qt just treat references and instances the same way in signals&slots, it copies the object.
No, it only copies in specific circumstances. See this answer for details. TL;DR: It only copies if it needs to deliver the call over a queued connection, and then only if there is a receiver attached to a given signal. With direct connections (or default automatic connections within the same thread), if both the signal and the slot pass the argument by reference, then no copies will be made.
I abuse std::shared_ptr in this case.
It's not abuse. You're passing what amount to a shared data structure, held by a shared_ptr. It makes perfect sense.
The real question is: if your structures are expensive to copy, why won't you use explicit sharing via QSharedData and QExplicitlySharedDataPointer? And why doesn't your question include measurement results to substantiate your concern? Come on, such things are trivial to measure. You've got Qt to help you out - use it.

How should I best lock and refresh JPA entities?

I am relatively new to JPA and have become very confused about how to best optimistically lock and refresh entities. I would like a set of general purpose methods to handle this consistently in my project.
I may be calling the lock / refresh methods from within a method that does not know the state of the entity, it may have been passed a detatched or new / not saved entity object as well as one previously read from the database. For simplicity I would like my utility methods to handle all eventualities. Semantically the methods I am trying to implement are:
MyEntity refreshAndLock(MyEntity e)
Re-reads the entity from the database and locks it optimistically, or do nothing for entities yet to be saved to the database. Detached entities would also be re-read and locked and a managed version returned.
MyEntity refresh(MyEntity e)
Just re-read the entity, or do nothing for entities yet to be saved to the database. Detached entities would also be re-read.
MyEntity lockAndNotRefresh(MyEntity e)
Lock the version of the entity in memory (may already be out of date)
Any tips or links gratefully accepted. I haven't managed to find clear guidance on this which I'm surprised at since it seems like a common requirement.
1st, my main recommendation is: Don't try to implement your own generic data access layer. You have the EntityManager at your hands doing all the stuff for you. Keep your code simple and don't overengeneer. With a generic layer you are very likely introduce new problems and lower maintainability.
2nd, you have to ask yourself, what will be the typical use case of your application in order to decide about locking. Locking always brings the problem of bottlenecks and possible dead locks. So if your application reads much more than it writes or is likely not to access the same entity at once, you're better off with optimistic locking and then treat exceptions. JPA provides you with versioning, so you always know if some other thread changed your object. If you really need pessimistic locking, then go ahead and set it for those cases.

Implementing task-local variables for Concurrency Runtime

I'm improving an application (Win64, C++) by making it more asynchronous. I'm using the Concurrency Runtime and it's worked great for me so far.
The application basically executes a number of 'jobs' transforming data. To track what each job does, certain subsystems are instrumented with code to track certain operations that the job performs. Previously this would use a single global variable representing the currently executing job to be able to register tracking information without having to pass context information all the way down the calling chain. Each job may also turn use the ConcRT to parallelize the job itself. This all works quite well.
Now though, I am refactoring the application so that we can execute the top-level jobs in parallel. Each job is executed as a ConcRT task, and this works well for all jobs except those which need tracking.
What I basically need is a way to associate some context information with a Task, and have that flow to any other tasks spawned by that task. Basically, I need "Task Local" variables.
With ConcRT we can't simply use thread locals to store the context information, since the job may spawn other jobs using ConcRT and these will execute on any number of threads.
My current approach involves creating a number of Scheduler instances at startup, and spawning each job in a scheduler dedicated to that job. I can then use the Concurrency::CurrentScheduler::Id() function to retrieve an integer ID which I can use as a key to figure out the context. This works but single-stepping through the Concurrency::CurrentScheduler::Id() in assembly makes me wince somewhat since it performs multiple virtual function calls and safety checks which adds quite a lot of overhead, which is a bit of a problem since this lookup needs to be done at an extremely high rate in some cases.
So - is there some better way to accomplish this? I would have loved to have a first-class TaskLocal/userdata mechanism which allowed me to associate a single context pointer with the current Scheduler/SchedulerGroup/Task which I could retrieve with very little overhead.
A hook which is called whenever a ConcRT thread grabs a new task would be my ideal, as I could then retrieve the Scheduler/ScheduleGroup ID and store it in a thread local for minimal access overhead. Alas, I can't see any way to register such a hook and it doesn't seem to be possible to implement custom Scheduler classes for PPL/agents (see this article).
Is there some reason that you can't pass some sort of context object to these tasks that gives them an interface for updating their status? Because from where I'm standing, it sounds like you have a really bad problem with Singletons (aka global variables), one that should be solved with dependency injection.
If dependency injection isn't an option, there is another strategy for dealing with Singletons. That strategy is basically allowing the Singleton to be a 'stack'. You can 'push' a new value to the Singleton, and then everybody who accesses it gets this new value. And then you can 'pop' the value back off and the value before pushing is restored. This does not have to be directly modeled with an actual stack, which is why I put the words 'push', 'pop' and 'stack' in quotes.
You can adapt this model to your circumstance by having a thread local Singleton that is initialized with the value (not the whole stack of values, just the top value) of the parent thread's version of this variable. Then, if a new context is required for this thread and its children you can push a new value onto the thread-local Singleton.

Is it ok to store large objects (java component for example) in an Application variable?

I am developing an app right now which creates and stores a connection to a local XMPP server in the Application scope. The connection methods are stored in a cfc that makes sure the Application.XMPPConnection is connected and authorized each time it is used, and makes use of the connection to send live events to users. As far as I can tell, this is working fine. BUT it hasn't been tested under any kind of stress.
My question is: Will this set up cause problems later on? I only ask because I can't find evidence of other people using Application variables in this way. If I weren't using railo I would be using CF's event gateway instead to accomplish the same task.
Size itself isn't a problem. If you were to initialize one object per request, you'd burn a lot more memory. The problem is access.
If you have a large number of requests competing for the same object, you need to measure the access time for that object vs. instantiation. Keep in mind that, for data objects, more than one thread can read them. My understanding, though, is that when an object's function is called, it locks that object to other threads until the function returns.
Also, if the object maintains state, you need to consider what to do when multiple threads are getting/setting that data. Will you end up with race conditions?
You might consider handling this object in the session scope, so that it is only instantiated per user (who, likely, will only make one or two simultaneous requests).
Of course you can use application scope for storing these components if they are used by all users in different parts of application.
Now, possible issues are :
size of the component(s)
time needed for initialization if these are set during application start
racing conditions between setting/getting states of these components
For the first, there are ways to calculate size of a component in memory. Lately there were lots of posts on this topic so it would be easy to find some. If you dont have some large structure or query saved inside, I guess you're ok here.
Second, again, if you are not filling this cfc with some large query from DB or doing some slow parsing, you're ok here too.
Third, pay attention to possible situations, where more users are changing states of these components. If so use cflock on each setting of the components the state.

Scalability implications of converting stateless session beans to POJOs

Imagine a heavily-used service object that's implemented as an EJB 2.1 SLSB, and that also happens to be thread-safe in itself by virtue of having no state whatsoever. All its public methods are transactional (via CMT), most simply requiring a transaction, but some requiring a new transaction.
If I convert this SLSB to a genuine singleton POJO (e.g. using a DI framework), how will that affect the scalability of the application? When the service was a SLSB, the EJB container would manage a pool of instances from which each client would get its own copy, so I'm wondering whether turning it into a singleton POJO will introduce some kind of contention for that single instance.
FWIW, none of this service's methods are synchronized.
Clarification: my motivation for converting the SLSB to a POJO is simplicity of both the object's lifecycle (true singleton versus container-managed) and of the code itself (one interface and one annotated POJO, versus three interfaces, one bean class, and a bunch of XML in ejb-jar.xml).
Also, FWIW, the service in question is one component of a collocated web app running on JBoss 3.x.
If the POJO is truly stateless, or has no conversational state (i.e. state is immutable) then this will not worsen the performance, and may even improve slightly since you really are using just one instance from your DI framework rather than a pool from the container. (Even the pool suffers from contention under high load.)
There is no synchronization needed for an object that is thread-safe by design, such as one with none or just immutable state. There will be no contention - threads can freely execute methods on the POJO without synchronization.
By using just the POJO you also get to see really what is going on in your app, and can be sure there is no hidden "container magic" going on behind the scenes.
Your POJO seem perfect.
So No, there will be no contention, your scalability will be perfect.
You have no additional cost.
You even have less because you have one instance instead of several
Your scalability is better because you will never hit the limit of your pool (you don't have).