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-2017 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  * Cluster event function that will be called when nodes are added/removed from the cluster.
132  */
134 
135  /**
136  * Cluster event user data that will be passed back to event_callback.
137  */
139 
140  /**
141  * Pending async commands counter array for all event loops.
142  */
143  int* pending;
144 
145  /**
146  * @private
147  * Initial seed hosts specified by user.
148  */
149  as_vector* /* <as_host> */ seeds;
150 
151  /**
152  * @private
153  * A IP translation table is used in cases where different clients use different server
154  * IP addresses. This may be necessary when using clients from both inside and outside
155  * a local area network. Default is no translation.
156  *
157  * The key is the IP address returned from friend info requests to other servers. The
158  * value is the real IP address used to connect to the server.
159  */
160  as_vector* /* <as_addr_map> */ ip_map;
161 
162  /**
163  * @private
164  * TLS parameters
165  */
167 
168  /**
169  * @private
170  * Pool of threads used to query server nodes in parallel for batch, scan and query.
171  */
173 
174  /**
175  * @private
176  * Cluster tend thread.
177  */
178  pthread_t tend_thread;
179 
180  /**
181  * @private
182  * Lock for adding/removing seeds.
183  */
184  pthread_mutex_t seed_lock;
185 
186  /**
187  * @private
188  * Lock for the tend thread to wait on with the tend interval as timeout.
189  * Normally locked, resulting in waiting a full interval between
190  * tend iterations. Upon cluster shutdown, unlocked by the main
191  * thread, allowing a fast termination of the tend thread.
192  */
193  pthread_mutex_t tend_lock;
194 
195  /**
196  * @private
197  * Tend thread identifier to be used with tend_lock.
198  */
199  pthread_cond_t tend_cond;
200 
201  /**
202  * @private
203  * Milliseconds between cluster tends.
204  */
205  uint32_t tend_interval;
206 
207  /**
208  * @private
209  * Maximum number of synchronous connections allowed per server node.
210  */
212 
213  /**
214  * @private
215  * Maximum number of asynchronous (non-pipeline) connections allowed for each node.
216  * Async transactions will be rejected if the maximum async node connections would be exceeded.
217  * This variable is ignored if asynchronous event loops are not created.
218  */
220 
221  /**
222  * @private
223  * Maximum number of pipeline connections allowed for each node.
224  * Pipeline transactions will be rejected if the maximum pipeline node connections would be exceeded.
225  * This variable is ignored if asynchronous event loops are not created.
226  */
228 
229  /**
230  * @private
231  * Number of synchronous connection pools used for each node.
232  */
234 
235  /**
236  * @private
237  * Initial connection timeout in milliseconds.
238  */
239  uint32_t conn_timeout_ms;
240 
241  /**
242  * @private
243  * Maximum socket idle in seconds.
244  */
245  uint32_t max_socket_idle;
246 
247  /**
248  * @private
249  * Random node index.
250  */
251  uint32_t node_index;
252 
253  /**
254  * @private
255  * Total number of data partitions used by cluster.
256  */
257  uint16_t n_partitions;
258 
259  /**
260  * @private
261  * If "services-alternate" should be used instead of "services"
262  */
264 
265  /**
266  * @private
267  * Should continue to tend cluster.
268  */
269  volatile bool valid;
270 } as_cluster;
271 
272 /******************************************************************************
273  * FUNCTIONS
274  ******************************************************************************/
275 
276 /**
277  * Create and initialize cluster.
278  */
279 as_status
280 as_cluster_create(as_config* config, as_error* err, as_cluster** cluster);
281 
282 /**
283  * Close all connections and release memory associated with cluster.
284  */
285 void
287 
288 /**
289  * Is cluster connected to any server nodes.
290  */
291 bool
293 
294 /**
295  * Get all node names in cluster.
296  */
297 void
298 as_cluster_get_node_names(as_cluster* cluster, int* n_nodes, char** node_names);
299 
300 /**
301  * Reserve reference counted access to cluster nodes.
302  */
303 static inline as_nodes*
305 {
306  as_nodes* nodes = (as_nodes *)ck_pr_load_ptr(&cluster->nodes);
307  //ck_pr_fence_acquire();
308  ck_pr_inc_32(&nodes->ref_count);
309  return nodes;
310 }
311 
312 /**
313  * Release reference counted access to cluster nodes.
314  */
315 static inline void
317 {
318  //ck_pr_fence_release();
319 
320  bool destroy;
321  ck_pr_dec_32_zero(&nodes->ref_count, &destroy);
322 
323  if (destroy) {
324  cf_free(nodes);
325  }
326 }
327 
328 /**
329  * Add seed to cluster.
330  */
331 void
332 as_cluster_add_seed(as_cluster* cluster, const char* hostname, const char* tls_name, uint16_t port);
333 
334 /**
335  * Remove seed from cluster.
336  */
337 void
338 as_cluster_remove_seed(as_cluster* cluster, const char* hostname, uint16_t port);
339 
340 /**
341  * @private
342  * Change user and password that is used to authenticate with cluster servers.
343  */
344 void
345 as_cluster_change_password(as_cluster* cluster, const char* user, const char* password);
346 
347 /**
348  * @private
349  * Get random node in the cluster.
350  * as_nodes_release() must be called when done with node.
351  */
352 as_node*
354 
355 /**
356  * @private
357  * Get node given node name.
358  * as_nodes_release() must be called when done with node.
359  */
360 as_node*
361 as_node_get_by_name(as_cluster* cluster, const char* name);
362 
363 /**
364  * @private
365  * Reserve reference counted access to partition tables.
366  * as_partition_tables_release() must be called when done with tables.
367  */
368 static inline as_partition_tables*
370 {
371  as_partition_tables* tables = (as_partition_tables *)ck_pr_load_ptr(&cluster->partition_tables);
372  ck_pr_inc_32(&tables->ref_count);
373  return tables;
374 }
375 
376 /**
377  * @private
378  * Release reference counted access to partition tables.
379  */
380 static inline void
382 {
383  bool destroy;
384  ck_pr_dec_32_zero(&tables->ref_count, &destroy);
385 
386  if (destroy) {
387  cf_free(tables);
388  }
389 }
390 
391 /**
392  * @private
393  * Get partition table given namespace.
394  */
395 static inline as_partition_table*
397 {
398  // Partition tables array size does not currently change after first cluster tend.
399  // Also, there is a one second delayed garbage collection coupled with as_partition_tables_get()
400  // being very fast. Reference counting the tables array is not currently necessary, but do it
401  // anyway in case the server starts supporting dynamic namespaces.
403  as_partition_table* table = as_partition_tables_get(tables, ns);
405  return table;
406 }
407 
408 /**
409  * @private
410  * Get mapped node given partition.
411  * as_nodes_release() must be called when done with node.
412  */
413 as_node*
414 as_partition_get_node(as_cluster* cluster, as_partition* p, as_policy_replica replica, bool use_master, bool cp_mode);
415 
416 /**
417  * @private
418  * Get mapped node given digest key. If there is no mapped node, another node is used based on replica.
419  * If successful, as_nodes_release() must be called when done with node.
420  */
421 as_status
423  struct as_cluster_s* cluster, as_error* err, const char* ns, const uint8_t* digest,
424  as_policy_replica replica, bool master, as_node** node
425  );
426 
427 #ifdef __cplusplus
428 } // end extern "C"
429 #endif
as_thread_pool thread_pool
Definition: as_cluster.h:172
uint32_t conn_pools_per_node
Definition: as_cluster.h:233
pthread_mutex_t tend_lock
Definition: as_cluster.h:193
as_node * as_partition_get_node(as_cluster *cluster, as_partition *p, as_policy_replica replica, bool use_master, bool cp_mode)
uint32_t ref_count
Definition: as_cluster.h:45
as_namespace ns
Definition: as_scan.h:380
as_policy_replica
Definition: as_policy.h:277
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:381
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
as_status as_cluster_get_node(struct as_cluster_s *cluster, as_error *err, const char *ns, const uint8_t *digest, as_policy_replica replica, bool master, as_node **node)
static as_partition_tables * as_partition_tables_reserve(as_cluster *cluster)
Definition: as_cluster.h:369
as_partition_tables * partition_tables
Definition: as_cluster.h:98
uint32_t conn_timeout_ms
Definition: as_cluster.h:239
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:178
bool use_services_alternate
Definition: as_cluster.h:263
uint32_t async_max_conns_per_node
Definition: as_cluster.h:219
uint32_t max_socket_idle
Definition: as_cluster.h:245
as_vector * seeds
Definition: as_cluster.h:149
uint32_t max_conns_per_node
Definition: as_cluster.h:211
void as_cluster_get_node_names(as_cluster *cluster, int *n_nodes, char **node_names)
void as_cluster_remove_seed(as_cluster *cluster, const char *hostname, uint16_t port)
char * user
Definition: as_cluster.h:116
as_vector * ip_map
Definition: as_cluster.h:160
as_cluster_event_callback event_callback
Definition: as_cluster.h:133
uint32_t node_index
Definition: as_cluster.h:251
pthread_cond_t tend_cond
Definition: as_cluster.h:199
uint32_t tend_interval
Definition: as_cluster.h:205
char * cluster_name
Definition: as_cluster.h:128
static as_partition_table * as_cluster_get_partition_table(as_cluster *cluster, const char *ns)
Definition: as_cluster.h:396
uint32_t size
Definition: as_cluster.h:51
uint16_t n_partitions
Definition: as_cluster.h:257
uint32_t pipe_max_conns_per_node
Definition: as_cluster.h:227
int * pending
Definition: as_cluster.h:143
struct as_shm_info_s * shm_info
Definition: as_cluster.h:110
void(* as_cluster_event_callback)(as_cluster_event *event)
Definition: as_config.h:146
pthread_mutex_t seed_lock
Definition: as_cluster.h:184
void as_cluster_add_seed(as_cluster *cluster, const char *hostname, const char *tls_name, uint16_t port)
volatile bool valid
Definition: as_cluster.h:269
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:304
bool as_cluster_is_connected(as_cluster *cluster)
void * event_callback_udata
Definition: as_cluster.h:138
static void as_nodes_release(as_nodes *nodes)
Definition: as_cluster.h:316
as_tls_context tls_ctx
Definition: as_cluster.h:166
as_node * as_node_get_random(as_cluster *cluster)