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

Side by Side Diff: google_apis/gcm/engine/user_list.cc

Issue 135303002: Adding a user list (to be consumed by GCM Client Implementation) (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Updated the code with CR feedback, applied more asynch model. Created 6 years, 11 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "google_apis/gcm/engine/user_list.h"
6
7 #include "base/bind.h"
8 #include "base/files/file_path.h"
9 #include "base/location.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/message_loop/message_loop_proxy.h"
14 #include "base/sequenced_task_runner.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_piece.h"
17 #include "third_party/leveldatabase/src/include/leveldb/db.h"
18
19 namespace {
20 const int64 kSerialNumberMissing = -1;
21 } // namespace
22
23 namespace gcm {
24
25 UserList::UserInfo::UserInfo()
26 : serial_number(kSerialNumberMissing),
27 delegate(NULL) {
28 }
29
30 UserList::UserInfo::UserInfo(int64 serial_number)
31 : serial_number(serial_number),
32 delegate(NULL) {
33 }
34
35 UserList::UserInfo::UserInfo(GCMClient::Delegate* delegate,
36 const SetDelegateCallback callback)
37 : serial_number(kSerialNumberMissing),
38 delegate(delegate),
39 callback(callback) {
40 }
41
42 UserList::UserInfo::~UserInfo() {
43 }
44
45 UserList::UserList(GCMStore* gcm_store)
46 : initialized_(false),
47 next_serial_number_(kSerialNumberMissing),
48 gcm_store_(gcm_store) {
49 }
50
51 UserList::~UserList() {
52 }
53
54 void UserList::Initialize(const GCMStore::SerialNumberMappings& result) {
55 DCHECK(!initialized_);
56 DCHECK_GT(result.next_serial_number, 0);
57
58 next_serial_number_ = result.next_serial_number;
59 for (std::map<std::string, int64>::const_iterator iter =
60 result.user_serial_numbers.begin();
61 iter != result.user_serial_numbers.end();
62 ++iter) {
63 SetSerialNumber(iter->first, iter->second);
64 }
65 initialized_ = true;
66
67 for (UserInfoMap::iterator iter = delegates_.begin();
68 iter != delegates_.end();
69 ++iter) {
70 // Process only users with delegate and callback present.
71 if (iter->second.delegate && !iter->second.callback.is_null()) {
72 if (iter->second.serial_number == kSerialNumberMissing)
73 AssignSerialNumber(iter->first);
74 else
75 RespondWithSerialNumber(iter);
76 }
77 }
78 }
79
80 void UserList::SetDelegate(const std::string& username,
81 GCMClient::Delegate* delegate,
82 const SetDelegateCallback& callback) {
83 DCHECK(!username.empty());
84 DCHECK(delegate);
85
86 UserInfoMap::iterator iter = delegates_.find(username);
87 if (iter != delegates_.end()) {
88 DCHECK(initialized_);
89 DCHECK(!iter->second.delegate);
90 iter->second.delegate = delegate;
91 iter->second.callback = callback;
92 } else {
93 delegates_.insert(
94 iter,
95 UserInfoMap::value_type(username, UserInfo(delegate, callback)));
96 }
97
98 if (initialized_) {
99 UserInfoMap::iterator iter = delegates_.find(username);
100 if (iter->second.serial_number == kSerialNumberMissing)
101 AssignSerialNumber(iter->first);
102 else
103 RespondWithSerialNumber(iter);
104 }
105 }
106
107 void UserList::AssignSerialNumber(const std::string& username) {
108 DCHECK(initialized_);
109 DCHECK_EQ(delegates_.count(username), 1UL);
110 DCHECK_EQ(delegates_[username].serial_number, kSerialNumberMissing);
111
112 // Start by incrementing the |next_serial_number_| and persist it in the GCM
113 // store.
114 int64 serial_number = next_serial_number_++;
Nicolas Zea 2014/01/14 23:56:42 this needs to be pre-increment right?
fgorski 2014/01/15 01:29:21 next serial number is the next that is going to be
115 gcm_store_->SetNextSerialNumber(
116 serial_number,
117 base::Bind(&UserList::IncrementSerialNumberCompleted,
118 base::Unretained(this),
119 username,
120 serial_number));
121 }
122
123 void UserList::IncrementSerialNumberCompleted(const std::string& username,
124 int64 user_serial_number,
125 bool success) {
126 // TODO(fgorski): Introduce retry logic.
Nicolas Zea 2014/01/14 23:56:42 I don't know that we want to retry on persistence
fgorski 2014/01/15 01:29:21 So a DCHECK?
127 if (!success)
128 DCHECK(success) << "Updating the next serial number failed.";
129
130 SetSerialNumber(username, user_serial_number);
131 gcm_store_->AddUserSerialNumber(
Nicolas Zea 2014/01/14 23:56:42 should this and SetNextSerialNumber be combined in
fgorski 2014/01/15 01:29:21 We could consider that. (Separate patch though.)
132 username,
133 user_serial_number,
134 base::Bind(&UserList::AssignSerialNumberCompleted,
135 base::Unretained(this),
136 username));
137 }
138
139 void UserList::AssignSerialNumberCompleted(const std::string& username,
140 bool success) {
141 // TODO(fgorski): Introduce retry logic.
142 if (!success) {
143 DVLOG(1) << "It was not possible to persist username to serial number"
144 << " mapping for username: " << username;
Nicolas Zea 2014/01/14 23:56:42 Perhaps respond with a -1 or something?
fgorski 2014/01/15 01:29:21 I realized that the serial number part of the resp
145 return;
146 }
147
148 UserInfoMap::iterator iter = delegates_.find(username);
149 DCHECK(iter != delegates_.end());
150 RespondWithSerialNumber(iter);
151 }
152
153 void UserList::RespondWithSerialNumber(UserInfoMap::iterator& iter) {
154 base::MessageLoop::current()->PostTask(
155 FROM_HERE,
156 base::Bind(iter->second.callback,
157 iter->first,
158 iter->second.serial_number));
159 iter->second.callback.Reset();
160 }
161
162 void UserList::SetSerialNumber(const std::string& username,
163 int64 serial_number) {
164 DCHECK(!username.empty());
165 DCHECK_GT(serial_number, 0L);
166
167 UserInfoMap::iterator iter = delegates_.find(username);
168 if (iter != delegates_.end()) {
169 DCHECK_EQ(iter->second.serial_number, kSerialNumberMissing);
170 iter->second.serial_number = serial_number;
171 } else {
172 delegates_.insert(
173 iter, UserInfoMap::value_type(username, UserInfo(serial_number)));
174 }
175 }
176
177 GCMClient::Delegate* UserList::GetDelegateBySerialNumber(int64 serial_number)
178 const {
179 for (UserInfoMap::const_iterator iter = delegates_.begin();
180 iter != delegates_.end();
181 ++iter) {
182 if (iter->second.serial_number == serial_number)
183 return iter->second.delegate;
184 }
185 return NULL;
186 }
187
188 GCMClient::Delegate* UserList::GetDelegateByUsername(
189 const std::string& username) const {
190 UserInfoMap::const_iterator iter = delegates_.find(username);
191 if (iter != delegates_.end())
192 return iter->second.delegate;
193 return NULL;
jianli 2014/01/15 01:07:09 nit: return iter != delegates_.end() ? iter->secon
fgorski 2014/01/15 20:42:47 Done.
194 }
195
196 bool UserList::GetSerialNumberForUsername(const std::string& username,
197 int64* serial_number) const {
198 UserInfoMap::const_iterator iter = delegates_.find(username);
199 if (iter != delegates_.end() &&
200 iter->second.serial_number != kSerialNumberMissing) {
201 *serial_number = iter->second.serial_number;
202 return true;
203 }
204 *serial_number = kSerialNumberMissing;
205 return false;
206 }
207
208 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698