All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_cluster.h
Go to the documentation of this file.
1 /*
2  * Copyright 2008-2016 Aerospike, Inc.
3  *
4  * Portions may be licensed to Aerospike, Inc. under one or more contributor
5  * license agreements.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
8  * use this file except in compliance with the License. You may obtain a copy of
9  * the License at http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14  * License for the specific language governing permissions and limitations under
15  * the License.
16  */
17 #pragma once
18 
19 #include <aerospike/as_config.h>
20 #include <aerospike/as_node.h>
21 #include <aerospike/as_partition.h>
22 #include <aerospike/as_policy.h>
24 
25 #ifdef __cplusplus
26 extern "C" {
27 #endif
28 
29 // Concurrency kit needs to be under extern "C" when compiling C++.
30 #include <aerospike/ck/ck_pr.h>
31 
32 /******************************************************************************
33  * TYPES
34  *****************************************************************************/
35 
36 /**
37  * @private
38  * Reference counted array of server node pointers.
39  */
40 typedef struct as_nodes_s {
41  /**
42  * @private
43  * Reference count of node array.
44  */
45  uint32_t ref_count;
46 
47  /**
48  * @private
49  * Length of node array.
50  */
51  uint32_t size;
52 
53  /**
54  * @private
55  * Server node array.
56  */
57  as_node* array[];
58 } as_nodes;
59 
60 /**
61  * @private
62  * Reference counted release function definition.
63  */
64 typedef void (*as_release_fn) (void* value);
65 
66 /**
67  * @private
68  * Reference counted data to be garbage collected.
69  */
70 typedef struct as_gc_item_s {
71  /**
72  * @private
73  * Reference counted data to be garbage collected.
74  */
75  void* data;
76 
77  /**
78  * @private
79  * Release function.
80  */
82 } as_gc_item;
83 
84 /**
85  * Cluster of server nodes.
86  */
87 typedef struct as_cluster_s {
88  /**
89  * @private
90  * Active nodes in cluster.
91  */
93 
94  /**
95  * @private
96  * Hints for best node for a partition.
97  */
99 
100  /**
101  * @private
102  * Nodes to be garbage collected.
103  */
104  as_vector* /* <as_gc_item> */ gc;
105 
106  /**
107  * @private
108  * Shared memory implementation of cluster.
109  */
110  struct as_shm_info_s* shm_info;
111 
112  /**
113  * @private
114  * User name in UTF-8 encoded bytes.
115  */
116  char* user;
117 
118  /**
119  * @private
120  * Password in hashed format in bytes.
121  */
122  char* password;
123 
124  /**
125  * @private
126  * Expected cluster name for all nodes. May be null.
127  */
129 
130  /**
131  * @private
132  * Initial seed hosts specified by user.
133  */
134  as_vector* /* <as_host> */ seeds;
135 
136  /**
137  * @private
138  * A IP translation table is used in cases where different clients use different server
139  * IP addresses. This may be necessary when using clients from both inside and outside
140  * a local area network. Default is no translation.
141  *
142  * The key is the IP address returned from friend info requests to other servers. The
143  * value is the real IP address used to connect to the server.
144  */
145  as_vector* /* <as_addr_map> */ ip_map;
146 
147  /**
148  * @private
149  * TLS parameters
150  */
152 
153  /**
154  * @private
155  * Pool of threads used to query server nodes in parallel for batch, scan and query.
156  */
158 
159  /**
160  * @private
161  * Cluster tend thread.
162  */
163  pthread_t tend_thread;
164 
165  /**
166  * @private
167  * Lock for the tend thread to wait on with the tend interval as timeout.
168  * Normally locked, resulting in waiting a full interval between
169  * tend iterations. Upon cluster shutdown, unlocked by the main
170  * thread, allowing a fast termination of the tend thread.
171  */
172  pthread_mutex_t tend_lock;
173 
174  /**
175  * @private
176  * Tend thread identifier to be used with tend_lock.
177  */
178  pthread_cond_t tend_cond;
179 
180  /**
181  * @private
182  * Configuration version. Incremented, when the configuration is changed.
183  */
184  uint32_t version;
185 
186  /**
187  * @private
188  * Milliseconds between cluster tends.
189  */
190  uint32_t tend_interval;
191 
192  /**
193  * @private
194  * Size of node's synchronous connection pool.
195  */
196  uint32_t conn_queue_size;
197 
198  /**
199  * @private
200  * Maximum number of asynchronous (non-pipeline) connections allowed for each node.
201  * Async transactions will be rejected if the maximum async node connections would be exceeded.
202  * This variable is ignored if asynchronous event loops are not created.
203  */
205 
206  /**
207  * @private
208  * Maximum number of pipeline connections allowed for each node.
209  * Pipeline transactions will be rejected if the maximum pipeline node connections would be exceeded.
210  * This variable is ignored if asynchronous event loops are not created.
211  */
213 
214  /**
215  * @private
216  * Number of pending async commands (i.e., commands with an outstanding reply).
217  */
218  uint32_t async_pending;
219 
220  /**
221  * @private
222  * Number of active async pipeline and non-pipeline connections combined.
223  */
225 
226  /**
227  * @private
228  * Number of async connections in the pools.
229  */
230  uint32_t async_conn_pool;
231 
232  /**
233  * @private
234  * Initial connection timeout in milliseconds.
235  */
236  uint32_t conn_timeout_ms;
237 
238  /**
239  * @private
240  * Maximum socket idle in seconds.
241  */
242  uint32_t max_socket_idle;
243 
244  /**
245  * @private
246  * Random node index.
247  */
248  uint32_t node_index;
249 
250  /**
251  * @private
252  * Total number of data partitions used by cluster.
253  */
254  uint16_t n_partitions;
255 
256  /**
257  * @private
258  * If "services-alternate" should be used instead of "services"
259  */
261 
262  /**
263  * @private
264  * Should continue to tend cluster.
265  */
266  volatile bool valid;
267 } as_cluster;
268 
269 /******************************************************************************
270  * FUNCTIONS
271  ******************************************************************************/
272 
273 /**
274  * Create and initialize cluster.
275  */
276 as_status
277 as_cluster_create(as_config* config, as_error* err, as_cluster** cluster);
278 
279 /**
280  * Close all connections and release memory associated with cluster.
281  */
282 void
284 
285 /**
286  * Is cluster connected to any server nodes.
287  */
288 bool
290 
291 /**
292  * Get all node names in cluster.
293  */
294 void
295 as_cluster_get_node_names(as_cluster* cluster, int* n_nodes, char** node_names);
296 
297 /**
298  * Reserve reference counted access to cluster nodes.
299  */
300 static inline as_nodes*
302 {
303  as_nodes* nodes = (as_nodes *)ck_pr_load_ptr(&cluster->nodes);
304  //ck_pr_fence_acquire();
305  ck_pr_inc_32(&nodes->ref_count);
306  return nodes;
307 }
308 
309 /**
310  * Release reference counted access to cluster nodes.
311  */
312 static inline void
314 {
315  //ck_pr_fence_release();
316 
317  bool destroy;
318  ck_pr_dec_32_zero(&nodes->ref_count, &destroy);
319 
320  if (destroy) {
321  cf_free(nodes);
322  }
323 }
324 
325 /**
326  * Change maximum async connections per node.
327  */
328 void
329 as_cluster_set_async_max_conns_per_node(as_cluster* cluster, uint32_t async_size, uint32_t pipe_size);
330 
331 /**
332  * @private
333  * Change user and password that is used to authenticate with cluster servers.
334  */
335 void
336 as_cluster_change_password(as_cluster* cluster, const char* user, const char* password);
337 
338 /**
339  * @private
340  * Get random node in the cluster.
341  * as_nodes_release() must be called when done with node.
342  */
343 as_node*
345 
346 /**
347  * @private
348  * Get node given node name.
349  * as_nodes_release() must be called when done with node.
350  */
351 as_node*
352 as_node_get_by_name(as_cluster* cluster, const char* name);
353 
354 /**
355  * @private
356  * Reserve reference counted access to partition tables.
357  * as_partition_tables_release() must be called when done with tables.
358  */
359 static inline as_partition_tables*
361 {
362  as_partition_tables* tables = (as_partition_tables *)ck_pr_load_ptr(&cluster->partition_tables);
363  ck_pr_inc_32(&tables->ref_count);
364  return tables;
365 }
366 
367 /**
368  * @private
369  * Release reference counted access to partition tables.
370  */
371 static inline void
373 {
374  bool destroy;
375  ck_pr_dec_32_zero(&tables->ref_count, &destroy);
376 
377  if (destroy) {
378  cf_free(tables);
379  }
380 }
381 
382 /**
383  * @private
384  * Get partition table given namespace.
385  */
386 static inline as_partition_table*
388 {
389  // Partition tables array size does not currently change after first cluster tend.
390  // Also, there is a one second delayed garbage collection coupled with as_partition_tables_get()
391  // being very fast. Reference counting the tables array is not currently necessary, but do it
392  // anyway in case the server starts supporting dynamic namespaces.
394  as_partition_table* table = as_partition_tables_get(tables, ns);
396  return table;
397 }
398 
399 /**
400  * @private
401  * Get mapped node given digest key and partition table. If there is no mapped node, a random
402  * node is used instead.
403  * as_nodes_release() must be called when done with node.
404  */
405 as_node*
406 as_partition_table_get_node(as_cluster* cluster, as_partition_table* table, const uint8_t* digest, as_policy_replica replica, bool master);
407 
408 /**
409  * @private
410  * Get shared memory mapped node given digest key. If there is no mapped node, a random node is used instead.
411  * as_nodes_release() must be called when done with node.
412  */
413 as_node*
414 as_shm_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, as_policy_replica replica, bool master);
415 
416 /**
417  * @private
418  * Get mapped node given digest key. If there is no mapped node, a random node is used instead.
419  * as_nodes_release() must be called when done with node.
420  */
421 static inline as_node*
422 as_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, as_policy_replica replica, bool master)
423 {
424 #ifdef AS_TEST_PROXY
425  return as_node_get_random(cluster);
426 #else
427  if (cluster->shm_info) {
428  return as_shm_node_get(cluster, ns, digest, replica, master);
429  }
430  else {
432  return as_partition_table_get_node(cluster, table, digest, replica, master);
433  }
434 #endif
435 }
436 
437 #ifdef __cplusplus
438 } // end extern "C"
439 #endif
as_thread_pool thread_pool
Definition: as_cluster.h:157
pthread_mutex_t tend_lock
Definition: as_cluster.h:172
as_node * as_partition_table_get_node(as_cluster *cluster, as_partition_table *table, const uint8_t *digest, as_policy_replica replica, bool master)
uint32_t ref_count
Definition: as_cluster.h:45
as_namespace ns
Definition: as_scan.h:359
as_policy_replica
Definition: as_policy.h:270
as_nodes * nodes
Definition: as_cluster.h:92
as_status
Definition: as_status.h:30
static void as_partition_tables_release(as_partition_tables *tables)
Definition: as_cluster.h:372
void(* as_release_fn)(void *value)
Definition: as_cluster.h:64
void as_cluster_change_password(as_cluster *cluster, const char *user, const char *password)
as_status as_cluster_create(as_config *config, as_error *err, as_cluster **cluster)
void * data
Definition: as_cluster.h:75
static as_partition_tables * as_partition_tables_reserve(as_cluster *cluster)
Definition: as_cluster.h:360
as_partition_tables * partition_tables
Definition: as_cluster.h:98
uint32_t conn_queue_size
Definition: as_cluster.h:196
uint32_t conn_timeout_ms
Definition: as_cluster.h:236
char * password
Definition: as_cluster.h:122
as_release_fn release_fn
Definition: as_cluster.h:81
pthread_t tend_thread
Definition: as_cluster.h:163
void as_cluster_set_async_max_conns_per_node(as_cluster *cluster, uint32_t async_size, uint32_t pipe_size)
bool use_services_alternate
Definition: as_cluster.h:260
uint32_t async_max_conns_per_node
Definition: as_cluster.h:204
uint32_t max_socket_idle
Definition: as_cluster.h:242
as_vector * seeds
Definition: as_cluster.h:134
void as_cluster_get_node_names(as_cluster *cluster, int *n_nodes, char **node_names)
uint32_t async_conn_pool
Definition: as_cluster.h:230
char * user
Definition: as_cluster.h:116
as_vector * ip_map
Definition: as_cluster.h:145
static as_node * as_node_get(as_cluster *cluster, const char *ns, const uint8_t *digest, as_policy_replica replica, bool master)
Definition: as_cluster.h:422
uint32_t node_index
Definition: as_cluster.h:248
pthread_cond_t tend_cond
Definition: as_cluster.h:178
uint32_t tend_interval
Definition: as_cluster.h:190
char * cluster_name
Definition: as_cluster.h:128
uint32_t version
Definition: as_cluster.h:184
static as_partition_table * as_cluster_get_partition_table(as_cluster *cluster, const char *ns)
Definition: as_cluster.h:387
uint32_t size
Definition: as_cluster.h:51
uint16_t n_partitions
Definition: as_cluster.h:254
uint32_t pipe_max_conns_per_node
Definition: as_cluster.h:212
struct as_shm_info_s * shm_info
Definition: as_cluster.h:110
uint32_t async_pending
Definition: as_cluster.h:218
volatile bool valid
Definition: as_cluster.h:266
uint32_t async_conn_count
Definition: as_cluster.h:224
void as_cluster_destroy(as_cluster *cluster)
as_node * as_node_get_by_name(as_cluster *cluster, const char *name)
as_vector * gc
Definition: as_cluster.h:104
as_partition_table * as_partition_tables_get(as_partition_tables *tables, const char *ns)
static as_nodes * as_nodes_reserve(as_cluster *cluster)
Definition: as_cluster.h:301
bool as_cluster_is_connected(as_cluster *cluster)
as_node * as_shm_node_get(as_cluster *cluster, const char *ns, const uint8_t *digest, as_policy_replica replica, bool master)
static void as_nodes_release(as_nodes *nodes)
Definition: as_cluster.h:313
as_tls_context tls_ctx
Definition: as_cluster.h:151
as_node * as_node_get_random(as_cluster *cluster)