blob: 93b9864f59b0c4aad91a703c6138f756f9e85798 [file]
// Copyright 2011 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.
// Implementation of the invalidation client library.
#ifndef GOOGLE_CACHEINVALIDATION_INVALIDATION_CLIENT_IMPL_H_
#define GOOGLE_CACHEINVALIDATION_INVALIDATION_CLIENT_IMPL_H_
#include <map>
#include <vector>
#include "google/cacheinvalidation/compiler-specific.h"
#include "google/cacheinvalidation/invalidation-client.h"
#include "google/cacheinvalidation/mutex.h"
#include "google/cacheinvalidation/network-manager.h"
#include "google/cacheinvalidation/persistence-manager.h"
#include "google/cacheinvalidation/persistence-utils.h"
#include "google/cacheinvalidation/random.h"
#include "google/cacheinvalidation/registration-update-manager.h"
#include "google/cacheinvalidation/scoped_ptr.h"
#include "google/cacheinvalidation/session-manager.h"
#include "google/cacheinvalidation/stl-namespace.h"
namespace invalidation {
using INVALIDATION_STL_NAMESPACE::map;
using INVALIDATION_STL_NAMESPACE::vector;
/**
* Implementation of the Invalidation Client Library (Ticl).
*/
class InvalidationClientImpl : public InvalidationClient, NetworkEndpoint {
public:
/* Constructs an InvalidationClientImpl with the given system resources,
* client type, and application name. It will deliver invalidations to
* the given listener.
*/
InvalidationClientImpl(SystemResources* resources,
const ClientType& client_type,
const string& app_name,
const string& client_info,
const ClientConfig& config,
InvalidationListener* listener);
static const char* INVALIDATE_ALL_OBJECT_NAME;
// Methods called by the application. ////////////////////////////////////////
// Inherited from InvalidationClient:
virtual void Start(const string& serialized_state);
virtual void Register(const ObjectId& oid);
virtual void Unregister(const ObjectId& oid);
virtual void PermanentShutdown();
virtual NetworkEndpoint* network_endpoint() {
return this;
}
virtual void GetClientUniquifier(string* uniquifier) {
CHECK(!resources_->IsRunningOnInternalThread());
MutexLock m(&lock_);
*uniquifier = session_manager_->client_uniquifier();
}
// Inherited from NetworkEndpoint:
virtual void TakeOutboundMessage(string* message);
virtual void HandleInboundMessage(const string& bundle);
virtual void AdviseNetworkStatus(bool online) {
CHECK(!resources_->IsRunningOnInternalThread());
}
virtual void RegisterOutboundListener(
NetworkCallback* outbound_message_ready);
RegState GetRegistrationStateForTest(const ObjectIdP& object_id) {
return registration_manager_->GetRegistrationState(object_id);
}
State GetRegistrationManagerStateForTest() {
return registration_manager_->GetStateForTest();
}
/**
* Generates a "smeared" delay. The returned smeared delay must be baseDelay
* +/- (baseDelay * smearFactor).
*/
// Visible for testing.
static TimeDelta SmearDelay(TimeDelta base_delay, double smear_factor,
Random* random);
private:
// Internal methods:
/* Persists a state blob that allocates config_.seqno_block_size sequence
* numbers. If the write is successful, reinitializes the registration
* manager with the new block of sequence numbers. This function manufactures
* a callback (to invoke HandleSeqnoWritebackResult), which it passes to the
* WriteState() function.
*/
void AllocateNewSequenceNumbers(const TiclState& persistent_state);
/* Handles the result of write performed on restart to allocate a new block of
* sequence numbers. If 'success' is false, the client forgets its persisted
* state and starts fresh; if it's true, the client is allowed to begin
* sending registration requests with sequence numbers up to the new maximum.
*/
void HandleSeqnoWritebackResult(int64 maximum_op_seqno, bool success);
/* Handles the result of a write performed on receipt of a new session. This
* write is best-effort, so 'success' is only used for logging.
*/
void HandleBestEffortWrite(bool success);
/* Checks for messages that need to be sent, operations to time out, etc. */
void PeriodicTask();
/* Handles a response from the server that involves getting a new session. */
void HandleNewSession();
/* Handles a lost-session event. */
void HandleLostSession();
/* Handles an OBJECT_CONTROL message. */
void HandleObjectControl(const ServerToClientMessage& bundle);
// Handlers for server-to-client messages. ///////////////////////////////////
/* Handles an invalidation. */
void ProcessInvalidation(const InvalidationP& invalidation);
/* Adds the given {@code invalidation} to the list of pending outgoing
* invalidations.
*/
void AcknowledgeInvalidation(const InvalidationP& invalidation);
/* Asynchronously adds the given {@code invalidation} to the list of pending
* outgoing invalidations.
*/
void ScheduleAcknowledgeInvalidation(const InvalidationP& invalidation);
/* Forgets any client id and session the client may currently have. */
void ForgetClientId();
/* Ensures that the client has been started. */
void EnsureStarted();
/* Various system resources needed by the Ticl (storage, CPU, logging). */
SystemResources* resources_;
/* Type of the client. */
const ClientType client_type_;
/* Application id of the client. */
const string app_name_;
/* The listener that will be notified of changes to objects. */
InvalidationListener* listener_;
/* Configuration parameters. */
ClientConfig config_;
/* Keeps track of pending and confirmed registrations. */
scoped_ptr<RegistrationUpdateManager> registration_manager_;
/* Manages push heartbeats and polling. */
NetworkManager network_manager_;
/* Manages client ids and session tokens. */
scoped_ptr<SessionManager> session_manager_;
/* Wraps resources_->WriteState() to ensure sequential access. */
PersistenceManager persistence_manager_;
/* Invalidation acknowledgments waiting to be delivered to the server. */
vector<InvalidationP> pending_invalidation_acks_;
/* Whether we're waiting for the initial seqno write-back to complete. While
* this is true, the Ticl will not accept any messages from the server, and it
* will not issue any registrations or inform the network listener that it has
* data to send.
*/
bool awaiting_seqno_writeback_;
/* Whether the client has been started. */
bool is_started_;
/* Random number generator for smearing periodic intervals. */
Random random_;
/* A lock to protect this object's state. */
Mutex lock_;
};
} // namespace invalidation
#endif // GOOGLE_CACHEINVALIDATION_INVALIDATION_CLIENT_IMPL_H_