Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(80)

Unified Diff: google_apis/gcm/engine/gcm_store_impl.cc

Issue 1121003003: [GCM] Adding handling of heartbeat intervals to the GCM store. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@heartbeat-gcm
Patch Set: Adding histrograms Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « google_apis/gcm/engine/gcm_store_impl.h ('k') | google_apis/gcm/engine/gcm_store_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: google_apis/gcm/engine/gcm_store_impl.cc
diff --git a/google_apis/gcm/engine/gcm_store_impl.cc b/google_apis/gcm/engine/gcm_store_impl.cc
index 602106ba298865f8dabc45d0542193dc842cc28a..4105e68518b6cd89dbce19c1c122554d82e9b367 100644
--- a/google_apis/gcm/engine/gcm_store_impl.cc
+++ b/google_apis/gcm/engine/gcm_store_impl.cc
@@ -47,6 +47,7 @@ enum LoadStatus {
LOADING_GSERVICE_SETTINGS_FAILED,
LOADING_ACCOUNT_MAPPING_FAILED,
LOADING_LAST_TOKEN_TIME_FAILED,
+ LOADING_HEARTBEAT_INTERVALS_FAILED,
// NOTE: always keep this entry at the end. Add new status types only
// immediately above this line. Make sure to update the corresponding
@@ -98,6 +99,12 @@ const char kAccountKeyStart[] = "account1-";
// Key guaranteed to be higher than all account keys.
// Used for limiting iteration.
const char kAccountKeyEnd[] = "account2-";
+// Lowest lexicographically ordered heartbeat key.
+// Used for prefixing account information.
+const char kHeartbeatKeyStart[] = "heartbeat1-";
+// Key guaranteed to be higher than all heartbeat keys.
+// Used for limiting iteration.
+const char kHeartbeatKeyEnd[] = "heartbeat2-";
// Key used for last token fetch time.
const char kLastTokenFetchTimeKey[] = "last_token_fetch_time";
@@ -137,6 +144,14 @@ std::string ParseAccountKey(const std::string& key) {
return key.substr(arraysize(kAccountKeyStart) - 1);
}
+std::string MakeHeartbeatKey(const std::string& scope) {
Nicolas Zea 2015/05/04 17:45:28 remind me, what is the scope derived from?
fgorski 2015/05/04 18:14:54 It is simply a token uniquely identifying componen
+ return kHeartbeatKeyStart + scope;
+}
+
+std::string ParseHeartbeatKey(const std::string& key) {
+ return key.substr(arraysize(kHeartbeatKeyStart) - 1);
+}
+
// Note: leveldb::Slice keeps a pointer to the data in |s|, which must therefore
// outlive the slice.
// For example: MakeSlice(MakeOutgoingKey(x)) is invalid.
@@ -194,6 +209,11 @@ class GCMStoreImpl::Backend
const UpdateCallback& callback);
void SetLastTokenFetchTime(const base::Time& time,
const UpdateCallback& callback);
+ void AddHeartbeatInterval(const std::string& scope,
+ int interval_ms,
+ const UpdateCallback& callback);
+ void RemoveHeartbeatInterval(const std::string& scope,
+ const UpdateCallback& callback);
void SetValue(const std::string& key,
const std::string& value,
const UpdateCallback& callback);
@@ -213,6 +233,7 @@ class GCMStoreImpl::Backend
std::string* digest);
bool LoadAccountMappingInfo(AccountMappings* account_mappings);
bool LoadLastTokenFetchTime(base::Time* last_token_fetch_time);
+ bool LoadHeartbeatIntervals(std::map<std::string, int>* heartbeat_intervals);
const base::FilePath path_;
scoped_refptr<base::SequencedTaskRunner> foreground_task_runner_;
@@ -273,7 +294,9 @@ LoadStatus GCMStoreImpl::Backend::OpenStoreAndLoadData(LoadResult* result) {
if (!LoadAccountMappingInfo(&result->account_mappings))
return LOADING_ACCOUNT_MAPPING_FAILED;
if (!LoadLastTokenFetchTime(&result->last_token_fetch_time))
- return LOADING_LAST_TOKEN_TIME_FAILED;
+ return LOADING_LAST_TOKEN_TIME_FAILED;
+ if (!LoadHeartbeatIntervals(&result->heartbeat_intervals))
+ return LOADING_HEARTBEAT_INTERVALS_FAILED;
return LOADING_SUCCEEDED;
}
@@ -688,6 +711,52 @@ void GCMStoreImpl::Backend::SetLastTokenFetchTime(
foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
}
+void GCMStoreImpl::Backend::AddHeartbeatInterval(
+ const std::string& scope,
+ int interval_ms,
+ const UpdateCallback& callback) {
+ DVLOG(1) << "Saving a heartbeat interval: scope: " << scope
+ << " interval: " << interval_ms << "ms.";
+ if (!db_.get()) {
+ LOG(ERROR) << "GCMStore db doesn't exist.";
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
+ }
+
+ leveldb::WriteOptions write_options;
+ write_options.sync = true;
+
+ std::string data = base::IntToString(interval_ms);
+ std::string key = MakeHeartbeatKey(scope);
+ const leveldb::Status s =
+ db_->Put(write_options, MakeSlice(key), MakeSlice(data));
+ if (!s.ok())
+ LOG(ERROR) << "LevelDB adding heartbeat interval failed: " << s.ToString();
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+}
+
+void GCMStoreImpl::Backend::RemoveHeartbeatInterval(
+ const std::string& scope,
+ const UpdateCallback& callback) {
+ if (!db_.get()) {
+ LOG(ERROR) << "GCMStore db doesn't exist.";
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, false));
+ return;
+ }
+
+ leveldb::WriteOptions write_options;
+ write_options.sync = true;
+
+ leveldb::Status s =
+ db_->Delete(write_options, MakeSlice(MakeHeartbeatKey(scope)));
+
+ if (!s.ok()) {
+ LOG(ERROR) << "LevelDB removal of heartbeat interval failed: "
+ << s.ToString();
+ }
+ foreground_task_runner_->PostTask(FROM_HERE, base::Bind(callback, s.ok()));
+}
+
void GCMStoreImpl::Backend::SetValue(const std::string& key,
const std::string& value,
const UpdateCallback& callback) {
@@ -929,6 +998,30 @@ bool GCMStoreImpl::Backend::LoadLastTokenFetchTime(
return true;
}
+bool GCMStoreImpl::Backend::LoadHeartbeatIntervals(
+ std::map<std::string, int>* heartbeat_intervals) {
+ leveldb::ReadOptions read_options;
+ read_options.verify_checksums = true;
+
+ scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(read_options));
+ for (iter->Seek(MakeSlice(kHeartbeatKeyStart));
+ iter->Valid() && iter->key().ToString() < kHeartbeatKeyEnd;
+ iter->Next()) {
+ std::string scope = ParseHeartbeatKey(iter->key().ToString());
+ int interval_ms;
+ if (!base::StringToInt(iter->value().ToString(), &interval_ms)) {
+ DVLOG(1) << "Failed to parse heartbeat interval info with scope: "
+ << scope;
+ return false;
+ }
+ DVLOG(1) << "Found heartbeat interval with scope: " << scope
+ << " interval: " << interval_ms << "ms.";
+ (*heartbeat_intervals)[scope] = interval_ms;
+ }
+
+ return true;
+}
+
GCMStoreImpl::GCMStoreImpl(
const base::FilePath& path,
scoped_refptr<base::SequencedTaskRunner> blocking_task_runner,
@@ -1159,6 +1252,28 @@ void GCMStoreImpl::SetLastTokenFetchTime(const base::Time& time,
callback));
}
+void GCMStoreImpl::AddHeartbeatInterval(const std::string& scope,
+ int interval_ms,
+ const UpdateCallback& callback) {
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GCMStoreImpl::Backend::AddHeartbeatInterval,
+ backend_,
+ scope,
+ interval_ms,
+ callback));
+}
+
+void GCMStoreImpl::RemoveHeartbeatInterval(const std::string& scope,
+ const UpdateCallback& callback) {
+ blocking_task_runner_->PostTask(
+ FROM_HERE,
+ base::Bind(&GCMStoreImpl::Backend::RemoveHeartbeatInterval,
+ backend_,
+ scope,
+ callback));
+}
+
void GCMStoreImpl::SetValueForTesting(const std::string& key,
const std::string& value,
const UpdateCallback& callback) {
« no previous file with comments | « google_apis/gcm/engine/gcm_store_impl.h ('k') | google_apis/gcm/engine/gcm_store_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698