generic observer pattern - c++

I'm working with code, which has a lot of observer pattern implementations. All of them are organized in such a manner:
Some interface to be implemented by observers:
class ObserverInterface {
virtual void FooOccurs() = 0;
};
Some class, which implements Register, Unregister and notifications:
class ObservableImpl {
public:
Register(ObserverInterface *observer);
Unregister(ObserverInterface *observer);
private:
void SomeMethod() {
// foo things
for(auto &observer: observers) {
observer.FooOccurs();
}
}
};
Every time there is a copy-paste of Register and Unregister as well as implementation of notification for each method of ObserverInterface. And every time a programmer has to remember about calling Unregister(), if its observer is going to be destructed.
I wish to enclose the observer pattern in two class templates. So far I've got something like that:
http://rextester.com/UZGG86035
But I'm not sure if I'm not reinventing the wheel. Are there any easier, commonly known approach to do that?

In C++11, I'd advise a token-based approach.
You register an observer. An observer is just a std::function<void(Signature...)>.
The registration function return a token, a std::shared_ptr<void>. So long as that returned shared_ptr is valid, the broadcaster will continue to broadcast to that listener.
The listener is now responsible for maintaining that std::shared_ptr lifetime.
Inside the broadcaster, you hold a weak_ptr and .lock() it before broadcasting. If I don't really need to unregister (usually I do not), I lazily clean up my list of weak_ptrs. Otherwise, I the shared_ptr I return has a deletion function that does the unregistration.
Alternatively, your listeners are shared_ptr<std::function<void(Args...)>>, and internally you store weak_ptr to same.
In this model, you cannot inject an unregistraiton function easily. However, it does mean they can use the aliasing constructor themselves to tightly bind the lifetime of the callback to themselves, assuming they are managed by a shared_ptr.
In my experience, simply having listeners maintain a std::vector<token> is sufficient. If they have a more complex listening relationship they can do more work, maintaining keys and the like.
Hybrid models are also possible.
Both of these are acceptable for not-thread-safe broadcasting, and can be written in a few dozen lines of code.
Thread-safe broadcasting gets tricky. Often I find you are better off using a message-passing pattern for this rather than the alternatives, as this reduces the difficulty in reasoning about concurrency slightly.
This also doesn't deal with situations where you want to register listeners willy-nilly, and broadcaster and listener lifetime is like popcorn.

Related

shared_ptr Real life use-cases

shared_ptr is to be used when we have a scenario where it is desirable to have multiple owners of a dynamically allocated item.
Problem is, I can't imagine any scenario where we require multiple owners. Every use-case I can image can be solved with a unique_ptr.
Could someone provide a real life use-case example with code where shared_ptr is required (and by required, I mean the optimal choice as a smart pointer)? And by "real life" I mean some practical and pragmatic use-case, not something overly abstract and fictitious.
In our simulator product, we use a framework to deliver messages between simulation components (called endpoints). These endpoints could reside on multiple threads within a process, or even on multiple machines in a simulation cluster with messages routed through a mesh of RDMA or TCP connections. The API looks roughly like:
class Endpoint {
public:
// Fill in sender address, etc., in msg, then send it to all
// subscribers on topic.
void send(std::unique_ptr<Message> msg, TopicId topic);
// Register this endpoint as a subscriber to topic, with handler
// called on receiving messages on that topic.
void subscribe(TopicId topic,
std::function<void(std::shared_ptr<const Message>)> handler);
};
In general, once the sender endpoint has executed send, it does not need to wait for any response from any receiver. So, if we were to try to keep a single owner throughout the message routing process, it would not make sense to keep ownership in the caller of send or otherwise, send would have to wait until all receivers are done processing the message, which would introduce an unnecessary round trip delay. On the other hand, if multiple receivers are subscribed to the topic, it also wouldn't make sense to assign unique ownership to any single one of them, as we don't know which one of them needs the message the longest. That would leave the routing infrastructure itself as the unique owner; but again, in that case, then the routing infrastructure would have to wait for all receivers to be done, while the infrastructure could have numerous messages to deliver to multiple threads, and it also wants to be able to pass off the message to receivers and be able to go to the next message to be delivered. Another alternative would be to keep a set of unique pointers to messages sent waiting for threads to process them, and have the receivers notify the message router when they're done; but that would also introduce unnecessary overhead.
On the other hand, by using shared_ptr here, once the routing infrastructure is done delivering messages to incoming queues of the endpoints, it can then release ownership to be shared between the various receivers. Then, the thread-safe reference counting ensures that the Message gets freed once all the receivers are done processing it. And in the case that there are subscribers on remote machines, the serialization and transmission component could be another shared owner of the message while it's doing its work; then, on the receiving machine(s), the receiving and deserialization component can pass off ownership of the Message copy it creates to shared ownership of the receivers on that machine.
In a CAD app, I use shared_ptr to save RAM and VRAM when multiple models happen to have a same mesh (e.g. after user copy-pasted these models). As a bonus, multiple threads can access meshes at the same time, because both shared_ptr and weak_ptr are thread safe when used correctly.
Below’s a trivial example. The real code is way more complex due to numerous reasons (GPU buffers, mouse picking, background processing triggered by some user input, and many others) but I hope that’s enough to give you an idea where shared_ptr is justified.
// Can be hundreds of megabytes in these vectors
class Mesh
{
std::string name;
std::vector<Vector3> vertices;
std::vector<std::array<uint32_t, 3>> indices;
BoundingBox bbox;
};
// Just 72 or 80 bytes, very cheap to copy.
// Can e.g. pass copies to another thread for background processing.
// A scene owns a collection of these things.
class Model
{
std::shared_ptr<Mesh> mesh;
Matrix transform;
};
In my program's user interface, I have the concept of "control point values" (a control point value represents the current state of a control on the hardware my program controls), and (of course) the concept of "widgets" (a widget is a GUI component that renders the current state of a control point to the monitor, for the user to see and/or manipulate).
Since it is a pretty elaborate system that it needs to control, we have
lots of different types of control point values (floats, ints, strings, booleans, binary blobs, etc)
lots of different types of widget (text displays, faders, meters, knobs, buttons, etc)
lots of different ways that a given widget could choose to render a particular control point value as text (upper case, lower case, more or fewer digits of precision, etc)
If we just did the obvious thing and wrote a new subclass every time we needed a new combination of the above, we'd end up with a geometric explosion of thousands of subclasses, and therefore a very large codebase that would be difficult to understand or maintain.
To avoid that, I separate out the knowledge of "how to translate a control point value into human-readable text in some particular way" into its own separate immutable object that can be used by anyone to do that translation, e.g.
// My abstract interface
class IControlPointToTextObject
{
public:
virtual std::string getTextForControlPoint(const ControlPoint & cp) const = 0;
};
// An example implementation
class RenderFloatingPointValueAsPercentage : public IControlPointToTextObject
{
public:
RenderFloatingPointValueAsPercentage(int precision) : m_precision(precision)
{
// empty
}
virtual std::string getTextForControlPoint(const ControlPoint & cp) const = 0
{
// code to create and return a percentage with (m_precision) digits after the decimal point goes here....
}
private:
const int m_precision;
};
... so far, so good; now e.g. when I want a text widget to display a control point value as a percentage with 3 digits of after the decimal point, I can do it like this:
TextWidget * myTextWidget = new TextWidget;
myTextWidget->setTextRenderer(std::unique_ptr<IControlPointToTextObject>(new RenderFloatingPointValueAsPercentage(3)));
... and I get what I want. But my GUIs can get rather elaborate, and they might have a large number (thousands) of widgets, and with the above approach I would have to create a separate RenderFloatingPointValueAsPercentage object for each widget, even though most of the RenderFloatingPointValueAsPercentage objects will end up being identical to each other. That's kind of wasteful, so I change my widget classes to accept a std::shared_ptr instead, and now I can do this:
std::shared_ptr<IControlPointToTextObject> threeDigitRenderer = std::make_shared<RenderFloatingPointValueAsPercentage>(3);
myWidget1->setTextRenderer(threeDigitRenderer);
myWidget2->setTextRenderer(threeDigitRenderer);
myWidget3->setTextRenderer(threeDigitRenderer);
[...]
No worries about object lifetimes, no dangling pointers, no memory leaks, no unnecessary creation of duplicate renderer objects. C'est bon :)
Take any lambda, called within a member function, f, of a class, C, where you want to deal with an object that you would pass into the lambda [&] as a reference. While you are waiting inside f for the lambda to finish, C goes out of scope. The function is gone and you have a dangling reference. Segmentation fault is as close as you get to defined behavior, when the lambda is next accessing the reference. You cannot pass the unique punter into the lambda. You couldn't access it from f once it's moved. The solution: shared pointer and [=]. I code the core of a database. We need shared pointers all the time in a multi-threaded infrastructure. Don't forget about the atomic reference counter. But your general scepticism is appreciated. Shared punters are used nearly always when one doesn't need them.
Suppose I want to implement a GLR parser for a language that is or contains a recursive "expression" definition. And the parsing must not just check whether the input conforms to the grammar, but also output something that can be used to do analysis, evaluations, compilations, etc. I'll need something to represent the result of each expression or subexpression grammar symbol. The actual semantic meaning of each grammar rule can be represented by polymorphism, so this will need to be some sort of pointer to a base class Expression.
The natural representation is then a std::shared_ptr<Expression>. An Expression object can be a subexpression of another compound Expression, in which case the compound Expression is the owner of the subexpression. Or an Expression object can be owned by the parse stack of the algorithm in progress, for a grammar production that has not yet been combined with other pieces. But not really both at the same time. If I were writing a LALR parser, I could probably do with std::unique_ptr<Expression>, transferring the subexpressions from the parse stack to the compound expression constructors as each grammar symbol is reduced.
The specific need for shared_ptr comes up with the GLR algorithm. At certain points, when there is more than one possible parse for the input scanned so far, the algorithm will duplicate the parse stack in order to try out tentative parses of each possibility. And as the tentative parsings proceed, each possiblity may need to use up some of those intermediate results from its own parse stack to form subexpressions of some compound expression, so now we might have the same Expression being used by both some number of parse stacks and some number of different compound Expression objects. Hopefully all but one tentative parsing will eventually fail, which means the failed parse stacks get discarded. The Expression objects directly and indirectly contained by discarded parse stacks should possibly be destroyed at that time, but some of them may be used directly or indirectly by other parse stacks.
It would be possible to do all this with just std::unique_ptr, but quite a bit more complicated. You could do a deep clone whenever parse stacks need to split, but that could be wasteful. You could have them owned by some other master container and have the parse stacks and/or compound expressions just use dumb pointers to them, but knowing when to clean them up would be difficult (and possibly end up essentially duplicating a simplified implementation of std::shared_ptr). I think std::shared_ptr is the clear winner here.
See this real life example. The current frame is shared across multiple consumers and with a smart pointer things get easy.
class frame { };
class consumer { public: virtual void draw(std::shared_ptr<frame>) = 0; };
class screen_consumer_t :public consumer { public: void draw(std::shared_ptr<frame>) override {} };
class matrox_consumer_t :public consumer { public: void draw(std::shared_ptr<frame>) override {} };
class decklink_consumer_t :public consumer { public: void draw(std::shared_ptr<frame>) override {} };
int main() {
std::shared_ptr<frame> current_frame = std::make_shared<frame>();
std::shared_ptr<consumer> screen_consumer = std::make_shared<screen_consumer_t>();
std::shared_ptr<consumer> matrox_consumer = std::make_shared<matrox_consumer_t>();
std::shared_ptr<consumer> decklink_consumer = std::make_shared<decklink_consumer_t>();
std::vector<consumer> consumers;
consumers.push_back(screen_consumer);
consumers.push_back(matrox_consumer);
consumers.push_back(decklink_consumer);
//screen_consumer->draw(current_frame);
//matrox_consumer->draw(current_frame);
//decklink_consumer->draw(current_frame);
for(auto c: consumers) c->draw(current_frame);
}
Edited:
Another example can be a Minimax tree, to avoid cyclic redundancy weak_ptr in conjunction with shared_ptr can be used:
struct node_t
{
std::unique_ptr<board_t> board_;
std::weak_ptr<node_t> parent_;
std::vector<std::shared_ptr<node_t>> children_;
};
Have you checked these articles about copy-on-write vector:
https://iheartcoding.net/blog/2016/07/11/copy-on-write-vector-in-c/
copy-on-write PIMPL:
https://crazycpp.wordpress.com/2014/09/13/pimplcow/
and generic copy-on-write pointer:
https://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Copy-on-write
All of them use shared_ptr internally.
std::shared_ptr is an implementation of reference counting technique in C++. For use-cases of reference counting see linked wikipedia article. One usage of reference counting is garbage collection in programming languages. So if you decide to write a new programming language with garbage collection in C++ you can implement it with std::shared_ptr, though you will also have to deal with cycles.
Simply put: there isn't really any.
For more detailed explanation, let's turn to formal reasoning. As we all know, C++ is a Turing-complete deterministic language. A popular simple example of equally computationally powerful tool is Brainfuck (often very convenient in establishing Turing-completeness of your favorite language of choice). If we look into Brainfuck's description (which is very small indeed, which makes it very handy for the purposes noted heretofore), we'll soon find out that there is not a single notion of anything resembling shared_ptr in there. So the answer is: no, there is no a real-life example where they would be absolutely required. Everything computable can be done without shared_ptrs.
If we continue the process thoroughly, we'll get rid equally easily of other unnecessary concepts, i.e. unique_ptr, std::unordered_map, exceptions, range-loops and so forth.

Async I/O operations - proper way to avoid deleting object

Using async I/O operations from boost::asio I often need shared pointers (and enable_shared_from_this and shared_from_this in callbacks) to avoid deleting objects too early.
I think that it could be done by keeping unique_ptr or just object (ownership) in class (as a member)
For example:
Only foo method use sender.
1st (popular solution):
class C {
public:
void foo
{
std::shared_ptr<Sender> sender = std::make_shared<Sender>();
sender->send();
// class Sender use async_write
// inheritance: enable_shared_from_this
// callback in async operation created with argument shared_from_this
}
};
Why nobody(?) use this solution:
class D {
public:
void foo
{
sender.reset(new Sender);
sender->send();
}
private:
std::unique_ptr<Sender> sender;
};
I know that sender will not be deleted to early. I have no shared_ptrs. I think it's good to avoid them because if callback in Sender class also use async operations I need another shared pointers etc. I think that class D is more friendly to read.
But I wonder if it's a good style... and I always see solution with shared_ptrs in the net.
You can only have one unique_ptr to an object. What happens if you have both a send and a receive operation pending? What happens if you have both a receive operation and a timer?
Yes, you could use a unique_ptr, but then you'd have to implement your own count of the number of outstanding operations. You'd have to increment and decrement that count in a thread-safe way. And you'd have to constantly check if that count was zero to invoke the destructor. To clean this up, you'd likely bundle all this functionality into its own class. And you'd have reinvented shared_ptr.
The latter usage is fragile and makes no guarantee that the sender will not be deleted too early. For instance, consider the case where D::foo() is called consecutively, before the asynchronous operations have completed. The previous Sender object could be deleted with outstanding operations that may depend on the Sender object:
public: Sender
{
public:
void send()
{
boost::asio::async_write(socket_, boost::asio::buffer(buffer_), ...);
}
private:
std::array<char, 64> buffer_;
boost::asio::ip::tcp::socket socket_;
...
};
D d;
d.foo(); // Create Sender1, initiate async_write.
d.foo(); // Delete Sender1, create Sender2, initiate async_write.
io_service.run(); // Sender1's async_write invokes undefined behavior.
In the above code, the second call to d.foo() will delete the first Sender object that has outstanding operations, resulting in undefined behavior. On the other hand, if Sender inherits from enable_shared_from_this, and the result of shared_from_this() is bound to the handlers for asynchronous operations, then the Sender object's lifetime would extend to be at least as long as the operations.
Have you looked at asio::spawn? Basically, it takes most of the complexity out of async C++ programming, and allow you to just put your objects on the stack.
Here is a simple example: modern.cpp
Using this approach saves a lot of time implementing and debugging an async application, and it makes the code really easy to understand. (I once implemented a RTP over TCP proxy, using traditional callbacks. It turned out to be a nightmare to maintain later on).
Regarding shard versus unique pointers - my experience is that shared pointers are simpler to use with asio. There were some problems moving unique pointers around, and when the program becomes slightly complex, it's really easy to make mistake mistakes. I think I would stick with shared and weak pointers as default - and only switch to unique pointers for objects where the profiler outputs suggests that it's worth the while.

Observer Design Pattern Issues

I am working on a large project in C++ that will have a graphical user interface.
The user interface will use some design pattern (MVVM/MVC) that will rely on the observer pattern.
My problem is that I currently have no way of predicting which parts of the Model should be observable. And there are many, many parts.
I find myself being pulled in several directions due to this issue:
If I develop back-end classes that do not support notification I will find myself violating the Open-Closed principle.
If I do provide support for notification to all Model classes and all of their data members it will have a massive performance cost that is unjustified since only a fraction of this support will actually be needed (even though this fraction is unknown).
The same is true if I only provide support for extension by making all non-const methods virtual and accessing these methods through base-pointers. This will also have a cost in readability.
I feel that out of these 3, (1.) is probably the lesser evil.
However, I feel like an ideal solution should actually exists in some language (definitely not C++), but I don't know if it's supported anywhere.
The unicorn solution I was thinking of is something like this:
Given a class Data, shouldn't it be possible for clients that seek to make Data observable do something like
#MakeObservable(Data)
as a compile time construct. This in turn would make it possible to call addObserver on Data objects and modify all assignments to data members with notifiers. it would also make you pay in performance only for what you get.
So my question is two-fold:
Am I right to assume that out of the 3 options I stated, (1.) is the lesser but necessary evil?
Does my unicorn solution exist anywhere? being worked on? or would be impossible to implement for some reason?
If I understand correctly, you're concerned with the cost of providing a signal/notification for potentially every observable property of every object.
Fortunately you're in luck, since storing a general thread-safe notifier with every single property of every object would generally be extremely expensive in any language or system.
Instead of getting all clever and trying to solve this problem at compile-time, which I recommend would shut out some very potentially useful options to a large-scale project (ex: plugins and scripting), I'd suggest thinking about how to make this cheaper at runtime. You want your signals to be stored at a coarser level than the individual properties of an object.
If you store just one with the object that passes along the appropriate data about which property was modified during a property change event to filter which clients to notify, then now we're getting a lot cheaper. We're exchanging some additional branching and larger aggregates for the connected slots, but you get a significantly smaller object in exchange with potentially faster read access, and I'd suggest this is a very valuable exchange in practice.
You can still design your public interface and even the event notification mechanism so that clients work with the system in a way that feels like they're connecting to properties rather than the whole object, perhaps even calling methods in a property (if it's an object/proxy) to connect slots if you need or can afford a back pointer to the object from a property.
If you're not sure, I would err on the side of attaching event slots to properties as well as modifying them as part of the object interface rather than property interface, as you'll have a lot more breathing room to optimize in exchange for a slightly different client aesthetic (one that I really don't think is less convenient so much as just 'different', or at least potentially worth the cost of eliminating a back pointer per property).
That's in the realm of convenience and wrapper-type things. But you don't need to violate the open-closed principle to achieve MVP designs in C++. Don't get crammed into a corner by data representation. You have a lot of flexibility at the public interface level.
Memory Compaction -- Paying for What We Use
On discovering that efficiency plays an important role here, I'd suggest some basic ways of thinking to help with that.
First, just because an object has some accessor like something() does not mean that the associated data has to be stored in that object. It doesn't even have to be stored anywhere until that method is called. If memory is your concern, it can be stored at some level outside.
Most software breaks down into hierarchies of aggregates owning resources. For example, in a 3D software, a vertex is owned by a mesh which is owned by the scene graph which is owned by the application root.
If you want designs where you pay almost no memory cost whatsoever for things that are not being used, then you want to associate the data to the object at a coarser level. If you store it directly in the object, then every object pays for what something() returns regardless of whether it is needed. If you store it indirectly in the object with a pointer, then you pay for the pointer to something() but not for the full cost of it unless it is used. If you associate it to the owner of the object, then retrieving it has a lookup cost, but one that is not as expensive as associating it to the owner of the owner of the object.
So there's always ways to get something very close to free for things you don't use if you associate at a coarse enough level. At granular levels you mitigate lookup and indirection overhead, at coarse levels you mitigate costs for things you don't use.
Massive Scale Events
Given massive scalability concerns with millions to billions of elements being processed, and still the desire for potentially some of them to generate events, if you can use an asynchronous design, I'd really recommend it here. You can have a lock-free per-thread event queue to which objects with a single bit flag set generate events. If the bit flag is not set, they don't.
This kind of deferred, async design is useful with such scale since it gives you periodic intervals (or possibly just other threads, though you'd need write locks -- as well as read locks, though writing is what needs to cheap -- in that case) in which to poll and devote full resources to bulk processing the queue while the more time-critical processing can continue without synchronizing with the event/notifier system.
Basic Example
// Interned strings are very useful here for fast lookups
// and reduced redundancy in memory.
// They're basically just indices or pointers to an
// associative string container (ex: hash or trie).
// Some contextual class for the thread storing things like a handle
// to its event queue, thread-local lock-free memory allocator,
// possible error codes triggered by functions called in the thread,
// etc. This is optional and can be replaced by thread-local storage
// or even just globals with an appropriate lock. However, while
// inconvenient, passing this down a thread's callstack is usually
// the most efficient and reliable, lock-free way.
// There may be times when passing around this contextual parameter
// is too impractical. There TLS helps in those exceptional cases.
class Context;
// Variant is some generic store/get/set anything type.
// A basic implementation is a void pointer combined with
// a type code to at least allow runtime checking prior to
// casting along with deep copying capabilities (functionality
// mapped to the type code). A more sophisticated one is
// abstract and overriden by subtypes like VariantInt
// or VariantT<int>
typedef void EventFunc(Context& ctx, int argc, Variant** argv);
// Your universal object interface. This is purely abstract:
// I recommend a two-tier design here:
// -- ObjectInterface->Object->YourSubType
// It'll give you room to use a different rep for
// certain subtypes without affecting ABI.
class ObjectInterface
{
public:
virtual ~Object() {}
// Leave it up to the subtype to choose the most
// efficient rep.
virtual bool has_events(Context& ctx) const = 0;
// Connect a slot to the object's signal (or its property
// if the event_id matches the property ID, e.g.).
// Returns a connection handle for th eslot. Note: RAII
// is useful here as failing to disconnect can have
// grave consequences if the slot is invalidated prior to
// the signal.
virtual int connect(Context& ctx, InternedString event_id, EventFunc func, const Variant& slot_data) = 0;
// Disconnect the slot from the signal.
virtual int disconnect(Context& ctx, int slot) = 0;
// Fetches a property with the specified ID O(n) integral cmps.
// Recommended: make properties stateless proxies pointing
// back to the object (more room for backend optimization).
// Properties can have set<T>/get<T> methods (can build this
// on top of your Variant if desired, but a bit more overhead
// if so).
// If even interned string compares are not fast enough for
// desired needs, then an alternative, less convenient interface
// to memoize property indices from an ID might be appropriate in
// addition to these.
virtual Property operator[](InternedString prop_id) = 0;
// Returns the nth property through an index.
virtual Property operator[](int n) = 0;
// Returns the number of properties for introspection/reflection.
virtual int num_properties() const = 0;
// Set the value of the specified property. This can generate
// an event with the matching property name to indicate that it
// changed.
virtual void set_value(Context& ctx, InternedString prop_id, const Variant& new_value) = 0;
// Returns the value of the specified property.
virtual const Variant& value(Context& ctx, InternedString prop_id) = 0;
// Poor man's RTTI. This can be ignored in favor of dynamic_cast
// for a COM-like design to retrieve additional interfaces the
// object supports if RTTI can be allowed for all builds/modes.
// I use this anyway for higher ABI compatibility with third
// parties.
virtual Interface* fetch_interface(Context& ctx, InternedString interface_id) = 0;
};
I'll avoid going into the nitty gritty details of the data representation -- the whole point is that it's flexible. What's important is to buy yourself room to change it as needed. Keeping the object abstract, keeping the property as a stateless proxy (with the exception of the backpointer to the object), etc. gives a lot of breathing room to profile and optimize away.
For async event handling, each thread should have a queue associated which can be passed down the call stack through this Context handle. When events occur, such as a property change, objects can push events to this queue through it if has_events() == true. Likewise, connect doesn't necessarily add any state to the object. It can create an associative structure, again through Context, which maps the object/event_id to the client. disconnect also removes it from that central thread source. Even the act of connecting/disconnecting a slot to/from a signal can be pushed to the event queue for a central, global place to process and make the appropriate associations (again preventing objects without observers from paying any memory cost).
When using this type of design, each thread should have at its entry point an exit handler for the thread which transfers the events pushed to the thread event queue from the thread-local queue to some global queue. This requires a lock but can be done not-too-frequently to avoid heavy contention and to allow each thread to not be slowed down by the event processing during performance-critical areas. Some kind of thread_yield kind of function should likewise be provided with such a design which also transfers from the thread-local queue to the global queue for long-lived threads/tasks.
The global queue is processed in a different thread, triggering the appropriate signals to the connected slots. There it can focus on bulk processing the queue when it isn't empty, sleeping/yielding when it is. The whole point of all of this is to aid performance: pushing to a queue is extremely cheap compared to the potential of sending synchronous events every time an object property is modified, and when working with massive scale inputs, this can be a very costly overhead. So simply pushing to a queue allows that thread to avoid spending its time on the event handling, deferring it to another thread.
Templatious library can help you with completely decoupling GUI and domain logic and making flexible/extendable/easy to maintain message systems and notifiers.
However, there's one downside - you need C++11 support for this.
Check out this article taming qt
And the example in github: DecoupledGuiExamples
So, you probably don't need notifiers on every class, you can just shoot messages from the inside functions and on specific classes where you can make any class send any message you want to GUI.

Pattern for safe asynchronous callbacks in C++

What alternatives does one have to the following code for performing safe asynchronous callbacks on an object?
class MyClass : public std::enable_shared_from_this<MyClass>
{
private:
void fetchResults()
{
std::weak_ptr<MyClass> weakSelf = shared_from_this();
m_service.getResultAsync(
/* args... */,
/* Callback */
[weakSelf](Result r)
{
auto self = weakSelf.lock();
if (self)
{
self->workFinishedWithResult(std::move(r));
}
});
}
void workFinishedWithResult(Result r) { // ... continue workflow }
std::shared_ptr<Service> m_service;
};
I would like to avoid using enable_shared_from_this (and avoid clients of m_service requiring it for what is a very common use case), but it seems difficult to extend the lifetime of MyClass once inside the callback without it.
Capturing this in the lambda instead and trying to deregister it in MyClass' destructor, or preventing MyClass from being destructed until the callback is finished is a path that leads to races, deadlocks and a loss of simplicity. I'm almost certain that capturing 'this' can't be made safe.
It seems if MyClass is asking a shared_ptr<Service> to call it back, it can only guarantee that it remains valid if it can manage or extend its own lifetime (via enable_shared_from_this) since it doesn't know how long the callback will live for. Otherwise it would have to be the responsibility of whoever owns MyClass, or whoever knows the lifetime of both the Service and MyClass to deal with this, but it all becomes very error-prone and impractical.
It seems the only viable solutions are:
Use enable_shared_from_this with the "capture weakly" pattern (as in the above code)
Have MyClass be given a Service& so it is the caller's responsibility to ensure the service outlives it.
Use a static method/function as the callback and pass everything it needs in by-value (problem is that sometimes you really do want to pass control back into MyClass and you have the same problem).
What are the alternatives here? Or does using enable_shared_from_this just become inevitable when doing async C++?
The exact thing that you're looking for would be std::future<T>::then(). It does not exist in C++11, but boost::future offers it.
However, in the general case, it would be the responsibility of the caller to ensure that the service and MyClass instances live long enough, although it would be also acceptable if the method takes an owning reference to the service.

Help me remove a Singleton: looking for an alternative

Background: I have some classes implementing a subject/observer design pattern that I've made thread-safe. A subject will notify it's observers by a simple method call observer->Notified( this ) if the observer was constructed in the same thread as the notification is being made. But if the observer was constructed in a different thread, then the notification will be posted onto a queue to be processed later by the thread that constructed the observer and then the simple method call can be made when the notification event is processed.
So… I have a map associating threads and queues which gets updated when threads and queues are constructed and destroyed. This map itself uses a mutex to protect multi-threaded access to it.
The map is a singleton.
I've been guilty of using singletons in the past because "there will be only one in this application", and believe me - I have paid my penance!
One part of me can't help thinking that there really will be only one queue/thread map in an application. The other voice says that singletons are not good and you should avoid them.
I like the idea of removing the singleton and being able to stub it for my unit tests. Trouble is, I'm having a hard time trying to think of a good alternative solution.
The "usual" solution which has worked in the past is to pass in a pointer to the object to use instead of referencing the singleton. I think that would be tricky in this case, since observers and subjects are 10-a-penny in my application and it would very awkward to have to pass a queue/thread map object into the constructor of every single observer.
What I appreciate is that I may well have only one map in my application, but it shouldn't be in the bowels of the subject and observer class code where that decision is made.
Maybe this is a valid singleton, but I'd also appreciate any ideas on how I could remove it.
Thanks.
PS. I have read What's Alternative to Singleton and this article mentioned in the accepted answer. I can't help thinking that the ApplicationFactory it just yet another singleton by another name. I really don't see the advantage.
If the only purpose to trying to get rid of the singleton is from a unit test perspective, maybe replacing the singleton getter with something that you can swap in a stub for.
class QueueThreadMapBase
{
//virtual functions
};
class QeueueThreadMap : public QueueThreadMapBase
{
//your real implementation
};
class QeueueThreadMapTestStub : public QueueThreadMapBase
{
//your test implementation
};
static QueueThreadMapBase* pGlobalInstance = new QeueueThreadMap;
QueueThreadMapBase* getInstance()
{
return pGlobalInstance;
}
void setInstance(QueueThreadMapBase* pNew)
{
pGlobalInstance = pNew
}
Then in your test just swap out the queue/thread map implementation. At the very least this exposes the singleton a little more.
Some thoughts towards a solution:
Why do you need to enqueue notifications for observers that were created on a different thread? My preferred design would be to have the subject just notify the observers directly, and put the onus on the observers to implement themselves thread-safely, with the knowledge that Notified() might be called at any time from another thread. The observers know which parts of their state need to be protected with locks, and they can handle that better than the subject or the queue.
Assuming that you really have a good reason for keeping the queue, why not make it an instance? Just do queue = new Queue() somewhere in main, and then pass around that reference. There may only every be one, but you can still treat that as an instance and not a global static.
What's wrong with putting the queue inside the subject class? What do you need the map for?
You already have a thread reading from the singleton queue map. Instead of doing that simply make the map inside the subject class and provide two methods to subscribe an observer:
class Subject
{
// Assume is threadsafe and all
private QueueMap queue;
void Subscribe(NotifyCallback, ThreadId)
{
// If it was created from another thread add to the map
if (ThreadId != This.ThreadId)
queue[ThreadId].Add(NotifyCallback);
}
public NotifyCallBack GetNext()
{
return queue[CallerThread.Id].Pop;
}
}
Now any thread can call the GetNext method to start dispatching... of course it is all overly simplified, but it's just the idea.
Note: I'm working with the assumption that you already have an architecture around this model so that you already have a bunch of Observers, one or more subjects and that the threads already go to the map to do the notifications. This gets rid of the singleton but I'd suggest you notify from the same thread and let the observers handle concurrency issues.
My approach was to have the observers provide a queue when they registered with the subject; the observer's owner would be responsible for both the thread and the associated queue, and the subject would associate the observer with the queue, with no need for a central registry.
Thread-safe observers could register without a queue, and be called directly by the subject.
Your observers may be cheap, but they depend on the notification-queue-thread map, right?
What's awkward about making that dependency explicit and taking control of it?
As for the application factory Miško Hevery describes in his article, the biggest advantages are that 1) the factory approach doesn't hide dependencies and 2) the single instances you depend on aren't globally available such that any other object can meddle with their state. So using this approach, in any given top-level application context, you know exactly what's using your map. With a globally accessible singleton, any class you use might be doing unsavory things with or to the map.
What about adding a Reset method that returns a singleton to its initial state that you can call between tests? That might be simpler than a stub. It might be possible to add a generic Reset method to a Singleton template (deletes the internal singleton pimpl and resets the pointer). This could even include a registry of all singletons with a master ResetAll method to reset all of them!