1137d5bcbSSteve Yen/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2137d5bcbSSteve Yen
34ba2e173SSteve Yen#ifndef CPROXY_H
44ba2e173SSteve Yen#define CPROXY_H
54ba2e173SSteve Yen
6ea4d0640SDustin Sallings#include "genhash.h"
74ba2e173SSteve Yen#include "work.h"
8af8bf580SSteve Yen#include "matcher.h"
90761324bSSteve Yen#include "mcs.h"
1007398270SSteve Yen#include "htgram.h"
114ba2e173SSteve Yen
12db427f17STrond Norbye/* From libmemcached. */
13db427f17STrond Norbye
14abef531aSSteve Yenuint32_t murmur_hash(const char *key, size_t length);
15abef531aSSteve Yen
16db427f17STrond Norbye/* ------------------------------- */
17139bef46SSteve Yen
18005a5e1aSSteve Yenint cproxy_init(char *cfg_str,
19005a5e1aSSteve Yen                char *behavior_str,
200b2bf826SSteve Yen                int nthreads,
210b2bf826SSteve Yen                struct event_base *main_base);
22052bcc36SSteve Yen
235b5b14f1SMatt Ingenthron#define CPROXY_NOT_CAS UINT64_MAX
248a1e4450SSteve Yen
256a26e91aSSteve Yenextern volatile uint64_t msec_current_time;
260b2bf826SSteve Yen
276b4a7e70SSteve Yenuint64_t usec_now(void);
286b4a7e70SSteve Yen
29db427f17STrond Norbyeextern char cproxy_hostname[300]; /* Immutable after init. */
30db427f17STrond Norbye
31db427f17STrond Norbye/* ------------------------------- */
32caae1590SSteve Yen
33db427f17STrond Norbye/* Special bucket name for the null bucket. */
344ba2e173SSteve Yen
351e0192d8SSteve Yen#define NULL_BUCKET "[ <NULL_BUCKET> ]"
361e0192d8SSteve Yen
37db427f17STrond Norbye/* Special bucket name that signifies that */
38db427f17STrond Norbye/* upstream connections start on the first */
39db427f17STrond Norbye/* configured bucket. */
40db427f17STrond Norbye
411e0192d8SSteve Yen#define FIRST_BUCKET "[ <FIRST_BUCKET> ]"
421e0192d8SSteve Yen
43db427f17STrond Norbye/* ------------------------------- */
441e0192d8SSteve Yen
45aa9f46b9SSteve Yentypedef struct {
46a4eaead9SSteve Yen    char *(*item_key)(void *it);
47a4eaead9SSteve Yen    int   (*item_key_len)(void *it);
48a4eaead9SSteve Yen    int   (*item_len)(void *it);
49a4eaead9SSteve Yen    void  (*item_add_ref)(void *it);
50a4eaead9SSteve Yen    void  (*item_dec_ref)(void *it);
51a4eaead9SSteve Yen    void *(*item_get_next)(void *it);
52a4eaead9SSteve Yen    void  (*item_set_next)(void *it, void *next);
53a4eaead9SSteve Yen    void *(*item_get_prev)(void *it);
54a4eaead9SSteve Yen    void  (*item_set_prev)(void *it, void *prev);
556a26e91aSSteve Yen    uint64_t (*item_get_exptime)(void *it);
566a26e91aSSteve Yen    void     (*item_set_exptime)(void *it, uint64_t exptime);
57a4eaead9SSteve Yen} mcache_funcs;
58a4eaead9SSteve Yen
59a4eaead9SSteve Yenextern mcache_funcs mcache_item_funcs;
60c2da5f79SSteve Yenextern mcache_funcs mcache_key_stats_funcs;
61a4eaead9SSteve Yen
62a4eaead9SSteve Yentypedef struct {
63a4eaead9SSteve Yen    mcache_funcs *funcs;
64a4eaead9SSteve Yen
657d4ff237STrond Norbye    cb_mutex_t *lock; /* NULL-able, for non-multithreaded. */
66aa9f46b9SSteve Yen
67db427f17STrond Norbye    bool key_alloc;        /* True if mcache must alloc key memory. */
68ac8ee0cdSSteve Yen
69db427f17STrond Norbye    genhash_t *map;        /* NULL-able, keyed by string, value is item. */
706b4e51cdSSteve Yen
71db427f17STrond Norbye    uint32_t max;          /* Maxiumum number of items to keep. */
72640002e8SSteve Yen
73db427f17STrond Norbye    void *lru_head;        /* Most recently used. */
74db427f17STrond Norbye    void *lru_tail;        /* Least recently used. */
75640002e8SSteve Yen
76db427f17STrond Norbye    uint32_t oldest_live;  /* In millisecs, relative to msec_current_time. */
77db427f17STrond Norbye
78db427f17STrond Norbye    /* Statistics. */
79ce834644SSteve Yen
80ce834644SSteve Yen    uint64_t tot_get_hits;
81ce834644SSteve Yen    uint64_t tot_get_expires;
82ce834644SSteve Yen    uint64_t tot_get_misses;
833c84d654SSteve Yen    uint64_t tot_get_bytes;
84ce834644SSteve Yen    uint64_t tot_adds;
85ce834644SSteve Yen    uint64_t tot_add_skips;
860687f612SSteve Yen    uint64_t tot_add_fails;
873c84d654SSteve Yen    uint64_t tot_add_bytes;
880687f612SSteve Yen    uint64_t tot_deletes;
89640002e8SSteve Yen    uint64_t tot_evictions;
90aa9f46b9SSteve Yen} mcache;
91aa9f46b9SSteve Yen
9216be84f5SSteve Yentypedef struct proxy               proxy;
9316be84f5SSteve Yentypedef struct proxy_td            proxy_td;
9416be84f5SSteve Yentypedef struct proxy_main          proxy_main;
9516be84f5SSteve Yentypedef struct proxy_stats         proxy_stats;
9616be84f5SSteve Yentypedef struct proxy_behavior      proxy_behavior;
9716be84f5SSteve Yentypedef struct proxy_behavior_pool proxy_behavior_pool;
9816be84f5SSteve Yentypedef struct downstream          downstream;
9916be84f5SSteve Yentypedef struct key_stats           key_stats;
10044353a55SSteve Yen
10144353a55SSteve Yenstruct proxy_behavior {
102db427f17STrond Norbye    /* IL means startup, system initialization level behavior. */
103db427f17STrond Norbye    /* ML means proxy/pool manager-level behavior (proxy_main). */
104db427f17STrond Norbye    /* PL means proxy/pool-level behavior. */
105db427f17STrond Norbye    /* SL means server-level behavior, although we inherit from proxy level. */
106db427f17STrond Norbye
107db427f17STrond Norbye    uint32_t       cycle;               /* IL: Clock resolution in millisecs. */
108db427f17STrond Norbye    uint32_t       downstream_max;      /* PL: Downstream concurrency. */
109db427f17STrond Norbye    uint32_t       downstream_conn_max; /* PL: Max # of conns per thread */
110db427f17STrond Norbye                                        /* and per host_ident. */
111db427f17STrond Norbye    uint32_t       downstream_weight;   /* SL: Server weight. */
112db427f17STrond Norbye    uint32_t       downstream_retry;    /* SL: How many times to retry a cmd. */
113db427f17STrond Norbye    enum protocol  downstream_protocol; /* SL: Favored downstream protocol. */
114db427f17STrond Norbye    struct timeval downstream_timeout;  /* SL: Fields of 0 mean no timeout. */
115db427f17STrond Norbye    struct timeval downstream_conn_queue_timeout; /* SL: Fields of 0 mean no timeout. */
116db427f17STrond Norbye    struct timeval wait_queue_timeout;  /* PL: Fields of 0 mean no timeout. */
117db427f17STrond Norbye    struct timeval connect_timeout;     /* PL: Fields of 0 mean no timeout. */
118db427f17STrond Norbye    struct timeval auth_timeout;        /* PL: Fields of 0 mean no timeout. */
119db427f17STrond Norbye    bool           time_stats;          /* IL: Capture timing stats. */
120db427f17STrond Norbye    char           mcs_opts[80];        /* PL: Extra options for mcs initialization. */
121db427f17STrond Norbye
122db427f17STrond Norbye    uint32_t connect_max_errors;      /* IL: Pause when too many connect() errs. */
123db427f17STrond Norbye    uint32_t connect_retry_interval;  /* IL: Time in millisecs before retrying */
124db427f17STrond Norbye                                      /* when too many connect() errors, to not */
125db427f17STrond Norbye                                      /* overwhelm the downstream servers. */
126db427f17STrond Norbye
127db427f17STrond Norbye    uint32_t front_cache_max;         /* PL: Max # of front cachable items. */
128db427f17STrond Norbye    uint32_t front_cache_lifespan;    /* PL: In millisecs. */
129db427f17STrond Norbye    char     front_cache_spec[300];   /* PL: Matcher prefixes for front caching. */
130db427f17STrond Norbye    char     front_cache_unspec[100]; /* PL: Don't front cache prefixes. */
131db427f17STrond Norbye
132db427f17STrond Norbye    uint32_t key_stats_max;         /* PL: Max # of key stats entries. */
133db427f17STrond Norbye    uint32_t key_stats_lifespan;    /* PL: In millisecs. */
134db427f17STrond Norbye    char     key_stats_spec[300];   /* PL: Matcher prefixes for key-level stats. */
135db427f17STrond Norbye    char     key_stats_unspec[100]; /* PL: Don't key stat prefixes. */
136db427f17STrond Norbye
137db427f17STrond Norbye    char optimize_set[400]; /* PL: Matcher prefixes for SET optimization. */
138db427f17STrond Norbye
139db427f17STrond Norbye    char usr[250];    /* SL. */
140db427f17STrond Norbye    char pwd[900];    /* SL. */
141db427f17STrond Norbye    char host[250];   /* SL. */
142db427f17STrond Norbye    int  port;        /* SL. */
143db427f17STrond Norbye    char bucket[250]; /* SL. */
144db427f17STrond Norbye    char nodeLocator[20]; /* Ex: ketama or vbucket. */
145db427f17STrond Norbye
146db427f17STrond Norbye    /* ML: Port for proxy_main to listen on. */
147db427f17STrond Norbye
148f93e1b3bSSteve Yen    int port_listen;
149eeb61742SSteve Yen
150db427f17STrond Norbye    char default_bucket_name[250]; /* ML: The named bucket (proxy->name) */
151db427f17STrond Norbye                                   /* that upstream conn's should start on. */
152db427f17STrond Norbye                                   /* When empty (""), then only binary SASL */
153db427f17STrond Norbye                                   /* clients can actually do anything useful. */
15444353a55SSteve Yen};
1554ba2e173SSteve Yen
1564c39a918SSteve Yenproxy_behavior behavior_default_g;
1574c39a918SSteve Yen
15816be84f5SSteve Yenstruct proxy_behavior_pool {
159db427f17STrond Norbye    proxy_behavior  base; /* Proxy pool-level (PL) behavior. */
160db427f17STrond Norbye    int             num;  /* Number of server-level (SL) behaviors. */
161db427f17STrond Norbye    proxy_behavior *arr;  /* Array, size is num. */
16216be84f5SSteve Yen};
16316be84f5SSteve Yen
164f4d35310SJoon(JunHyun Park)typedef enum {
165f4d35310SJoon(JunHyun Park)    PROXY_CONF_TYPE_STATIC = 0,
166f4d35310SJoon(JunHyun Park)    PROXY_CONF_TYPE_DYNAMIC,
167f4d35310SJoon(JunHyun Park)    PROXY_CONF_TYPE_last
168f4d35310SJoon(JunHyun Park)} enum_proxy_conf_type;
169f4d35310SJoon(JunHyun Park)
170db427f17STrond Norbye/* Quick map of struct hierarchy... */
171db427f17STrond Norbye
172db427f17STrond Norbye/* proxy_main */
173db427f17STrond Norbye/*  - has list of... */
174db427f17STrond Norbye/*    proxy */
175db427f17STrond Norbye/*     - has array of... */
176db427f17STrond Norbye/*       proxy_td (one proxy_td per worker thread) */
177db427f17STrond Norbye/*       - has list of... */
178db427f17STrond Norbye/*         downstream (in either reserved or released list) */
179db427f17STrond Norbye/*         - has mst/libmemcached struct */
180db427f17STrond Norbye/*         - has array of downstream conn's */
181db427f17STrond Norbye/*         - has non-NULL upstream conn, when reserved */
1820761324bSSteve Yen
183c198dc0eSSteve Yen/* Structure used and owned by main listener thread to
184c198dc0eSSteve Yen * track all the outstanding proxy objects.
1854ba2e173SSteve Yen */
1864ba2e173SSteve Yenstruct proxy_main {
187db427f17STrond Norbye    proxy_behavior behavior; /* Default, main listener modifiable only. */
188db427f17STrond Norbye
189db427f17STrond Norbye    enum_proxy_conf_type conf_type; /* Immutable proxy configuration type. */
1904ba2e173SSteve Yen
191db427f17STrond Norbye    /* Any thread that accesses the proxy list must */
192db427f17STrond Norbye    /* first acquire the proxy_main_lock. */
193f4d35310SJoon(JunHyun Park)
1947d4ff237STrond Norbye    cb_mutex_t proxy_main_lock;
195f4d35310SJoon(JunHyun Park)
196db427f17STrond Norbye    /* Start of proxy list.  Covered by proxy_main_lock. */
197db427f17STrond Norbye    /* Only the main listener thread may modify the proxy list. */
198db427f17STrond Norbye    /* Other threads may read-only traverse the proxy list. */
199db427f17STrond Norbye
2004ba2e173SSteve Yen    proxy *proxy_head;
201c449413bSSteve Yen
202db427f17STrond Norbye    int nthreads; /* Immutable. */
203db427f17STrond Norbye
204db427f17STrond Norbye    /* Updated by main listener thread only, */
205db427f17STrond Norbye    /* so no extra locking needed. */
2068a7e4b6dSSteve Yen
207ace6e98dSSteve Yen    uint64_t stat_configs;
208ace6e98dSSteve Yen    uint64_t stat_config_fails;
209ace6e98dSSteve Yen    uint64_t stat_proxy_starts;
210ace6e98dSSteve Yen    uint64_t stat_proxy_start_fails;
211ace6e98dSSteve Yen    uint64_t stat_proxy_existings;
212ace6e98dSSteve Yen    uint64_t stat_proxy_shutdowns;
2134ba2e173SSteve Yen};
2144ba2e173SSteve Yen
2154ba2e173SSteve Yen/* Owned by main listener thread.
2164ba2e173SSteve Yen */
2174ba2e173SSteve Yenstruct proxy {
218db427f17STrond Norbye    proxy_main *main; /* Immutable, points to parent proxy_main. */
2192bebd7a9SSteve Yen
220db427f17STrond Norbye    int   port;   /* Immutable. */
221db427f17STrond Norbye    char *name;   /* Mutable, covered by proxy_lock, for debugging, NULL-able. */
222db427f17STrond Norbye    char *config; /* Mutable, covered by proxy_lock, mem owned by proxy, */
223db427f17STrond Norbye                  /* might be NULL if the proxy is shutting down. */
224db427f17STrond Norbye
225db427f17STrond Norbye    /* Mutable, covered by proxy_lock, incremented */
226db427f17STrond Norbye    /* whenever config changes. */
227da4d206eSSteve Yen
228da4d206eSSteve Yen    uint32_t config_ver;
2294ba2e173SSteve Yen
230db427f17STrond Norbye    /* Mutable, covered by proxy_lock. */
231db427f17STrond Norbye
23216be84f5SSteve Yen    proxy_behavior_pool behavior_pool;
233005a5e1aSSteve Yen
234db427f17STrond Norbye    /* Any thread that accesses the mutable fields should */
235db427f17STrond Norbye    /* first acquire the proxy_lock. */
236db427f17STrond Norbye
2377d4ff237STrond Norbye    cb_mutex_t proxy_lock;
2384ba2e173SSteve Yen
239db427f17STrond Norbye    /* Number of listening conn's acting as a proxy, */
240db427f17STrond Norbye    /* where (((proxy *) conn->extra) == this). */
241db427f17STrond Norbye    /* Modified/accessed only by main listener thread. */
242db427f17STrond Norbye
24362591117SSteve Yen    uint64_t listening;
244db427f17STrond Norbye    uint64_t listening_failed; /* When server_socket() failed. */
2454ba2e173SSteve Yen
246db427f17STrond Norbye    proxy *next; /* Modified/accessed only by main listener thread. */
2474ba2e173SSteve Yen
24866b74002SSteve Yen    mcache  front_cache;
24966b74002SSteve Yen    matcher front_cache_matcher;
25030e7a4a2SSteve Yen    matcher front_cache_unmatcher;
251a49bb8afSSteve Yen
25259719968SSteve Yen    matcher optimize_set_matcher;
25359719968SSteve Yen
254db427f17STrond Norbye    proxy_td *thread_data;     /* Immutable. */
255db427f17STrond Norbye    int       thread_data_num; /* Immutable. */
2564ba2e173SSteve Yen};
2574ba2e173SSteve Yen
2584ba2e173SSteve Yenstruct proxy_stats {
259db427f17STrond Norbye    /* Naming convention is that num_xxx's go up and down, */
260db427f17STrond Norbye    /* while tot_xxx's and err_xxx's only increase.  Only */
261db427f17STrond Norbye    /* the tot_xxx's and err_xxx's can be reset to 0. */
262db427f17STrond Norbye
263db427f17STrond Norbye    uint64_t num_upstream; /* Current # of upstreams conns using this proxy. */
264db427f17STrond Norbye    uint64_t tot_upstream; /* Total # upstream conns that used this proxy. */
2654ba2e173SSteve Yen
26662591117SSteve Yen    uint64_t num_downstream_conn;
26762591117SSteve Yen    uint64_t tot_downstream_conn;
26853c72691SSteve Yen    uint64_t tot_downstream_conn_acquired;
26953c72691SSteve Yen    uint64_t tot_downstream_conn_released;
2704ba2e173SSteve Yen    uint64_t tot_downstream_released;
2714ba2e173SSteve Yen    uint64_t tot_downstream_reserved;
2726b4a7e70SSteve Yen    uint64_t tot_downstream_reserved_time;
27329e719f0SSteve Yen    uint64_t max_downstream_reserved_time;
274be29f307SSteve Yen    uint64_t tot_downstream_freed;
27562591117SSteve Yen    uint64_t tot_downstream_quit_server;
27662591117SSteve Yen    uint64_t tot_downstream_max_reached;
277be29f307SSteve Yen    uint64_t tot_downstream_create_failed;
278c93a38e2SSteve Yen
279db427f17STrond Norbye    /* When connections have stabilized... */
280db427f17STrond Norbye    /*   tot_downstream_connect_started == */
281db427f17STrond Norbye    /*     tot_downstream_connect + tot_downstream_connect_failed. */
282db427f17STrond Norbye
283db427f17STrond Norbye    /* When a new connection is just created but not yet ready for use... */
284db427f17STrond Norbye    /*   tot_downstream_connect_started > */
285db427f17STrond Norbye    /*     tot_downstream_connect + tot_downstream_connect_failed. */
286db427f17STrond Norbye
287c93a38e2SSteve Yen    uint64_t tot_downstream_connect_started;
288c8b41bb0SSteve Yen    uint64_t tot_downstream_connect_wait;
289db427f17STrond Norbye    uint64_t tot_downstream_connect; /* Incremented when connect() + auth + */
290db427f17STrond Norbye                                     /* bucket_selection succeeds. */
29130102044SSteve Yen    uint64_t tot_downstream_connect_failed;
2925b2c1e3aSSteve Yen    uint64_t tot_downstream_connect_timeout;
2935b2c1e3aSSteve Yen    uint64_t tot_downstream_connect_interval;
2945b2c1e3aSSteve Yen    uint64_t tot_downstream_connect_max_reached;
295c93a38e2SSteve Yen
2965b2c1e3aSSteve Yen    uint64_t tot_downstream_waiting_errors;
29730102044SSteve Yen    uint64_t tot_downstream_auth;
29830102044SSteve Yen    uint64_t tot_downstream_auth_failed;
29930102044SSteve Yen    uint64_t tot_downstream_bucket;
30030102044SSteve Yen    uint64_t tot_downstream_bucket_failed;
3018d744532SSteve Yen    uint64_t tot_downstream_propagate_failed;
30290fdea80SSteve Yen    uint64_t tot_downstream_close_on_upstream_close;
303026a9b78SSteve Yen    uint64_t tot_downstream_conn_queue_timeout;
3044270fcc5SSteve Yen    uint64_t tot_downstream_conn_queue_add;
3054270fcc5SSteve Yen    uint64_t tot_downstream_conn_queue_remove;
3068d744532SSteve Yen    uint64_t tot_downstream_timeout;
3078d744532SSteve Yen    uint64_t tot_wait_queue_timeout;
308646bff3dSSteve Yen    uint64_t tot_auth_timeout;
309be29f307SSteve Yen    uint64_t tot_assign_downstream;
310be29f307SSteve Yen    uint64_t tot_assign_upstream;
3118d744532SSteve Yen    uint64_t tot_assign_recursion;
312be29f307SSteve Yen    uint64_t tot_reset_upstream_avail;
31362591117SSteve Yen    uint64_t tot_retry;
3146b4a7e70SSteve Yen    uint64_t tot_retry_time;
3159e23e48fSSteve Yen    uint64_t max_retry_time;
316498dc881SSteve Yen    uint64_t tot_retry_vbucket;
317498dc881SSteve Yen    uint64_t tot_upstream_paused;
318498dc881SSteve Yen    uint64_t tot_upstream_unpaused;
319ee5cacf7SSteve Yen    uint64_t tot_multiget_keys;
320ee5cacf7SSteve Yen    uint64_t tot_multiget_keys_dedupe;
321b5e50f9eSSteve Yen    uint64_t tot_multiget_bytes_dedupe;
3225d99f3adSSteve Yen    uint64_t tot_optimize_sets;
323dac445fbSSteve Yen    uint64_t err_oom;
32447c58bd9SSteve Yen    uint64_t err_upstream_write_prep;
3252f11722aSSteve Yen    uint64_t err_downstream_write_prep;
3262dc6f3e4SAliaksey Kandratsenka    uint64_t tot_cmd_time;
3272dc6f3e4SAliaksey Kandratsenka    uint64_t tot_cmd_count;
3282dc6f3e4SAliaksey Kandratsenka    uint64_t tot_local_cmd_time;
3292dc6f3e4SAliaksey Kandratsenka    uint64_t tot_local_cmd_count;
3304ba2e173SSteve Yen};
3314ba2e173SSteve Yen
3321de95aacSSteve Yentypedef struct {
333db427f17STrond Norbye    uint64_t seen;        /* Number of times a command was seen. */
334db427f17STrond Norbye    uint64_t hits;        /* Number of hits or successes. */
335db427f17STrond Norbye    uint64_t misses;      /* Number of misses or failures. */
336db427f17STrond Norbye    uint64_t read_bytes;  /* Total bytes read, incoming into proxy. */
337db427f17STrond Norbye    uint64_t write_bytes; /* Total bytes written, outgoing from proxy. */
338db427f17STrond Norbye    uint64_t cas;         /* Number that had or required cas-id. */
3391de95aacSSteve Yen} proxy_stats_cmd;
3401de95aacSSteve Yen
3411de95aacSSteve Yentypedef enum {
342db427f17STrond Norbye    STATS_CMD_GET = 0, /* For each "get" cmd, even if multikey get. */
343db427f17STrond Norbye    STATS_CMD_GET_KEY, /* For each key in a "get". */
3441de95aacSSteve Yen    STATS_CMD_SET,
3451de95aacSSteve Yen    STATS_CMD_ADD,
3461de95aacSSteve Yen    STATS_CMD_REPLACE,
3471de95aacSSteve Yen    STATS_CMD_DELETE,
3481de95aacSSteve Yen    STATS_CMD_APPEND,
3491de95aacSSteve Yen    STATS_CMD_PREPEND,
3501de95aacSSteve Yen    STATS_CMD_INCR,
3511de95aacSSteve Yen    STATS_CMD_DECR,
3521de95aacSSteve Yen    STATS_CMD_FLUSH_ALL,
3531de95aacSSteve Yen    STATS_CMD_CAS,
354f0088767SSteve Yen    STATS_CMD_STATS,
355f0088767SSteve Yen    STATS_CMD_STATS_RESET,
356f0088767SSteve Yen    STATS_CMD_VERSION,
357f0088767SSteve Yen    STATS_CMD_VERBOSITY,
358f0088767SSteve Yen    STATS_CMD_QUIT,
3595a7e4a19SManik Taneja    STATS_CMD_GETL,
360fd7b5c09SManik Taneja    STATS_CMD_UNL,
361f0088767SSteve Yen    STATS_CMD_ERROR,
3621de95aacSSteve Yen    STATS_CMD_last
3631de95aacSSteve Yen} enum_stats_cmd;
3641de95aacSSteve Yen
3651de95aacSSteve Yentypedef enum {
3661de95aacSSteve Yen    STATS_CMD_TYPE_REGULAR = 0,
3671de95aacSSteve Yen    STATS_CMD_TYPE_QUIET,
3681de95aacSSteve Yen    STATS_CMD_TYPE_last
3691de95aacSSteve Yen} enum_stats_cmd_type;
3701de95aacSSteve Yen
3711de95aacSSteve Yentypedef struct {
3721de95aacSSteve Yen    proxy_stats     stats;
3731de95aacSSteve Yen    proxy_stats_cmd stats_cmd[STATS_CMD_TYPE_last][STATS_CMD_last];
37407398270SSteve Yen
37507398270SSteve Yen    HTGRAM_HANDLE downstream_reserved_time_htgram;
37683361a6bSSteve Yen    HTGRAM_HANDLE downstream_connect_time_htgram;
3771de95aacSSteve Yen} proxy_stats_td;
3781de95aacSSteve Yen
37944ffe47aSSteve Yenstruct key_stats {
38044ffe47aSSteve Yen    char key[KEY_MAX_LENGTH + 1];
38144ffe47aSSteve Yen    int  refcount;
3826a26e91aSSteve Yen    uint64_t exptime;
3836a26e91aSSteve Yen    uint64_t added_at;
38444ffe47aSSteve Yen    key_stats *next;
38544ffe47aSSteve Yen    key_stats *prev;
38644ffe47aSSteve Yen    proxy_stats_cmd stats_cmd[STATS_CMD_TYPE_last][STATS_CMD_last];
38744ffe47aSSteve Yen};
38844ffe47aSSteve Yen
389d4655aeeSSteve Yen/* We mirror memcached's threading model with a separate
390d4655aeeSSteve Yen * proxy_td (td means "thread data") struct owned by each
391d4655aeeSSteve Yen * worker thread.  The idea is to avoid extraneous locks.
3924ba2e173SSteve Yen */
393db427f17STrond Norbyestruct proxy_td { /* Per proxy, per worker-thread data struct. */
394db427f17STrond Norbye    proxy *proxy; /* Immutable parent pointer. */
395db427f17STrond Norbye
396db427f17STrond Norbye    /* Snapshot of proxy-level configuration to avoid locks. */
3974ba2e173SSteve Yen
39888ab7dbeSSteve Yen    char    *config;
39988ab7dbeSSteve Yen    uint32_t config_ver;
40088ab7dbeSSteve Yen
40116be84f5SSteve Yen    proxy_behavior_pool behavior_pool;
40288ab7dbeSSteve Yen
403db427f17STrond Norbye    /* Upstream conns that are paused, waiting for */
404db427f17STrond Norbye    /* an available, released downstream. */
405db427f17STrond Norbye
40633f8cad1SSteve Yen    conn *waiting_any_downstream_head;
40733f8cad1SSteve Yen    conn *waiting_any_downstream_tail;
4084ba2e173SSteve Yen
409db427f17STrond Norbye    downstream *downstream_reserved; /* Downstreams assigned to upstream conns. */
410db427f17STrond Norbye    downstream *downstream_released; /* Downstreams unassigned to upstreams conn. */
411db427f17STrond Norbye    uint64_t    downstream_tot;      /* Total lifetime downstreams created. */
412db427f17STrond Norbye    int         downstream_num;      /* Number downstreams existing. */
413db427f17STrond Norbye    int         downstream_max;      /* Max downstream concurrency number. */
414db427f17STrond Norbye    uint64_t    downstream_assigns;  /* Track recursion. */
415db427f17STrond Norbye
416db427f17STrond Norbye    /* A timeout for the wait_queue, so that we can emit error */
417db427f17STrond Norbye    /* on any upstream conn's that are waiting too long for */
418db427f17STrond Norbye    /* an available downstream. */
419db427f17STrond Norbye
420db427f17STrond Norbye    /* Timeout is in use when timeout_tv fields are non-zero. */
421db427f17STrond Norbye
422ac7b45afSSteve Yen    struct timeval timeout_tv;
423ac7b45afSSteve Yen    struct event   timeout_event;
424ac7b45afSSteve Yen
42544ffe47aSSteve Yen    mcache  key_stats;
42644ffe47aSSteve Yen    matcher key_stats_matcher;
42744ffe47aSSteve Yen    matcher key_stats_unmatcher;
4284ba2e173SSteve Yen
42944ffe47aSSteve Yen    proxy_stats_td stats;
430c2da5f79SSteve Yen};
431c2da5f79SSteve Yen
432fd2c7018SSteve Yen/* A 'downstream' struct represents a set of downstream connections.
433fd2c7018SSteve Yen * A possibly better name for it should have been "downstream_conn_set".
434fd2c7018SSteve Yen *
435fd2c7018SSteve Yen * Owned by worker thread.
4364ba2e173SSteve Yen */
4374ba2e173SSteve Yenstruct downstream {
438db427f17STrond Norbye    /* The following group of fields are immutable or read-only (RO), */
439db427f17STrond Norbye    /* except for config_ver, which gets updated if the downstream's */
440db427f17STrond Norbye    /* config/behaviors still matches the parent ptd's config/behaviors. */
441db427f17STrond Norbye
442db427f17STrond Norbye    proxy_td       *ptd;           /* RO: Parent pointer. */
443db427f17STrond Norbye    char           *config;        /* RO: Mem owned by downstream. */
444db427f17STrond Norbye    uint32_t        config_ver;    /* RW: Mutable, copy of proxy->config_ver. */
445db427f17STrond Norbye    int             behaviors_num; /* RO: Snapshot of ptd->behavior_pool.num. */
446db427f17STrond Norbye    proxy_behavior *behaviors_arr; /* RO: Snapshot of ptd->behavior_pool.arr. */
447db427f17STrond Norbye    mcs_st          mst;           /* RW: From mcs. */
448db427f17STrond Norbye
449db427f17STrond Norbye    downstream *next; /* To track reserved/released lists. */
450db427f17STrond Norbye                      /* See ptd->downstream_reserved/downstream_released. */
451db427f17STrond Norbye
452db427f17STrond Norbye    downstream *next_waiting; /* To track lists when a downstream is reserved, */
453db427f17STrond Norbye                              /* but is waiting for a downstream connection, */
454db427f17STrond Norbye                              /* per zstored perf enhancement. */
455db427f17STrond Norbye
456db427f17STrond Norbye    conn **downstream_conns;  /* Wraps the fd's of mst with conns. */
457db427f17STrond Norbye    int    downstream_used;   /* Number of in-use downstream conns, might */
458db427f17STrond Norbye                              /* be >1 during scatter-gather commands. */
459d35fcd6cSSteve Yen    int    downstream_used_start;
4606b4a7e70SSteve Yen
461db427f17STrond Norbye    uint64_t usec_start; /* Snapshot of usec_now(). */
4626b4a7e70SSteve Yen
463db427f17STrond Norbye    conn  *upstream_conn;     /* Non-NULL when downstream is reserved. */
464db427f17STrond Norbye    char  *upstream_suffix;   /* Last bit to write when downstreams are done. */
465db427f17STrond Norbye    int    upstream_suffix_len; /* When > 0, overrides strlen(upstream_suffix), */
466db427f17STrond Norbye                                /* during binary protocol. */
4675fa3a334SSteve Yen
468db427f17STrond Norbye    /* Used during an error when upstream is binary protocol. */
4695fa3a334SSteve Yen    protocol_binary_response_status upstream_status;
4705fa3a334SSteve Yen
471db427f17STrond Norbye    int    upstream_retry;    /* Will be >0 if we should retry the entire */
472db427f17STrond Norbye                              /* command again when all downstreams are done. */
473db427f17STrond Norbye                              /* Used in not-my-vbucket error case.  During */
474db427f17STrond Norbye                              /* the retry, we'll reuse the same multiget */
475db427f17STrond Norbye                              /* de-duplication tracking table to avoid */
476db427f17STrond Norbye                              /* asking for successful keys again. */
477db427f17STrond Norbye    int    upstream_retries;  /* Count number of upstream_retry attempts. */
478146c5cb5SSteve Yen
479db427f17STrond Norbye    /* Used when proxying a simple, single-key (non-broadcast) command. */
4800745b38dSSteve Yen    char *target_host_ident;
4810745b38dSSteve Yen
482db427f17STrond Norbye    genhash_t *multiget; /* Keyed by string. */
483db427f17STrond Norbye    genhash_t *merger;   /* Keyed by string, for merging replies like STATS. */
484db427f17STrond Norbye
485db427f17STrond Norbye    /* Timeout is in use when timeout_tv fields are non-zero. */
486b9949368SSteve Yen
487b9949368SSteve Yen    struct timeval timeout_tv;
488b9949368SSteve Yen    struct event   timeout_event;
4894ba2e173SSteve Yen};
4904ba2e173SSteve Yen
491db427f17STrond Norbye/* Sentinel value for downstream->downstream_conns[] array entries, */
492db427f17STrond Norbye/* which usually signals that moxi wasn't able to create a connection */
493db427f17STrond Norbye/* to a downstream server. */
494db427f17STrond Norbye
4958a09afddSSteve Yen#define NULL_CONN ((conn *) -1)
4968a09afddSSteve Yen
497db427f17STrond Norbye/* Functions. */
498db427f17STrond Norbye
4992bebd7a9SSteve Yenproxy *cproxy_create(proxy_main *main,
5002bebd7a9SSteve Yen                     char    *name,
50116be84f5SSteve Yen                     int      port,
50216be84f5SSteve Yen                     char    *config,
50316be84f5SSteve Yen                     uint32_t config_ver,
50416be84f5SSteve Yen                     proxy_behavior_pool *behavior_pool,
5058a7e4b6dSSteve Yen                     int nthreads);
506dd39956cSSteve Yen
507ff103261SSteve Yenint cproxy_listen(proxy *p);
508ff103261SSteve Yenint cproxy_listen_port(int port,
509ff103261SSteve Yen                       enum protocol protocol,
510ff103261SSteve Yen                       enum network_transport transport,
511ff103261SSteve Yen                       void       *conn_extra,
512ff103261SSteve Yen                       conn_funcs *conn_funcs);
513ff103261SSteve Yen
5147d4ff237STrond Norbyeproxy_td *cproxy_find_thread_data(proxy *p, cb_thread_t thread_id);
5157aef30f6SSteve Yenbool      cproxy_init_upstream_conn(conn *c);
5167aef30f6SSteve Yenbool      cproxy_init_downstream_conn(conn *c);
5174ba2e173SSteve Yenvoid      cproxy_on_close_upstream_conn(conn *c);
5184ba2e173SSteve Yenvoid      cproxy_on_close_downstream_conn(conn *c);
5194ba2e173SSteve Yenvoid      cproxy_on_pause_downstream_conn(conn *c);
5204ba2e173SSteve Yen
521498dc881SSteve Yenvoid cproxy_upstream_state_change(conn *c, enum conn_states next_state);
522498dc881SSteve Yen
52316be84f5SSteve Yenvoid cproxy_add_downstream(proxy_td *ptd);
52416be84f5SSteve Yenvoid cproxy_free_downstream(downstream *d);
52516be84f5SSteve Yen
5267209ef6aSSteve Yendownstream *cproxy_create_downstream(char *config,
5277209ef6aSSteve Yen                                     uint32_t config_ver,
52816be84f5SSteve Yen                                     proxy_behavior_pool *behavior_pool);
52916be84f5SSteve Yen
5304ba2e173SSteve Yendownstream *cproxy_reserve_downstream(proxy_td *ptd);
5314ba2e173SSteve Yenbool        cproxy_release_downstream(downstream *d, bool force);
5324ba2e173SSteve Yenvoid        cproxy_release_downstream_conn(downstream *d, conn *c);
5334ba2e173SSteve Yenbool        cproxy_check_downstream_config(downstream *d);
5344ba2e173SSteve Yen
535b03ad2b1SSteve Yenint   cproxy_connect_downstream(downstream *d,
536c5a57ebbSSteve Yen                                LIBEVENT_THREAD *thread,
537c5a57ebbSSteve Yen                                int server_index);
538b03ad2b1SSteve Yenconn *cproxy_connect_downstream_conn(downstream *d,
539b03ad2b1SSteve Yen                                     LIBEVENT_THREAD *thread,
5409554b975SSteve Yen                                     mcs_server_st *msst,
541b03ad2b1SSteve Yen                                     proxy_behavior *behavior);
542b03ad2b1SSteve Yen
54333f8cad1SSteve Yenvoid  cproxy_wait_any_downstream(proxy_td *ptd, conn *c);
5444ba2e173SSteve Yenvoid  cproxy_assign_downstream(proxy_td *ptd);
5454ba2e173SSteve Yen
5461e0192d8SSteve Yenproxy *cproxy_find_proxy_by_auth(proxy_main *m,
5471e0192d8SSteve Yen                                 const char *usr,
5481e0192d8SSteve Yen                                 const char *pwd);
5491e0192d8SSteve Yen
550646bff3dSSteve Yenint cproxy_auth_downstream(mcs_server_st *server,
551ed741b63STrond Norbye                           proxy_behavior *behavior, SOCKET fd);
552646bff3dSSteve Yenint cproxy_bucket_downstream(mcs_server_st *server,
553ed741b63STrond Norbye                             proxy_behavior *behavior, SOCKET fd);
55476a3d758SSteve Yen
5554ba2e173SSteve Yenvoid  cproxy_pause_upstream_for_downstream(proxy_td *ptd, conn *upstream);
556caae1590SSteve Yenconn *cproxy_find_downstream_conn(downstream *d, char *key, int key_length,
5573163f0b1SAliaksey Kandratsenka                                  bool *local);
5585f686497SSteve Yenconn *cproxy_find_downstream_conn_ex(downstream *d, char *key, int key_length,
5593163f0b1SAliaksey Kandratsenka                                     bool *local, int *vbucket);
5605f686497SSteve Yenint   cproxy_server_index(downstream *d, char *key, size_t key_length, int *vbucket);
561dd39956cSSteve Yenbool  cproxy_prep_conn_for_write(conn *c);
562dd39956cSSteve Yenbool  cproxy_dettach_if_noreply(downstream *d, conn *uc);
5634ba2e173SSteve Yen
5644ba2e173SSteve Yenvoid cproxy_reset_upstream(conn *uc);
5654ba2e173SSteve Yen
566d36ac3b1SSteve Yenbool cproxy_update_event_write(downstream *d, conn *c);
567d36ac3b1SSteve Yen
568204bfcaeSSteve Yenbool cproxy_forward(downstream *d);
569204bfcaeSSteve Yen
5705fa3a334SSteve Yenvoid upstream_error_msg(conn *uc, char *ascii_msg,
5715fa3a334SSteve Yen                        protocol_binary_response_status binary_status);
572f595a5dbSSteve Yenvoid upstream_retry(void *data0, void *data1);
573f595a5dbSSteve Yen
574f595a5dbSSteve Yenint downstream_conn_index(downstream *d, conn *c);
575f595a5dbSSteve Yen
576ed741b63STrond Norbyevoid cproxy_dump_header(SOCKET prefix, char *bb);
577d36ac3b1SSteve Yen
578f76dee5dSSteve Yenint cproxy_max_retries(downstream *d);
579f76dee5dSSteve Yen
580db427f17STrond Norbye/* --------------------------------------------------------------- */
581d785d2daSSteve Yen
5824ba2e173SSteve Yenvoid cproxy_process_upstream_ascii(conn *c, char *line);
5834ba2e173SSteve Yenvoid cproxy_process_upstream_ascii_nread(conn *c);
5844ba2e173SSteve Yen
585d785d2daSSteve Yenvoid cproxy_process_downstream_ascii(conn *c, char *line);
586d785d2daSSteve Yenvoid cproxy_process_downstream_ascii_nread(conn *c);
587d785d2daSSteve Yen
588d785d2daSSteve Yenvoid cproxy_process_upstream_binary(conn *c);
589d785d2daSSteve Yenvoid cproxy_process_upstream_binary_nread(conn *c);
590d785d2daSSteve Yen
591d785d2daSSteve Yenvoid cproxy_process_downstream_binary(conn *c);
592d785d2daSSteve Yenvoid cproxy_process_downstream_binary_nread(conn *c);
593d785d2daSSteve Yen
594db427f17STrond Norbye/* --------------------------------------------------------------- */
595db427f17STrond Norbye/* a2a means ascii upstream, ascii downstream. */
596db427f17STrond Norbye
5970528d201SSteve Yenvoid cproxy_init_a2a(void);
598bcb5e6eaSSteve Yenvoid cproxy_process_a2a_downstream(conn *c, char *line);
599bcb5e6eaSSteve Yenvoid cproxy_process_a2a_downstream_nread(conn *c);
600bcb5e6eaSSteve Yen
601bcb5e6eaSSteve Yenbool cproxy_forward_a2a_downstream(downstream *d);
602d785d2daSSteve Yen
603bcb5e6eaSSteve Yenbool cproxy_forward_a2a_multiget_downstream(downstream *d, conn *uc);
604bcb5e6eaSSteve Yenbool cproxy_forward_a2a_simple_downstream(downstream *d, char *command,
605bcb5e6eaSSteve Yen                                          conn *uc);
606bcb5e6eaSSteve Yenbool cproxy_forward_a2a_item_downstream(downstream *d, short cmd,
607bcb5e6eaSSteve Yen                                        item *it, conn *uc);
608bcb5e6eaSSteve Yenbool cproxy_broadcast_a2a_downstream(downstream *d, char *command,
609bcb5e6eaSSteve Yen                                     conn *uc, char *suffix);
610bcb5e6eaSSteve Yen
611db427f17STrond Norbye/* --------------------------------------------------------------- */
612db427f17STrond Norbye/* a2b means ascii upstream, binary downstream. */
613db427f17STrond Norbye
6140528d201SSteve Yenvoid cproxy_init_a2b(void);
615cece4527SSteve Yenvoid cproxy_process_a2b_downstream(conn *c);
616bcb5e6eaSSteve Yenvoid cproxy_process_a2b_downstream_nread(conn *c);
617bcb5e6eaSSteve Yen
618bcb5e6eaSSteve Yenbool cproxy_forward_a2b_downstream(downstream *d);
619bcb5e6eaSSteve Yenbool cproxy_forward_a2b_multiget_downstream(downstream *d, conn *uc);
620bcb5e6eaSSteve Yenbool cproxy_forward_a2b_simple_downstream(downstream *d, char *command,
621bcb5e6eaSSteve Yen                                          conn *uc);
622bcb5e6eaSSteve Yenbool cproxy_forward_a2b_item_downstream(downstream *d, short cmd,
623bcb5e6eaSSteve Yen                                        item *it, conn *uc);
624671fcd63SSteve Yenbool cproxy_broadcast_a2b_downstream(downstream *d,
625671fcd63SSteve Yen                                     protocol_binary_request_header *req,
626671fcd63SSteve Yen                                     int req_size,
627671fcd63SSteve Yen                                     uint8_t *key,
628671fcd63SSteve Yen                                     uint16_t keylen,
629671fcd63SSteve Yen                                     uint8_t  extlen,
630bcb5e6eaSSteve Yen                                     conn *uc, char *suffix);
6314ba2e173SSteve Yen
632db427f17STrond Norbye/* --------------------------------------------------------------- */
633db427f17STrond Norbye/* b2b means binary upstream, binary downstream. */
634db427f17STrond Norbye
635d785d2daSSteve Yenvoid cproxy_init_b2b(void);
636d785d2daSSteve Yenvoid cproxy_process_b2b_downstream(conn *c);
637d785d2daSSteve Yenvoid cproxy_process_b2b_downstream_nread(conn *c);
638d785d2daSSteve Yen
639d785d2daSSteve Yenbool cproxy_forward_b2b_downstream(downstream *d);
640d785d2daSSteve Yenbool cproxy_forward_b2b_multiget_downstream(downstream *d, conn *uc);
641d785d2daSSteve Yenbool cproxy_forward_b2b_simple_downstream(downstream *d, conn *uc);
642d785d2daSSteve Yen
643d785d2daSSteve Yenbool cproxy_broadcast_b2b_downstream(downstream *d, conn *uc);
644d785d2daSSteve Yen
645db427f17STrond Norbye/* --------------------------------------------------------------- */
6468a1e4450SSteve Yen
647dcdc1778SSteve Yenbool b2b_forward_item(conn *uc, downstream *d, item *it);
648dcdc1778SSteve Yen
649dcdc1778SSteve Yenbool b2b_forward_item_vbucket(conn *uc, downstream *d, item *it,
6503c813ba1SAliaksey Kandratsenka                              conn *c, int vbucket);
651dcdc1778SSteve Yen
652db427f17STrond Norbye/* --------------------------------------------------------------- */
653db427f17STrond Norbye
654db427f17STrond Norbye/* Magic opaque value that tells us to eat a binary quiet command */
655db427f17STrond Norbye/* response.  That is, do not send the response up to the ascii client */
656db427f17STrond Norbye/* which originally made its request with noreply. */
657dcdc1778SSteve Yen
6586c1acee5SSteve Yen#define OPAQUE_IGNORE_REPLY 0x0411F00D
6596c1acee5SSteve Yen
6606c1acee5SSteve Yenbool cproxy_binary_ignore_reply(conn *c, protocol_binary_response_header *header, item *it);
6616c1acee5SSteve Yen
662db427f17STrond Norbye/* --------------------------------------------------------------- */
6636c1acee5SSteve Yen
664f4d35310SJoon(JunHyun Park)proxy_main *cproxy_gen_proxy_main(proxy_behavior behavior,
665f4d35310SJoon(JunHyun Park)                                  int nthreads, enum_proxy_conf_type conf_type);
666f4d35310SJoon(JunHyun Park)
6676534a5adSSteve Yenproxy_behavior cproxy_parse_behavior(char          *behavior_str,
6686534a5adSSteve Yen                                     proxy_behavior behavior_default);
6696534a5adSSteve Yen
6706534a5adSSteve Yenvoid cproxy_parse_behavior_key_val_str(char *key_val,
6716534a5adSSteve Yen                                       proxy_behavior *behavior);
6726534a5adSSteve Yen
6736534a5adSSteve Yenvoid cproxy_parse_behavior_key_val(char *key,
6746534a5adSSteve Yen                                   char *val,
6756534a5adSSteve Yen                                   proxy_behavior *behavior);
6766534a5adSSteve Yen
6776534a5adSSteve Yenproxy_behavior *cproxy_copy_behaviors(int arr_size, proxy_behavior *arr);
6786534a5adSSteve Yen
6796534a5adSSteve Yenbool cproxy_equal_behaviors(int x_size, proxy_behavior *x,
6806534a5adSSteve Yen                            int y_size, proxy_behavior *y);
6816534a5adSSteve Yenbool cproxy_equal_behavior(proxy_behavior *x,
6826534a5adSSteve Yen                           proxy_behavior *y);
6836534a5adSSteve Yen
684c1506ae6SSteve Yenvoid cproxy_dump_behavior(proxy_behavior *b, char *prefix, int level);
685d18522f1SSteve Yenvoid cproxy_dump_behavior_ex(proxy_behavior *b, char *prefix, int level,
68638458c40SSteve Yen                             void (*dump)(const void *dump_opaque,
68738458c40SSteve Yen                                          const char *prefix,
68838458c40SSteve Yen                                          const char *key,
68938458c40SSteve Yen                                          const char *buf),
69038458c40SSteve Yen                             const void *dump_opaque);
69138458c40SSteve Yenvoid cproxy_dump_behavior_stderr(const void *dump_opaque,
69238458c40SSteve Yen                                 const char *prefix,
69338458c40SSteve Yen                                 const char *key,
69438458c40SSteve Yen                                 const char *val);
695fbc73dbdSSteve Yen
696db427f17STrond Norbye/* --------------------------------------------------------------- */
6976534a5adSSteve Yen
698c5a57ebbSSteve Yenbool cproxy_is_broadcast_cmd(int cmd);
699c5a57ebbSSteve Yen
70088005dc4SSteve Yenvoid cproxy_ascii_broadcast_suffix(downstream *d);
70188005dc4SSteve Yen
702e93d6d75SSteve Yenvoid cproxy_upstream_ascii_item_response(item *it, conn *uc,
703e93d6d75SSteve Yen                                         int cas_emit);
7048a1e4450SSteve Yen
70531821cfeSSteve Yenbool cproxy_clear_timeout(downstream *d);
70631821cfeSSteve Yen
70750187c23SSteve Yenstruct timeval cproxy_get_downstream_timeout(downstream *d, conn *c);
7084eb97c82SSteve Yen
70950187c23SSteve Yenbool cproxy_start_downstream_timeout(downstream *d, conn *c);
710026a9b78SSteve Yenbool cproxy_start_downstream_timeout_ex(downstream *d, conn *c,
711026a9b78SSteve Yen                                        struct timeval dt);
7126d7eb51cSSteve Yenbool cproxy_start_wait_queue_timeout(proxy_td *ptd, conn *uc);
713efbbeceeSSteve Yen
7144ba2e173SSteve Yenrel_time_t cproxy_realtime(const time_t exptime);
7154ba2e173SSteve Yen
7164ba2e173SSteve Yenvoid cproxy_close_conn(conn *c);
7174ba2e173SSteve Yen
7181de95aacSSteve Yenvoid cproxy_reset_stats_td(proxy_stats_td *pstd);
719b7a3357eSSteve Yenvoid cproxy_reset_stats(proxy_stats *ps);
7201de95aacSSteve Yenvoid cproxy_reset_stats_cmd(proxy_stats_cmd *sc);
721b7a3357eSSteve Yen
722d36ac3b1SSteve Yenbool cproxy_binary_cork_cmd(conn *uc);
723d785d2daSSteve Yenvoid cproxy_binary_uncork_cmds(downstream *d, conn *uc);
724d785d2daSSteve Yen
7258c1525caSSteve Yenbool ascii_scan_key(char *line, char **key, int *key_len);
7268c1525caSSteve Yen
727db427f17STrond Norbye/* Multiget key de-duplication. */
728db427f17STrond Norbye
7292cca768bSSteve Yentypedef struct multiget_entry multiget_entry;
7302cca768bSSteve Yen
7312cca768bSSteve Yenstruct multiget_entry {
7322cca768bSSteve Yen    conn           *upstream_conn;
733db427f17STrond Norbye    uint32_t        opaque; /* For binary protocol. */
7345fa79c79SSteve Yen    uint64_t        hits;
7352cca768bSSteve Yen    multiget_entry *next;
7362cca768bSSteve Yen};
7372cca768bSSteve Yen
7382e7c15c2SSteve Yenbool multiget_ascii_downstream(
7392e7c15c2SSteve Yen    downstream *d, conn *uc,
740db6a381dSSteve Yen    int (*emit_start)(conn *c, char *cmd, int cmd_len),
7414aa49f51SSteve Yen    int (*emit_skey)(conn *c, char *skey, int skey_len, int vbucket, int key_index),
742af8bf580SSteve Yen    int (*emit_end)(conn *c),
743aa9f46b9SSteve Yen    mcache *front_cache);
7442e7c15c2SSteve Yen
7450049a6b5SSteve Yenvoid multiget_ascii_downstream_response(downstream *d, item *it);
7460049a6b5SSteve Yen
747ea4d0640SDustin Sallingsvoid multiget_foreach_free(const void *key,
748ea4d0640SDustin Sallings                           const void *value,
749ea4d0640SDustin Sallings                           void *user_data);
7502cca768bSSteve Yen
751ea4d0640SDustin Sallingsvoid multiget_remove_upstream(const void *key,
752ea4d0640SDustin Sallings                              const void *value,
753ea4d0640SDustin Sallings                              void *user_data);
754ac4b3ee2SSteve Yen
755db427f17STrond Norbye/* Space or null terminated key funcs. */
756db427f17STrond Norbye
757ea4d0640SDustin Sallingssize_t skey_len(const char *key);
758ea4d0640SDustin Sallingsint    skey_hash(const void *v);
759ea4d0640SDustin Sallingsint    skey_equal(const void *v1, const void *v2);
760db94fe97SSteve Yen
761ea4d0640SDustin Sallingsextern struct hash_ops strhash_ops;
762ea4d0640SDustin Sallingsextern struct hash_ops skeyhash_ops;
763ea4d0640SDustin Sallings
764ea4d0640SDustin Sallingsvoid noop_free(void *v);
76543d4b3a1SSteve Yen
766db427f17STrond Norbye/* Stats handling. */
767db427f17STrond Norbye
768ea4d0640SDustin Sallingsbool protocol_stats_merge_line(genhash_t *merger, char *line);
7695048d8b5SSteve Yen
770ea4d0640SDustin Sallingsbool protocol_stats_merge_name_val(genhash_t *merger,
7715048d8b5SSteve Yen                                   char *prefix,
7725048d8b5SSteve Yen                                   int   prefix_len,
7735048d8b5SSteve Yen                                   char *name,
7745048d8b5SSteve Yen                                   int   name_len,
7755048d8b5SSteve Yen                                   char *val,
7765048d8b5SSteve Yen                                   int   val_len);
77789324b91SSteve Yen
778ea4d0640SDustin Sallingsvoid protocol_stats_foreach_free(const void *key,
779ea4d0640SDustin Sallings                                 const void *value,
780ea4d0640SDustin Sallings                                 void *user_data);
78189324b91SSteve Yen
782ea4d0640SDustin Sallingsvoid protocol_stats_foreach_write(const void *key,
783ea4d0640SDustin Sallings                                  const void *value,
784ea4d0640SDustin Sallings                                  void *user_data);
785e9da625fSSteve Yen
78659719968SSteve Yenbool cproxy_optimize_set_ascii(downstream *d, conn *uc,
78759719968SSteve Yen                               char *key, int key_len);
78859719968SSteve Yen
789df0d0686SSteve Yenvoid cproxy_del_front_cache_key_ascii(downstream *d,
790df0d0686SSteve Yen                                      char *command);
791df0d0686SSteve Yen
792df0d0686SSteve Yenvoid cproxy_del_front_cache_key_ascii_response(downstream *d,
793df0d0686SSteve Yen                                               char *response,
794df0d0686SSteve Yen                                               char *command);
795df0d0686SSteve Yen
796ec0aa369SSteve Yenvoid cproxy_front_cache_delete(proxy_td *ptd, char *key, int key_len);
797ec0aa369SSteve Yen
798ec0aa369SSteve Yenbool cproxy_front_cache_key(proxy_td *ptd, char *key, int key_len);
799ec0aa369SSteve Yen
800384534dbSSteve YenHTGRAM_HANDLE cproxy_create_timing_histogram(void);
80107398270SSteve Yen
802f1ae675fSAliaksey Kandratsenkatypedef void (*mcache_traversal_func)(const void *it, void *userdata);
803f1ae675fSAliaksey Kandratsenka
804db427f17STrond Norbye/* Functions for the front cache. */
805db427f17STrond Norbye
806ac8ee0cdSSteve Yenvoid  mcache_init(mcache *m, bool multithreaded,
807ac8ee0cdSSteve Yen                  mcache_funcs *funcs, bool key_alloc);
8083c6141d2SSteve Yenvoid  mcache_start(mcache *m, uint32_t max);
809df0d0686SSteve Yenbool  mcache_started(mcache *m);
810aa9f46b9SSteve Yenvoid  mcache_stop(mcache *m);
811ce834644SSteve Yenvoid  mcache_reset_stats(mcache *m);
812a4eaead9SSteve Yenvoid *mcache_get(mcache *m, char *key, int key_len,
8136a26e91aSSteve Yen                 uint64_t curr_time);
814aaf92120SSteve Yenvoid  mcache_set(mcache *m, void *it,
8156a26e91aSSteve Yen                 uint64_t exptime,
816ea217f9bSSteve Yen                 bool add_only,
817ea217f9bSSteve Yen                 bool mod_exptime_if_exists);
818b86f34b7SSteve Yenvoid  mcache_delete(mcache *m, char *key, int key_len);
8196b4e51cdSSteve Yenvoid  mcache_flush_all(mcache *m, uint32_t msec_exp);
820f1ae675fSAliaksey Kandratsenkavoid  mcache_foreach(mcache *m, mcache_traversal_func f, void *userdata);
821ceb25177SSteve Yen
822db427f17STrond Norbye/* Functions for key stats. */
823db427f17STrond Norbye
8244d4df1e1SSteve Yenkey_stats *find_key_stats(proxy_td *ptd, char *key, int key_len,
8256a26e91aSSteve Yen                          uint64_t msec_time);
8264d4df1e1SSteve Yen
8274d4df1e1SSteve Yenvoid touch_key_stats(proxy_td *ptd, char *key, int key_len,
8286a26e91aSSteve Yen                     uint64_t msec_current_time,
8294d4df1e1SSteve Yen                     enum_stats_cmd_type cmd_type,
8304d4df1e1SSteve Yen                     enum_stats_cmd cmd,
8314d4df1e1SSteve Yen                     int delta_seen,
8324d4df1e1SSteve Yen                     int delta_hits,
8334d4df1e1SSteve Yen                     int delta_misses,
8344d4df1e1SSteve Yen                     int delta_read_bytes,
8354d4df1e1SSteve Yen                     int delta_write_bytes);
8364d4df1e1SSteve Yen
837dcbf4c02SSteve Yenvoid key_stats_add_ref(void *it);
838dcbf4c02SSteve Yenvoid key_stats_dec_ref(void *it);
839dcbf4c02SSteve Yen