buffet: Support multiple proxies for a command. This is necessary to support Cloud API updates on command changes. BUG=None TEST=cros_workon_make buffet --test&&manual Change-Id: I09149d02c0564aa89c74bd66356b63547c17724f Reviewed-on: https://chromium-review.googlesource.com/226533 Tested-by: Anton Muhin <antonm@chromium.org> Reviewed-by: Alex Vakulenko <avakulenko@chromium.org> Commit-Queue: Anton Muhin <antonm@chromium.org>
diff --git a/buffet/commands/command_instance.cc b/buffet/commands/command_instance.cc index 9e1211a..f403630 100644 --- a/buffet/commands/command_instance.cc +++ b/buffet/commands/command_instance.cc
@@ -137,8 +137,9 @@ if (progress != progress_) { progress_ = progress; SetStatus(kStatusInProgress); - if (proxy_) - proxy_->OnProgressChanged(progress_); + for (auto& proxy : proxies_) { + proxy->OnProgressChanged(progress_); + } } return true; } @@ -165,8 +166,9 @@ void CommandInstance::SetStatus(const std::string& status) { if (status != status_) { status_ = status; - if (proxy_) - proxy_->OnStatusChanged(status_); + for (auto& proxy : proxies_) { + proxy->OnStatusChanged(status_); + } } }
diff --git a/buffet/commands/command_instance.h b/buffet/commands/command_instance.h index f8bde2a..e35fd7b 100644 --- a/buffet/commands/command_instance.h +++ b/buffet/commands/command_instance.h
@@ -8,6 +8,7 @@ #include <map> #include <memory> #include <string> +#include <vector> #include <base/macros.h> #include <chromeos/errors/error.h> @@ -58,9 +59,11 @@ // Sets the command ID (normally done by CommandQueue when the command // instance is added to it). void SetID(const std::string& id) { id_ = id; } - // Sets the command proxy for the dispatch technology used. + // Adds a proxy for this command. // The proxy object is not owned by this class. - void SetProxy(CommandProxyInterface* proxy) { proxy_ = proxy; } + void AddProxy(CommandProxyInterface* proxy) { proxies_.push_back(proxy); } + // Removes all the proxies for this command. + void ClearProxies() { proxies_.clear(); } // Sets the pointer to queue this command is part of. void SetCommandQueue(CommandQueue* queue) { queue_ = queue; } @@ -111,10 +114,8 @@ std::string status_ = kStatusQueued; // Current command execution progress. int progress_ = 0; - // Command proxy class for the current dispatch technology (e.g. D-Bus). - // This is a weak pointer. The proxy's lifetime is managed by the command - // dispatcher. - CommandProxyInterface* proxy_ = nullptr; + // Command proxies for the command. + std::vector<CommandProxyInterface*> proxies_; // Pointer to the command queue this command instance is added to. // The queue owns the command instance, so it outlives this object. CommandQueue* queue_ = nullptr;
diff --git a/buffet/commands/dbus_command_dispatcher.cc b/buffet/commands/dbus_command_dispatcher.cc index e6041d2..591c1cc 100644 --- a/buffet/commands/dbus_command_dispatcher.cc +++ b/buffet/commands/dbus_command_dispatcher.cc
@@ -24,7 +24,7 @@ void DBusCommandDispacher::OnCommandAdded(CommandInstance* command_instance) { auto proxy = CreateDBusCommandProxy(command_instance); proxy->RegisterAsync(AsyncEventSequencer::GetDefaultCompletionAction()); - command_instance->SetProxy(proxy.get()); + command_instance->AddProxy(proxy.get()); auto pair = std::make_pair(command_instance, std::move(proxy)); CHECK(command_map_.insert(std::move(pair)).second) @@ -32,7 +32,7 @@ } void DBusCommandDispacher::OnCommandRemoved(CommandInstance* command_instance) { - command_instance->SetProxy(nullptr); + command_instance->ClearProxies(); CHECK_GT(command_map_.erase(command_instance), 0u) << "The command instance is not in the dispatcher command map"; }
diff --git a/buffet/commands/dbus_command_proxy_unittest.cc b/buffet/commands/dbus_command_proxy_unittest.cc index 34d9f1d..f8fba8d 100644 --- a/buffet/commands/dbus_command_proxy_unittest.cc +++ b/buffet/commands/dbus_command_proxy_unittest.cc
@@ -92,14 +92,14 @@ command_proxy_.reset(new DBusCommandProxy(nullptr, bus_, command_instance_.get())); - command_instance_->SetProxy(command_proxy_.get()); + command_instance_->AddProxy(command_proxy_.get()); command_proxy_->RegisterAsync( AsyncEventSequencer::GetDefaultCompletionAction()); } void TearDown() override { EXPECT_CALL(*mock_exported_object_command_, Unregister()).Times(1); - command_instance_->SetProxy(nullptr); + command_instance_->ClearProxies(); command_proxy_.reset(); command_instance_.reset(); dict_.Clear();