| Index: third_party/cacheinvalidation/src/google/cacheinvalidation/impl/registration-manager.cc
|
| diff --git a/third_party/cacheinvalidation/src/google/cacheinvalidation/impl/registration-manager.cc b/third_party/cacheinvalidation/src/google/cacheinvalidation/impl/registration-manager.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..3e4574ef15aa4a3a53e3c1f19d8330b2892b9de5
|
| --- /dev/null
|
| +++ b/third_party/cacheinvalidation/src/google/cacheinvalidation/impl/registration-manager.cc
|
| @@ -0,0 +1,135 @@
|
| +// Copyright 2012 Google Inc.
|
| +//
|
| +// Licensed under the Apache License, Version 2.0 (the "License");
|
| +// you may not use this file except in compliance with the License.
|
| +// You may obtain a copy of the License at
|
| +//
|
| +// http://www.apache.org/licenses/LICENSE-2.0
|
| +//
|
| +// Unless required by applicable law or agreed to in writing, software
|
| +// distributed under the License is distributed on an "AS IS" BASIS,
|
| +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| +// See the License for the specific language governing permissions and
|
| +// limitations under the License.
|
| +
|
| +// Object to track desired client registrations. This class belongs to caller
|
| +// (e.g., InvalidationClientImpl) and is not thread-safe - the caller has to use
|
| +// this class in a thread-safe manner.
|
| +
|
| +#include "google/cacheinvalidation/impl/registration-manager.h"
|
| +
|
| +#include "google/cacheinvalidation/impl/client-protocol-namespace-fix.h"
|
| +#include "google/cacheinvalidation/impl/log-macro.h"
|
| +#include "google/cacheinvalidation/impl/proto-helpers.h"
|
| +#include "google/cacheinvalidation/impl/simple-registration-store.h"
|
| +
|
| +namespace invalidation {
|
| +
|
| +RegistrationManager::RegistrationManager(
|
| + Logger* logger, Statistics* statistics, DigestFunction* digest_function)
|
| + : desired_registrations_(new SimpleRegistrationStore(digest_function)),
|
| + statistics_(statistics),
|
| + logger_(logger) {
|
| + // Initialize the server summary with a 0 size and the digest corresponding to
|
| + // it. Using defaultInstance would wrong since the server digest will not
|
| + // match unnecessarily and result in an info message being sent.
|
| + GetClientSummary(&last_known_server_summary_);
|
| +}
|
| +
|
| +void RegistrationManager::PerformOperations(
|
| + const vector<ObjectIdP>& object_ids, RegistrationP::OpType reg_op_type,
|
| + vector<ObjectIdP>* oids_to_send) {
|
| + // Record that we have pending operations on the objects.
|
| + vector<ObjectIdP>::const_iterator iter = object_ids.begin();
|
| + for (; iter != object_ids.end(); iter++) {
|
| + pending_operations_[*iter] = reg_op_type;
|
| + }
|
| + // Update the digest appropriately.
|
| + if (reg_op_type == RegistrationP_OpType_REGISTER) {
|
| + desired_registrations_->Add(object_ids, oids_to_send);
|
| + } else {
|
| + desired_registrations_->Remove(object_ids, oids_to_send);
|
| + }
|
| +}
|
| +
|
| +void RegistrationManager::GetRegistrations(
|
| + const string& digest_prefix, int prefix_len, RegistrationSubtree* builder) {
|
| + vector<ObjectIdP> oids;
|
| + desired_registrations_->GetElements(digest_prefix, prefix_len, &oids);
|
| + for (size_t i = 0; i < oids.size(); ++i) {
|
| + builder->add_registered_object()->CopyFrom(oids[i]);
|
| + }
|
| +}
|
| +
|
| +void RegistrationManager::HandleRegistrationStatus(
|
| + const RepeatedPtrField<RegistrationStatus>& registration_statuses,
|
| + vector<bool>* success_status) {
|
| +
|
| + // Local-processing result code for each element of
|
| + // registrationStatuses. Indicates whether the registration status was
|
| + // compatible with the client's desired state (e.g., a successful unregister
|
| + // from the server when we desire a registration is incompatible).
|
| + for (int i = 0; i < registration_statuses.size(); ++i) {
|
| + const RegistrationStatus& registration_status =
|
| + registration_statuses.Get(i);
|
| + const ObjectIdP& object_id_proto =
|
| + registration_status.registration().object_id();
|
| +
|
| + // The object is no longer pending, since we have received a server status
|
| + // for it, so remove it from the pendingOperations map. (It may or may not
|
| + // have existed in the map, since we can receive spontaneous status messages
|
| + // from the server.)
|
| + pending_operations_.erase(object_id_proto);
|
| +
|
| + // We start off with the local-processing set as success, then potentially
|
| + // fail.
|
| + bool is_success = true;
|
| +
|
| + // if the server operation succeeded, then local processing fails on
|
| + // "incompatibility" as defined above.
|
| + if (registration_status.status().code() == StatusP_Code_SUCCESS) {
|
| + bool app_wants_registration =
|
| + desired_registrations_->Contains(object_id_proto);
|
| + bool is_op_registration =
|
| + (registration_status.registration().op_type() ==
|
| + RegistrationP_OpType_REGISTER);
|
| + bool discrepancy_exists = is_op_registration ^ app_wants_registration;
|
| + if (discrepancy_exists) {
|
| + // Remove the registration and set isSuccess to false, which will cause
|
| + // the caller to issue registration-failure to the application.
|
| + desired_registrations_->Remove(object_id_proto);
|
| + statistics_->RecordError(
|
| + Statistics::ClientErrorType_REGISTRATION_DISCREPANCY);
|
| + TLOG(logger_, INFO,
|
| + "Ticl discrepancy detected: registered = %d, requested = %d. "
|
| + "Removing %s from requested",
|
| + is_op_registration, app_wants_registration,
|
| + ProtoHelpers::ToString(object_id_proto).c_str());
|
| + is_success = false;
|
| + }
|
| + } else {
|
| + // If the server operation failed, then local processing also fails.
|
| + desired_registrations_->Remove(object_id_proto);
|
| + TLOG(logger_, FINE, "Removing %s from committed",
|
| + ProtoHelpers::ToString(object_id_proto).c_str());
|
| + is_success = false;
|
| + }
|
| + success_status->push_back(is_success);
|
| + }
|
| +}
|
| +
|
| +void RegistrationManager::GetClientSummary(RegistrationSummary* summary) {
|
| + summary->set_num_registrations(desired_registrations_->size());
|
| + summary->set_registration_digest(desired_registrations_->GetDigest());
|
| +}
|
| +
|
| +string RegistrationManager::ToString() {
|
| + return StringPrintf(
|
| + "Last known digest: %s, Requested regs: %s",
|
| + ProtoHelpers::ToString(last_known_server_summary_).c_str(),
|
| + desired_registrations_->ToString().c_str());
|
| +}
|
| +
|
| +const char* RegistrationManager::kEmptyPrefix = "";
|
| +
|
| +} // namespace invalidation
|
|
|