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>
23 #include <aerospike/as_thread_pool.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  * Seed host.
38  */
39 typedef struct as_seed_s {
40  /**
41  * Host name.
42  */
43  char* name;
44 
45  /**
46  * Host port.
47  */
48  in_port_t port;
49 } as_seed;
50 
51 /**
52  * @private
53  * Reference counted array of seed hosts.
54  */
55 typedef struct as_seeds_s {
56  /**
57  * @private
58  * Reference count.
59  */
60  uint32_t ref_count;
61 
62  /*
63  * @private
64  * Length of seed array.
65  */
66  uint32_t size;
67 
68  /**
69  * @private
70  * Seed array.
71  */
72  as_seed array[];
73 } as_seeds;
74 
75 /**
76  * @private
77  * Reference counted array of server node pointers.
78  */
79 typedef struct as_nodes_s {
80  /**
81  * @private
82  * Reference count of node array.
83  */
84  uint32_t ref_count;
85 
86  /**
87  * @private
88  * Length of node array.
89  */
90  uint32_t size;
91 
92  /**
93  * @private
94  * Server node array.
95  */
96  as_node* array[];
97 } as_nodes;
98 
99 
100 /**
101  * @private
102  * Reference counted array of address maps.
103  */
104 typedef struct as_addr_maps_s {
105  /**
106  * @private
107  * Reference count.
108  */
109  uint32_t ref_count;
110 
111  /*
112  * @private
113  * Length of address map array.
114  */
115  uint32_t size;
116 
117  /**
118  * @private
119  * tAddress map array.
120  */
121  as_addr_map array[];
122 } as_addr_maps;
123 
124 /**
125  * @private
126  * Reference counted release function definition.
127  */
128 typedef void (*as_release_fn) (void* value);
129 
130 /**
131  * @private
132  * Reference counted data to be garbage collected.
133  */
134 typedef struct as_gc_item_s {
135  /**
136  * @private
137  * Reference counted data to be garbage collected.
138  */
139  void* data;
140 
141  /**
142  * @private
143  * Release function.
144  */
146 } as_gc_item;
147 
148 /**
149  * Cluster of server nodes.
150  */
151 typedef struct as_cluster_s {
152  /**
153  * @private
154  * Active nodes in cluster.
155  */
157 
158  /**
159  * @private
160  * Hints for best node for a partition.
161  */
163 
164  /**
165  * @private
166  * Nodes to be garbage collected.
167  */
168  as_vector* /* <as_gc_item> */ gc;
169 
170  /**
171  * @private
172  * Shared memory implementation of cluster.
173  */
174  struct as_shm_info_s* shm_info;
175 
176  /**
177  * @private
178  * User name in UTF-8 encoded bytes.
179  */
180  char* user;
181 
182  /**
183  * @private
184  * Password in hashed format in bytes.
185  */
186  char* password;
187 
188  /**
189  * @private
190  * Initial seed nodes specified by user.
191  */
193 
194  /**
195  * @private
196  * Configuration version. Incremented, when the configuration is changed.
197  */
198  uint32_t version;
199 
200  /**
201  * @private
202  * A IP translation table is used in cases where different clients use different server
203  * IP addresses. This may be necessary when using clients from both inside and outside
204  * a local area network. Default is no translation.
205  *
206  * The key is the IP address returned from friend info requests to other servers. The
207  * value is the real IP address used to connect to the server.
208  */
210 
211  /**
212  * @private
213  * Pool of threads used to query server nodes in parallel for batch, scan and query.
214  */
215  as_thread_pool thread_pool;
216 
217  /**
218  * @private
219  * Cluster tend thread.
220  */
221  pthread_t tend_thread;
222 
223  /**
224  * @private
225  * Lock for the tend thread to wait on with the tend interval as timeout.
226  * Normally locked, resulting in waiting a full interval between
227  * tend iterations. Upon cluster shutdown, unlocked by the main
228  * thread, allowing a fast termination of the tend thread.
229  */
230  pthread_mutex_t tend_lock;
231 
232  /**
233  * @private
234  * Tend thread identifier to be used with tend_lock.
235  */
236  pthread_cond_t tend_cond;
237 
238  /**
239  * @private
240  * Milliseconds between cluster tends.
241  */
242  uint32_t tend_interval;
243 
244  /**
245  * @private
246  * Size of node's synchronous connection pool.
247  */
248  uint32_t conn_queue_size;
249 
250  /**
251  * @private
252  * Maximum number of asynchronous (non-pipeline) connections allowed for each node.
253  * Async transactions will be rejected if the maximum async node connections would be exceeded.
254  * This variable is ignored if asynchronous event loops are not created.
255  */
257 
258  /**
259  * @private
260  * Maximum number of pipeline connections allowed for each node.
261  * Pipeline transactions will be rejected if the maximum pipeline node connections would be exceeded.
262  * This variable is ignored if asynchronous event loops are not created.
263  */
265 
266  /**
267  * @private
268  * Number of pending async commands (i.e., commands with an outstanding reply).
269  */
270  uint32_t async_pending;
271 
272  /**
273  * @private
274  * Number of active async pipeline and non-pipeline connections combined.
275  */
277 
278  /**
279  * @private
280  * Number of async connections in the pools.
281  */
282  uint32_t async_conn_pool;
283 
284  /**
285  * @private
286  * Initial connection timeout in milliseconds.
287  */
288  uint32_t conn_timeout_ms;
289 
290  /**
291  * @private
292  * Maximum socket idle in seconds.
293  */
294  uint32_t max_socket_idle;
295 
296  /**
297  * @private
298  * Random node index.
299  */
300  uint32_t node_index;
301 
302  /**
303  * @private
304  * Total number of data partitions used by cluster.
305  */
306  uint16_t n_partitions;
307 
308  /**
309  * @private
310  * If "services-alternate" should be used instead of "services"
311  */
313 
314  /**
315  * @private
316  * Should continue to tend cluster.
317  */
318  volatile bool valid;
319 } as_cluster;
320 
321 /******************************************************************************
322  * FUNCTIONS
323  ******************************************************************************/
324 
325 /**
326  * Create and initialize cluster.
327  */
328 as_status
329 as_cluster_create(as_config* config, as_error* err, as_cluster** cluster);
330 
331 /**
332  * Close all connections and release memory associated with cluster.
333  */
334 void
336 
337 /**
338  * Is cluster connected to any server nodes.
339  */
340 bool
342 
343 /**
344  * Get all node names in cluster.
345  */
346 void
347 as_cluster_get_node_names(as_cluster* cluster, int* n_nodes, char** node_names);
348 
349 /**
350  * Reserve reference counted access to cluster nodes.
351  */
352 static inline as_nodes*
354 {
355  as_nodes* nodes = (as_nodes *)ck_pr_load_ptr(&cluster->nodes);
356  //ck_pr_fence_acquire();
357  ck_pr_inc_32(&nodes->ref_count);
358  return nodes;
359 }
360 
361 /**
362  * Release reference counted access to cluster nodes.
363  */
364 static inline void
366 {
367  //ck_pr_fence_release();
368 
369  bool destroy;
370  ck_pr_dec_32_zero(&nodes->ref_count, &destroy);
371 
372  if (destroy) {
373  cf_free(nodes);
374  }
375 }
376 
377 /**
378  * Reserve reference counted access to seeds.
379  */
380 static inline as_seeds*
382 {
383  as_seeds* seeds = (as_seeds *)ck_pr_load_ptr(&cluster->seeds);
384  ck_pr_inc_32(&seeds->ref_count);
385  return seeds;
386 }
387 
388 /**
389  * Release reference counted access to seeds.
390  */
391 static inline void
393 {
394  bool destroy;
395  ck_pr_dec_32_zero(&seeds->ref_count, &destroy);
396 
397  if (destroy) {
398  for (uint32_t i = 0; i < seeds->size; i++) {
399  cf_free(seeds->array[i].name);
400  }
401 
402  cf_free(seeds);
403  }
404 }
405 
406 /**
407  * Add seeds to the cluster.
408  */
409 void
410 as_seeds_add(as_cluster* cluster, as_seed* seed_list, uint32_t size);
411 
412 /**
413  * Replace the seeds of the cluster.
414  */
415 void
416 as_seeds_update(as_cluster* cluster, as_seed* seed_list, uint32_t size);
417 
418 /**
419  * Reserve reference counted access to IP map.
420  */
421 static inline as_addr_maps*
423 {
424  as_addr_maps* ip_map = (as_addr_maps *)ck_pr_load_ptr(&cluster->ip_map);
425 
426  if (ip_map == NULL) {
427  return NULL;
428  }
429 
430  ck_pr_inc_32(&ip_map->ref_count);
431  return ip_map;
432 }
433 
434 /**
435  * Release reference counted access to IP map.
436  */
437 static inline void
439 {
440  bool destroy;
441  ck_pr_dec_32_zero(&ip_map->ref_count, &destroy);
442 
443  if (destroy) {
444  for (uint32_t i = 0; i < ip_map->size; i++) {
445  cf_free(ip_map->array[i].orig);
446  cf_free(ip_map->array[i].alt);
447  }
448 
449  cf_free(ip_map);
450  }
451 }
452 
453 /**
454  * Replace the IP address map of the cluster.
455  */
456 void
457 as_ip_map_update(as_cluster* cluster, as_addr_map* ip_map_list, uint32_t size);
458 
459 /**
460  * Change maximum async connections per node.
461  */
462 void
463 as_cluster_set_async_max_conns_per_node(as_cluster* cluster, uint32_t async_size, uint32_t pipe_size);
464 
465 /**
466  * @private
467  * Change user and password that is used to authenticate with cluster servers.
468  */
469 void
470 as_cluster_change_password(as_cluster* cluster, const char* user, const char* password);
471 
472 /**
473  * @private
474  * Get random node in the cluster.
475  * as_nodes_release() must be called when done with node.
476  */
477 as_node*
479 
480 /**
481  * @private
482  * Get node given node name.
483  * as_nodes_release() must be called when done with node.
484  */
485 as_node*
486 as_node_get_by_name(as_cluster* cluster, const char* name);
487 
488 /**
489  * @private
490  * Reserve reference counted access to partition tables.
491  * as_partition_tables_release() must be called when done with tables.
492  */
493 static inline as_partition_tables*
495 {
496  as_partition_tables* tables = (as_partition_tables *)ck_pr_load_ptr(&cluster->partition_tables);
497  ck_pr_inc_32(&tables->ref_count);
498  return tables;
499 }
500 
501 /**
502  * @private
503  * Release reference counted access to partition tables.
504  */
505 static inline void
507 {
508  bool destroy;
509  ck_pr_dec_32_zero(&tables->ref_count, &destroy);
510 
511  if (destroy) {
512  cf_free(tables);
513  }
514 }
515 
516 /**
517  * @private
518  * Get partition table given namespace.
519  */
520 static inline as_partition_table*
522 {
523  // Partition tables array size does not currently change after first cluster tend.
524  // Also, there is a one second delayed garbage collection coupled with as_partition_tables_get()
525  // being very fast. Reference counting the tables array is not currently necessary, but do it
526  // anyway in case the server starts supporting dynamic namespaces.
528  as_partition_table* table = as_partition_tables_get(tables, ns);
530  return table;
531 }
532 
533 /**
534  * @private
535  * Get mapped node given digest key and partition table. If there is no mapped node, a random
536  * node is used instead.
537  * as_nodes_release() must be called when done with node.
538  */
539 as_node*
540 as_partition_table_get_node(as_cluster* cluster, as_partition_table* table, const uint8_t* digest, bool write, as_policy_replica replica);
541 
542 /**
543  * @private
544  * Get shared memory mapped node given digest key. If there is no mapped node, a random node is used instead.
545  * as_nodes_release() must be called when done with node.
546  */
547 as_node*
548 as_shm_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, bool write, as_policy_replica replica);
549 
550 /**
551  * @private
552  * Get mapped node given digest key. If there is no mapped node, a random node is used instead.
553  * as_nodes_release() must be called when done with node.
554  */
555 static inline as_node*
556 as_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, bool write, as_policy_replica replica)
557 {
558 #ifdef AS_TEST_PROXY
559  return as_node_get_random(cluster);
560 #else
561  if (cluster->shm_info) {
562  return as_shm_node_get(cluster, ns, digest, write, replica);
563  }
564  else {
566  return as_partition_table_get_node(cluster, table, digest, write, replica);
567  }
568 #endif
569 }
570 
571 #ifdef __cplusplus
572 } // end extern "C"
573 #endif