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