/*
 * 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.
 */

// Author: jmarantz@google.com (Joshua Marantz)

#ifndef PAGESPEED_SYSTEM_APR_MEM_CACHE_H_
#define PAGESPEED_SYSTEM_APR_MEM_CACHE_H_

#include <cstddef>
#include <vector>

#include "pagespeed/kernel/base/atomic_bool.h"
#include "pagespeed/kernel/base/basictypes.h"
#include "pagespeed/kernel/base/string.h"
#include "pagespeed/kernel/base/string_util.h"
#include "pagespeed/kernel/base/timer.h"
#include "pagespeed/kernel/cache/cache_interface.h"

struct apr_memcache2_t;
struct apr_memcache2_server_t;
struct apr_pool_t;

namespace net_instaweb {

class Hasher;
class MessageHandler;
class SharedString;
class Statistics;
class UpDownCounter;
class Variable;

// Interface to memcached via the apr_memcache2*, as documented in
// http://apr.apache.org/docs/apr-util/1.4/group___a_p_r___util___m_c.html.
//
// While this class derives from CacheInterface, it is a blocking
// implementation, suitable for instantiating underneath an AsyncCache.
class AprMemCache : public CacheInterface {
 public:
  // Experimentally it seems large values larger than 1M bytes result in
  // a failure, e.g. from load-tests:
  //     [Fri Jul 20 10:29:34 2012] [error] [mod_pagespeed 0.10.0.0-1699 @1522]
  //     AprMemCache::Put error: Internal error on key
  //     http://example.com/image.jpg, value-size 1393146
  // External to this class, we use a fallback cache (in Apache a FileCache) to
  // handle too-large requests.  This is managed by class FallbackCache in
  // ../util.
  static const size_t kValueSizeThreshold = 1 * 1000 * 1000;

  // Amount of time after a burst of errors to retry memcached operations.
  static const int64 kHealthCheckpointIntervalMs = 30 * Timer::kSecondMs;

  // Maximum number of errors tolerated within kHealthCheckpointIntervalMs,
  // after which AprMemCache will declare itself unhealthy for
  // kHealthCheckpointIntervalMs.
  static const int64 kMaxErrorBurst = 4;

  // servers is a comma-separated list of host[:port] where port defaults
  // to 11211, the memcached default.
  //
  // thread_limit is used to provide apr_memcache2_server_create with
  // a hard maximum number of client connections to open.
  AprMemCache(const StringPiece& servers, int thread_limit, Hasher* hasher,
              Statistics* statistics, Timer* timer, MessageHandler* handler);
  ~AprMemCache();

  static void InitStats(Statistics* statistics);

  const GoogleString& server_spec() const { return server_spec_; }

  // As mentioned above, Get and MultiGet are blocking in this implementation.
  virtual void Get(const GoogleString& key, Callback* callback);
  virtual void Put(const GoogleString& key, SharedString* value);
  virtual void Delete(const GoogleString& key);
  virtual void MultiGet(MultiGetRequest* request);

  // Connects to the server, returning whether the connection was
  // successful or not.
  bool Connect();

  bool valid_server_spec() const { return valid_server_spec_; }

  // Get detailed status in a string, returning false if the server
  // failed to return status.
  bool GetStatus(GoogleString* status_string);

  static GoogleString FormatName() { return "AprMemCache"; }
  virtual GoogleString Name() const { return FormatName(); }

  virtual bool IsBlocking() const { return true; }

  // Records in statistics that a system error occurred, helping it detect
  // when it's unhealthy if they are too frequent.
  void RecordError();

  // Determines whether memcached is healthy enough to attempt another
  // operation.  Note that even though there may be multiple shards,
  // some of which are healthy and some not, we don't currently track
  // errors on a per-shard basis, so we effectively declare all the
  // memcached instances unhealthy if any of them are.
  virtual bool IsHealthy() const;

  // Close down the connection to the memcached servers.
  virtual void ShutDown();

  virtual bool MustEncodeKeyInValueOnPut() const { return true; }
  virtual void PutWithKeyInValue(const GoogleString& key,
                                 SharedString* key_and_value);

  // Sets the I/O timeout in microseconds.  This should be called at
  // setup time and not while there are operations in flight.
  void set_timeout_us(int timeout_us);

 private:
  void DecodeValueMatchingKeyAndCallCallback(
      const GoogleString& key, const char* data, size_t data_len,
      const char* calling_method, Callback* callback);

  // Puts a value that's already encoded with the key into the cache, without
  // checking health first.  This is meant to be called from Put and
  // PutWithKeyInValue, which will do the health check.
  void PutHelper(const GoogleString& key, SharedString* key_and_value);

  StringVector hosts_;
  std::vector<int> ports_;
  GoogleString server_spec_;
  bool valid_server_spec_;
  int thread_limit_;
  int timeout_us_;
  apr_pool_t* pool_;
  apr_memcache2_t* memcached_;
  std::vector<apr_memcache2_server_t*> servers_;
  Hasher* hasher_;
  Timer* timer_;
  AtomicBool shutdown_;

  Variable* timeouts_;
  UpDownCounter* last_error_checkpoint_ms_;
  UpDownCounter* error_burst_size_;

  bool is_machine_local_;
  MessageHandler* message_handler_;

  // When memcached is killed, we will generate errors for every cache
  // operation.  To bound the amount of logging we do, we keep track
  // of the last time when we issued a log message for an APR failure.
  // We use a Statistic here for this so that it's shared across
  // Apache processes.
  //
  // Note that we have some messages indicating a potential functional issue on
  // (e.g. key collision) and a variety of places where we print messages
  // because the Apr routine failed.  We are grouping together Apr failures
  // for Get, Put, Delete, and MultiGet.  We might at some point wish to
  // track the last time we sent a message for each of those.
  Variable* last_apr_error_;

  DISALLOW_COPY_AND_ASSIGN(AprMemCache);
};

}  // namespace net_instaweb

#endif  // PAGESPEED_SYSTEM_APR_MEM_CACHE_H_
