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-2015 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 #ifdef __cplusplus
20 extern "C" {
21 #endif
22 
23 #include <aerospike/as_config.h>
24 #include <aerospike/as_node.h>
25 #include <aerospike/as_partition.h>
26 #include <aerospike/as_policy.h>
27 #include <aerospike/as_thread_pool.h>
28 #include <citrusleaf/cf_atomic.h>
29 #include "ck_pr.h"
30 
31 /******************************************************************************
32  * TYPES
33  *****************************************************************************/
34 
35 /**
36  * Seed host.
37  */
38 typedef struct as_seed_s {
39  /**
40  * Host name.
41  */
42  char* name;
43 
44  /**
45  * Host port.
46  */
47  in_port_t port;
48 } as_seed;
49 
50 /**
51  * @private
52  * Reference counted array of server node pointers.
53  */
54 typedef struct as_nodes_s {
55  /**
56  * @private
57  * Reference count of node array.
58  */
59  uint32_t ref_count;
60 
61  /**
62  * @private
63  * Length of node array.
64  */
65  uint32_t size;
66 
67  /**
68  * @private
69  * Server node array.
70  */
71  as_node* array[];
72 } as_nodes;
73 
74 /**
75  * @private
76  * Reference counted release function definition.
77  */
78 typedef void (*as_release_fn) (void* value);
79 
80 /**
81  * @private
82  * Reference counted data to be garbage collected.
83  */
84 typedef struct as_gc_item_s {
85  /**
86  * @private
87  * Reference counted data to be garbage collected.
88  */
89  void* data;
90 
91  /**
92  * @private
93  * Release function.
94  */
96 } as_gc_item;
97 
98 struct threadpool_t;
99 
100 /**
101  * Cluster of server nodes.
102  */
103 typedef struct as_cluster_s {
104  /**
105  * @private
106  * Active nodes in cluster.
107  */
109 
110  /**
111  * @private
112  * Hints for best node for a partition.
113  */
115 
116  /**
117  * @private
118  * Nodes to be garbage collected.
119  */
120  as_vector* /* <as_gc_item> */ gc;
121 
122  /**
123  * @private
124  * Shared memory implementation of cluster.
125  */
126  struct as_shm_info_s* shm_info;
127 
128  /**
129  * @private
130  * User name in UTF-8 encoded bytes.
131  */
132  char* user;
133 
134  /**
135  * @private
136  * Password in hashed format in bytes.
137  */
138  char* password;
139 
140  /**
141  * @private
142  * Initial seed nodes specified by user.
143  */
145 
146  /**
147  * @private
148  * Length of seeds array.
149  */
150  uint32_t seeds_size;
151 
152  /**
153  * @private
154  * Length of ip_map array.
155  */
156  uint32_t ip_map_size;
157 
158  /**
159  * @private
160  * A IP translation table is used in cases where different clients use different server
161  * IP addresses. This may be necessary when using clients from both inside and outside
162  * a local area network. Default is no translation.
163  *
164  * The key is the IP address returned from friend info requests to other servers. The
165  * value is the real IP address used to connect to the server.
166  */
168 
169  /**
170  * @private
171  * Pool of threads used to query server nodes in parallel for batch, scan and query.
172  */
173  as_thread_pool thread_pool;
174 
175  /**
176  * @private
177  * Lock for the tend thread to wait on with the tend interval as timeout.
178  * Normally locked, resulting in waiting a full interval between
179  * tend iterations. Upon cluster shutdown, unlocked by the main
180  * thread, allowing a fast termination of the tend thread.
181  */
182  pthread_mutex_t tend_lock;
183 
184  /**
185  * @private
186  * Tend thread identifier to be used with tend_lock.
187  */
188  pthread_cond_t tend_cond;
189 
190  /**
191  * @private
192  * Milliseconds between cluster tends.
193  */
194  uint32_t tend_interval;
195 
196  /**
197  * @private
198  * Size of node's synchronous connection pool.
199  */
200  uint32_t conn_queue_size;
201 
202  /**
203  * @private
204  * Initial connection timeout in milliseconds.
205  */
206  uint32_t conn_timeout_ms;
207 
208  /**
209  * @private
210  * Maximum socket idle in seconds.
211  */
212  uint32_t max_socket_idle;
213 
214  /**
215  * @private
216  * Random node index.
217  */
218  uint32_t node_index;
219 
220  /**
221  * @private
222  * Total number of data partitions used by cluster.
223  */
224  cl_partition_id n_partitions;
225 
226  /**
227  * @private
228  * Should continue to tend cluster.
229  */
230  volatile bool valid;
231 
232  /**
233  * @private
234  * Batch transaction lock.
235  */
236  pthread_mutex_t batch_init_lock;
237 
238  /**
239  * @private
240  * Cluster tend thread.
241  */
242  pthread_t tend_thread;
243 } as_cluster;
244 
245 /******************************************************************************
246  * FUNCTIONS
247  ******************************************************************************/
248 
249 /**
250  * Create and initialize cluster.
251  */
252 as_status
253 as_cluster_create(as_config* config, as_error* err, as_cluster** cluster);
254 
255 /**
256  * Close all connections and release memory associated with cluster.
257  */
258 void
260 
261 /**
262  * Is cluster connected to any server nodes.
263  */
264 bool
266 
267 /**
268  * Get all node names in cluster.
269  */
270 void
271 as_cluster_get_node_names(as_cluster* cluster, int* n_nodes, char** node_names);
272 
273 /**
274  * Reserve reference counted access to cluster nodes.
275  */
276 static inline as_nodes*
278 {
279  as_nodes* nodes = (as_nodes *)ck_pr_load_ptr(&cluster->nodes);
280  //ck_pr_fence_acquire();
281  ck_pr_inc_32(&nodes->ref_count);
282  return nodes;
283 }
284 
285 /**
286  * Release reference counted access to cluster nodes.
287  */
288 static inline void
290 {
291  //ck_pr_fence_release();
292 
293  bool destroy;
294  ck_pr_dec_32_zero(&nodes->ref_count, &destroy);
295 
296  if (destroy) {
297  cf_free(nodes);
298  }
299 }
300 
301 /**
302  * @private
303  * Change user and password that is used to authenticate with cluster servers.
304  */
305 void
306 as_cluster_change_password(as_cluster* cluster, const char* user, const char* password);
307 
308 /**
309  * @private
310  * Get random node in the cluster.
311  * as_nodes_release() must be called when done with node.
312  */
313 as_node*
315 
316 /**
317  * @private
318  * Get node given node name.
319  * as_nodes_release() must be called when done with node.
320  */
321 as_node*
322 as_node_get_by_name(as_cluster* cluster, const char* name);
323 
324 /**
325  * @private
326  * Reserve reference counted access to partition tables.
327  * as_partition_tables_release() must be called when done with tables.
328  */
329 static inline as_partition_tables*
331 {
332  as_partition_tables* tables = (as_partition_tables *)ck_pr_load_ptr(&cluster->partition_tables);
333  ck_pr_inc_32(&tables->ref_count);
334  return tables;
335 }
336 
337 /**
338  * @private
339  * Release reference counted access to partition tables.
340  */
341 static inline void
343 {
344  bool destroy;
345  ck_pr_dec_32_zero(&tables->ref_count, &destroy);
346 
347  if (destroy) {
348  cf_free(tables);
349  }
350 }
351 
352 /**
353  * @private
354  * Get partition table given namespace.
355  */
356 static inline as_partition_table*
358 {
359  // Partition tables array size does not currently change after first cluster tend.
360  // Also, there is a one second delayed garbage collection coupled with as_partition_tables_get()
361  // being very fast. Reference counting the tables array is not currently necessary, but do it
362  // anyway in case the server starts supporting dynamic namespaces.
364  as_partition_table* table = as_partition_tables_get(tables, ns);
366  return table;
367 }
368 
369 /**
370  * @private
371  * Get mapped node given digest key and partition table. If there is no mapped node, a random
372  * node is used instead.
373  * as_nodes_release() must be called when done with node.
374  */
375 as_node*
376 as_partition_table_get_node(as_cluster* cluster, as_partition_table* table, const uint8_t* digest, bool write, as_policy_replica replica);
377 
378 /**
379  * @private
380  * Get shared memory mapped node given digest key. If there is no mapped node, a random node is used instead.
381  * as_nodes_release() must be called when done with node.
382  */
383 as_node*
384 as_shm_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, bool write, as_policy_replica replica);
385 
386 /**
387  * @private
388  * Get mapped node given digest key. If there is no mapped node, a random node is used instead.
389  * as_nodes_release() must be called when done with node.
390  */
391 static inline as_node*
392 as_node_get(as_cluster* cluster, const char* ns, const uint8_t* digest, bool write, as_policy_replica replica)
393 {
394  if (cluster->shm_info) {
395  return as_shm_node_get(cluster, ns, digest, write, replica);
396  }
397  else {
399  return as_partition_table_get_node(cluster, table, digest, write, replica);
400  }
401 }
402 
403 #ifdef __cplusplus
404 } // end extern "C"
405 #endif