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