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 "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 } as_node;
148 
149 /**
150  * @private
151  * Friend host address information.
152  */
153 typedef struct as_friend_s {
154  /**
155  * @private
156  * Socket IP address string representation (xxx.xxx.xxx.xxx).
157  */
158  char name[INET_ADDRSTRLEN];
159 
160  /**
161  * @private
162  * Socket IP address.
163  */
164  in_addr_t addr;
165 
166  /**
167  * @private
168  * Socket IP port.
169  */
170  in_port_t port;
171 } as_friend;
172 
173 /******************************************************************************
174  * FUNCTIONS
175  ******************************************************************************/
176 
177 /**
178  * @private
179  * Create new cluster node.
180  */
181 as_node*
182 as_node_create(struct as_cluster_s* cluster, const char* name, struct sockaddr_in* addr);
183 
184 /**
185  * @private
186  * Close all connections in pool and free resources.
187  */
188 void
189 as_node_destroy(as_node* node);
190 
191 /**
192  * @private
193  * Set node to inactive.
194  */
195 static inline void
197 {
198  // Make volatile write so changes are reflected in other threads.
199  ck_pr_store_8(&node->active, false);
200 }
201 
202 /**
203  * @private
204  * Reserve existing cluster node.
205  */
206 static inline void
208 {
209  //ck_pr_fence_acquire();
210  ck_pr_inc_32(&node->ref_count);
211 }
212 
213 /**
214  * @private
215  * Release existing cluster node.
216  */
217 static inline void
219 {
220  //ck_pr_fence_release();
221 
222  bool destroy;
223  ck_pr_dec_32_zero(&node->ref_count, &destroy);
224 
225  if (destroy) {
226  as_node_destroy(node);
227  }
228 }
229 
230 /**
231  * @private
232  * Add socket address to node addresses.
233  */
234 void
235 as_node_add_address(as_node* node, struct sockaddr_in* addr);
236 
237 /**
238  * @private
239  * Get socket address and name.
240  */
241 static inline struct sockaddr_in*
243 {
244  as_address* address = (as_address *)as_vector_get(&node->addresses, node->address_index);
245  return &address->addr;
246 }
247 
248 /**
249  * Get socket address and name.
250  */
251 static inline as_address*
253 {
254  return (as_address *)as_vector_get(&node->addresses, node->address_index);
255 }
256 
257 /**
258  * @private
259  * Get a connection to the given node from pool and validate. Return 0 on success.
260  */
261 as_status
262 as_node_get_connection(as_error* err, as_node* node, int* fd);
263 
264 /**
265  * @private
266  * Put connection back into pool.
267  */
268 void
269 as_node_put_connection(as_node* node, int fd);
270 
271 #ifdef __cplusplus
272 } // end extern "C"
273 #endif