In this talk on concurrency, Arthur O'Dwyer explains the "blue/green" pattern. This looks like something I'd like to have in my toolbox but don't fully grasp it yet.
Essentially it creates two categories for a shared state (namely blue and green) and has:
A write side, were modifications are atomically added only when the blue state is consistent:
using ConfigMap = std::map<std::string, std::string>; std::atomic<std::shared_ptr<const ConfigMap>> g_config; void setDefaultHostname(std::string const& value) { std::shared_ptr<const ConfigMap> blue = g_config.load(); do { std::shared_ptr<ConfigMap> green = std::make_shared<ConfigMap>(*blue); green->insert_or_assign("default.hostname", value); } while (g_config.compare_exchange_strong(blue, std::move(green))); }
A read side that gets the current value in a lock free manner
std::shared_ptr<const std::string> getDefaultHostname() { std::shared_ptr<const ConfigMap> blue = g_config.load(); auto& value = blue.at("default.hostname"); return std::shared_ptr<const std::string>(std::move(blue), &value); }
That said, here are my questions:
- Is anyone (open source library/established project) using this in production?
- Is there a better explanation available? An alternative example?
- Is it worth the trouble? Especially since the write side has to repeat the expensive clone operation until the blue state contains solely our modification.