Merge "Prevent fetch command queue requests from piling up"
diff --git a/libweave/src/device_registration_info.cc b/libweave/src/device_registration_info.cc
index 2f058a8..310eaf0 100644
--- a/libweave/src/device_registration_info.cc
+++ b/libweave/src/device_registration_info.cc
@@ -1008,11 +1008,10 @@
StartQueuedUpdateDeviceResource();
}
-namespace {
-
-void HandleFetchCommandsResult(
+void DeviceRegistrationInfo::OnFetchCommandsSuccess(
const base::Callback<void(const base::ListValue&)>& callback,
const base::DictionaryValue& json) {
+ OnFetchCommandsReturned();
const base::ListValue* commands{nullptr};
if (!json.GetList("commands", &commands)) {
VLOG(2) << "No commands in the response.";
@@ -1021,18 +1020,41 @@
callback.Run(commands ? *commands : empty);
}
-} // namespace
+void DeviceRegistrationInfo::OnFetchCommandsError(
+ const CloudRequestErrorCallback& callback,
+ const Error* error) {
+ OnFetchCommandsReturned();
+ callback.Run(error);
+}
+
+void DeviceRegistrationInfo::OnFetchCommandsReturned() {
+ fetch_commands_request_sent_ = false;
+ // If we have additional requests queued, send them out now.
+ if (fetch_commands_request_queued_)
+ FetchAndPublishCommands();
+}
void DeviceRegistrationInfo::FetchCommands(
const base::Callback<void(const base::ListValue&)>& on_success,
const CloudRequestErrorCallback& on_failure) {
+ fetch_commands_request_sent_ = true;
+ fetch_commands_request_queued_ = false;
DoCloudRequest(
http::kGet,
GetServiceURL("commands/queue", {{"deviceId", config_->device_id()}}),
- nullptr, base::Bind(&HandleFetchCommandsResult, on_success), on_failure);
+ nullptr,
+ base::Bind(&DeviceRegistrationInfo::OnFetchCommandsSuccess, AsWeakPtr(),
+ on_success),
+ base::Bind(&DeviceRegistrationInfo::OnFetchCommandsError, AsWeakPtr(),
+ on_failure));
}
void DeviceRegistrationInfo::FetchAndPublishCommands() {
+ if (fetch_commands_request_sent_) {
+ fetch_commands_request_queued_ = true;
+ return;
+ }
+
FetchCommands(base::Bind(&DeviceRegistrationInfo::PublishCommands,
weak_factory_.GetWeakPtr()),
base::Bind(&IgnoreCloudError));
diff --git a/libweave/src/device_registration_info.h b/libweave/src/device_registration_info.h
index 564fb87..93fe85c 100644
--- a/libweave/src/device_registration_info.h
+++ b/libweave/src/device_registration_info.h
@@ -233,6 +233,15 @@
void FetchCommands(
const base::Callback<void(const base::ListValue&)>& on_success,
const CloudRequestErrorCallback& on_failure);
+ // Success/failure callbacks for FetchCommands().
+ void OnFetchCommandsSuccess(
+ const base::Callback<void(const base::ListValue&)>& callback,
+ const base::DictionaryValue& json);
+ void OnFetchCommandsError(const CloudRequestErrorCallback& callback,
+ const Error* error);
+ // Called when FetchCommands completes (with either success or error).
+ // This method reschedules any pending/queued fetch requests.
+ void OnFetchCommandsReturned();
// Processes the command list that is fetched from the server on connection.
// Aborts commands which are in transitional states and publishes queued
@@ -307,6 +316,12 @@
// to the cloud server.
bool device_state_update_pending_{false};
+ // Set to true when command queue fetch request is in flight to the server.
+ bool fetch_commands_request_sent_{false};
+ // Set to true when another command queue fetch request is queued while
+ // another one was in flight.
+ bool fetch_commands_request_queued_{false};
+
using ResourceUpdateCallbackList =
std::vector<std::pair<base::Closure, CloudRequestErrorCallback>>;
// Success/error callbacks for device resource update request currently in