All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
as_node.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_error.h>
20 #include <aerospike/as_event.h>
21 #include <aerospike/as_queue.h>
22 #include <aerospike/as_vector.h>
23 #include <citrusleaf/cf_queue.h>
24 #include <netinet/in.h>
25 #include <sys/uio.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 // Concurrency kit needs to be under extern "C" when compiling C++.
32 #include <aerospike/ck/ck_pr.h>
33 
34 /******************************************************************************
35  * MACROS
36  *****************************************************************************/
37 
38 /**
39  * Maximum size (including NULL byte) of a hostname.
40  */
41 #define AS_HOSTNAME_SIZE 256
42 
43 /**
44  * Maximum size of node name
45  */
46 #define AS_NODE_NAME_SIZE 20
47 
48 // Leave this is in for backwards compatibility.
49 #define AS_NODE_NAME_MAX_SIZE AS_NODE_NAME_SIZE
50 
51 /******************************************************************************
52  * TYPES
53  *****************************************************************************/
54 
55 /**
56  * Socket address information.
57  */
58 typedef struct as_address_s {
59  /**
60  * Socket IP address.
61  */
62  struct sockaddr_in addr;
63 
64  /**
65  * Socket IP address string representation (xxx.xxx.xxx.xxx).
66  */
67  char name[INET_ADDRSTRLEN];
68 } as_address;
69 
70 struct as_cluster_s;
71 
72 /**
73  * Server node representation.
74  */
75 typedef struct as_node_s {
76  /**
77  * @private
78  * Reference count of node.
79  */
80  uint32_t ref_count;
81 
82  /**
83  * @private
84  * Server's generation count for partition management.
85  */
87 
88  /**
89  * The name of the node.
90  */
91  char name[AS_NODE_NAME_SIZE];
92 
93  /**
94  * @private
95  * Primary host address index into addresses array.
96  */
97  uint32_t address_index;
98 
99  /**
100  * @private
101  * Vector of sockaddr_in which the host is currently known by.
102  * Only used by tend thread. Not thread-safe.
103  */
104  as_vector /* <as_address> */ addresses;
105 
106  /**
107  * @private
108  * Vector of aliases which the host is currently known by.
109  * Only used by tend thread. Not thread-safe.
110  */
111  as_vector /* <as_host> */ aliases;
112 
113  struct as_cluster_s* cluster;
114 
115  /**
116  * @private
117  * Pool of current, cached FDs.
118  */
119  cf_queue* conn_q;
120 
121  /**
122  * @private
123  * Array of connection pools used in async commands. There is one pool per node/event loop.
124  * Only used by event loop threads. Not thread-safe.
125  */
127 
128  /**
129  * @private
130  * Pool of connections used in pipelined async commands. Also not thread-safe.
131  */
133 
134  /**
135  * @private
136  * Socket used exclusively for cluster tend thread info requests.
137  */
138  int info_fd;
139 
140  /**
141  * @private
142  * Number of other nodes that consider this node a member of the cluster.
143  */
144  uint32_t friends;
145 
146  /**
147  * @private
148  * Number of consecutive info request failures.
149  */
150  uint32_t failures;
151 
152  /**
153  * @private
154  * Shared memory node array index.
155  */
156  uint32_t index;
157 
158  /**
159  * @private
160  * Is node currently active.
161  */
162  uint8_t active;
163 
164  /**
165  * @private
166  * Does node support batch-index protocol?
167  */
169 
170  /**
171  * @private
172  * Does node support replicas-all info protocol?
173  */
175 
176  /**
177  * @private
178  * Does node support floating point type?
179  */
180  uint8_t has_double;
181 
182  /**
183  * @private
184  * Does node support geospatial queries?
185  */
186  uint8_t has_geo;
187 
188 } as_node;
189 
190 /**
191  * @private
192  * Node discovery information.
193  */
194 typedef struct as_node_info_s {
195  /**
196  * @private
197  * Node name.
198  */
199  char name[AS_NODE_NAME_SIZE];
200 
201  /**
202  * @private
203  * Does node support batch-index protocol?
204  */
206 
207  /**
208  * @private
209  * Does node support replicas-all info protocol?
210  */
212 
213  /**
214  * @private
215  * Does node support floating point type?
216  */
217  uint8_t has_double;
218 
219  /**
220  * @private
221  * Does node support geospatial queries?
222  */
223  uint8_t has_geo;
224 
225 } as_node_info;
226 
227 /**
228  * @private
229  * Friend host address information.
230  */
231 typedef struct as_host_s {
232  /**
233  * @private
234  * Hostname or IP address string representation (xxx.xxx.xxx.xxx).
235  */
236  char name[AS_HOSTNAME_SIZE];
237 
238  /**
239  * @private
240  * Socket IP port.
241  */
242  in_port_t port;
243 
244 } as_host;
245 
246 /******************************************************************************
247  * FUNCTIONS
248  ******************************************************************************/
249 
250 /**
251  * @private
252  * Create new cluster node.
253  */
254 as_node*
255 as_node_create(struct as_cluster_s* cluster, as_host* host, struct sockaddr_in* addr, as_node_info* node_info);
256 
257 /**
258  * @private
259  * Close all connections in pool and free resources.
260  */
261 void
262 as_node_destroy(as_node* node);
263 
264 /**
265  * @private
266  * Set node to inactive.
267  */
268 static inline void
270 {
271  // Make volatile write so changes are reflected in other threads.
272  ck_pr_store_8(&node->active, false);
273 }
274 
275 /**
276  * @private
277  * Reserve existing cluster node.
278  */
279 static inline void
281 {
282  //ck_pr_fence_acquire();
283  ck_pr_inc_32(&node->ref_count);
284 }
285 
286 /**
287  * @private
288  * Release existing cluster node.
289  */
290 static inline void
292 {
293  //ck_pr_fence_release();
294 
295  bool destroy;
296  ck_pr_dec_32_zero(&node->ref_count, &destroy);
297 
298  if (destroy) {
299  as_node_destroy(node);
300  }
301 }
302 
303 /**
304  * @private
305  * Add socket address to node addresses.
306  */
307 void
308 as_node_add_address(as_node* node, as_host* host, struct sockaddr_in* addr);
309 
310 /**
311  * @private
312  * Get socket address and name.
313  */
314 static inline struct sockaddr_in*
316 {
317  as_address* address = (as_address *)as_vector_get(&node->addresses, node->address_index);
318  return &address->addr;
319 }
320 
321 /**
322  * Get socket address and name.
323  */
324 static inline as_address*
326 {
327  return (as_address *)as_vector_get(&node->addresses, node->address_index);
328 }
329 
330 /**
331  * @private
332  * Get a connection to the given node from pool and validate. Return 0 on success.
333  */
334 as_status
335 as_node_get_connection(as_error* err, as_node* node, uint64_t deadline_ms, int* fd);
336 
337 /**
338  * @private
339  * Put connection back into pool if pool size < limit. Otherwise, close connection.
340  */
341 static inline void
342 as_node_put_connection(as_node* node, int fd, uint32_t limit)
343 {
344  if (! cf_queue_push_limit(node->conn_q, &fd, limit)) {
345  close(fd);
346  }
347 }
348 
349 /**
350  * @private
351  * Are hosts equal.
352  */
353 static inline bool
355 {
356  return strcmp(h1->name, h2->name) == 0 && h1->port == h2->port;
357 }
358 
359 #ifdef __cplusplus
360 } // end extern "C"
361 #endif