diff options
author | Omar Tarabai <tarabai@devegypt.com> | 2014-05-31 21:48:01 +0000 |
---|---|---|
committer | Omar Tarabai <tarabai@devegypt.com> | 2014-05-31 21:48:01 +0000 |
commit | 805d4a3556dee6d13ad5a9439b7a4a9ef3f9ab46 (patch) | |
tree | 63473a907807a2aadb7780353b4ad34ee6a041fa /src/peerstore/gnunet-service-peerstore.c | |
parent | 95cdeb5c0bb1f14f3959863e6bf4675db48ea177 (diff) | |
download | gnunet-805d4a3556dee6d13ad5a9439b7a4a9ef3f9ab46.tar.gz gnunet-805d4a3556dee6d13ad5a9439b7a4a9ef3f9ab46.zip |
peerstore: watch functionality
Diffstat (limited to 'src/peerstore/gnunet-service-peerstore.c')
-rw-r--r-- | src/peerstore/gnunet-service-peerstore.c | 94 |
1 files changed, 72 insertions, 22 deletions
diff --git a/src/peerstore/gnunet-service-peerstore.c b/src/peerstore/gnunet-service-peerstore.c index 70d79ea5e..706fcaaae 100644 --- a/src/peerstore/gnunet-service-peerstore.c +++ b/src/peerstore/gnunet-service-peerstore.c | |||
@@ -73,6 +73,11 @@ static struct GNUNET_PEERSTORE_PluginFunctions *db; | |||
73 | static struct GNUNET_CONTAINER_MultiHashMap *watchers; | 73 | static struct GNUNET_CONTAINER_MultiHashMap *watchers; |
74 | 74 | ||
75 | /** | 75 | /** |
76 | * Our notification context. | ||
77 | */ | ||
78 | static struct GNUNET_SERVER_NotificationContext *nc; | ||
79 | |||
80 | /** | ||
76 | * Task run during shutdown. | 81 | * Task run during shutdown. |
77 | * | 82 | * |
78 | * @param cls unused | 83 | * @param cls unused |
@@ -88,8 +93,8 @@ shutdown_task (void *cls, | |||
88 | GNUNET_free (db_lib_name); | 93 | GNUNET_free (db_lib_name); |
89 | db_lib_name = NULL; | 94 | db_lib_name = NULL; |
90 | } | 95 | } |
91 | if(NULL != watchers) | 96 | GNUNET_SERVER_notification_context_destroy(nc); |
92 | GNUNET_CONTAINER_multihashmap_destroy(watchers); | 97 | GNUNET_CONTAINER_multihashmap_destroy(watchers); |
93 | GNUNET_SCHEDULER_shutdown(); | 98 | GNUNET_SCHEDULER_shutdown(); |
94 | } | 99 | } |
95 | 100 | ||
@@ -154,6 +159,60 @@ int record_iterator(void *cls, | |||
154 | } | 159 | } |
155 | 160 | ||
156 | /** | 161 | /** |
162 | * Iterator over all watcher clients | ||
163 | * to notify them of a new record | ||
164 | * | ||
165 | * @param cls closuer, a 'struct GNUNET_PEERSTORE_Record *' | ||
166 | * @param key hash of record key | ||
167 | * @param value the watcher client, a 'struct GNUNET_SERVER_Client *' | ||
168 | * @return #GNUNET_YES to continue iterating | ||
169 | */ | ||
170 | int watch_notifier_it(void *cls, | ||
171 | const struct GNUNET_HashCode *key, | ||
172 | void *value) | ||
173 | { | ||
174 | struct GNUNET_PEERSTORE_Record *record = cls; | ||
175 | struct GNUNET_SERVER_Client *client = value; | ||
176 | struct StoreRecordMessage *srm; | ||
177 | |||
178 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Found a watcher to update.\n"); | ||
179 | if(NULL == value) | ||
180 | { | ||
181 | GNUNET_CONTAINER_multihashmap_remove(watchers, key, value); | ||
182 | return GNUNET_YES; | ||
183 | } | ||
184 | srm = PEERSTORE_create_record_message(record->sub_system, | ||
185 | record->peer, | ||
186 | record->key, | ||
187 | record->value, | ||
188 | record->value_size, | ||
189 | record->expiry, | ||
190 | GNUNET_MESSAGE_TYPE_PEERSTORE_WATCH_RECORD); | ||
191 | GNUNET_SERVER_notification_context_unicast(nc, client, | ||
192 | (const struct GNUNET_MessageHeader *)srm, GNUNET_YES); | ||
193 | return GNUNET_YES; | ||
194 | } | ||
195 | |||
196 | /** | ||
197 | * Given a new record, notifies watchers | ||
198 | * | ||
199 | * @cls closure, a 'struct GNUNET_PEERSTORE_Record *' | ||
200 | * @tc unused | ||
201 | */ | ||
202 | void watch_notifier (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
203 | { | ||
204 | struct GNUNET_PEERSTORE_Record *record = cls; | ||
205 | struct GNUNET_HashCode keyhash; | ||
206 | |||
207 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "Sending update to any watchers.\n"); | ||
208 | PEERSTORE_hash_key(record->sub_system, | ||
209 | record->peer, | ||
210 | record->key, | ||
211 | &keyhash); | ||
212 | GNUNET_CONTAINER_multihashmap_get_multiple(watchers, &keyhash, &watch_notifier_it, record); | ||
213 | } | ||
214 | |||
215 | /** | ||
157 | * Handle a watch cancel request from client | 216 | * Handle a watch cancel request from client |
158 | * | 217 | * |
159 | * @param cls unused | 218 | * @param cls unused |
@@ -167,13 +226,6 @@ void handle_watch_cancel (void *cls, | |||
167 | struct StoreKeyHashMessage *hm; | 226 | struct StoreKeyHashMessage *hm; |
168 | 227 | ||
169 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received a watch cancel request from client.\n"); | 228 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received a watch cancel request from client.\n"); |
170 | if(NULL == watchers) | ||
171 | { | ||
172 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
173 | "Received a watch cancel request when we don't have any watchers.\n"); | ||
174 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | ||
175 | return; | ||
176 | } | ||
177 | hm = (struct StoreKeyHashMessage *) message; | 229 | hm = (struct StoreKeyHashMessage *) message; |
178 | GNUNET_CONTAINER_multihashmap_remove(watchers, &hm->keyhash, client); | 230 | GNUNET_CONTAINER_multihashmap_remove(watchers, &hm->keyhash, client); |
179 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | 231 | GNUNET_SERVER_receive_done(client, GNUNET_OK); |
@@ -195,8 +247,7 @@ void handle_watch (void *cls, | |||
195 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received a watch request from client.\n"); | 247 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Received a watch request from client.\n"); |
196 | hm = (struct StoreKeyHashMessage *) message; | 248 | hm = (struct StoreKeyHashMessage *) message; |
197 | GNUNET_SERVER_client_mark_monitor(client); | 249 | GNUNET_SERVER_client_mark_monitor(client); |
198 | if(NULL == watchers) | 250 | GNUNET_SERVER_notification_context_add(nc, client); |
199 | watchers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); | ||
200 | GNUNET_CONTAINER_multihashmap_put(watchers, &hm->keyhash, | 251 | GNUNET_CONTAINER_multihashmap_put(watchers, &hm->keyhash, |
201 | client, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); | 252 | client, GNUNET_CONTAINER_MULTIHASHMAPOPTION_MULTIPLE); |
202 | GNUNET_SERVER_receive_done(client, GNUNET_OK); | 253 | GNUNET_SERVER_receive_done(client, GNUNET_OK); |
@@ -246,7 +297,7 @@ void handle_iterate (void *cls, | |||
246 | GNUNET_free(tc); | 297 | GNUNET_free(tc); |
247 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | 298 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); |
248 | } | 299 | } |
249 | GNUNET_free(record); | 300 | GNUNET_free(record); /* FIXME: destroy record */ |
250 | } | 301 | } |
251 | 302 | ||
252 | /** | 303 | /** |
@@ -261,7 +312,6 @@ void handle_store (void *cls, | |||
261 | const struct GNUNET_MessageHeader *message) | 312 | const struct GNUNET_MessageHeader *message) |
262 | { | 313 | { |
263 | struct GNUNET_PEERSTORE_Record *record; | 314 | struct GNUNET_PEERSTORE_Record *record; |
264 | uint16_t response_type; | ||
265 | struct GNUNET_SERVER_TransmitContext *tc; | 315 | struct GNUNET_SERVER_TransmitContext *tc; |
266 | 316 | ||
267 | record = PEERSTORE_parse_record_message(message); | 317 | record = PEERSTORE_parse_record_message(message); |
@@ -275,6 +325,7 @@ void handle_store (void *cls, | |||
275 | || NULL == record->peer | 325 | || NULL == record->peer |
276 | || NULL == record->key) | 326 | || NULL == record->key) |
277 | { | 327 | { |
328 | /* FIXME: Destroy record */ | ||
278 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Full key not supplied in client store request\n"); | 329 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Full key not supplied in client store request\n"); |
279 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); | 330 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); |
280 | return; | 331 | return; |
@@ -284,7 +335,7 @@ void handle_store (void *cls, | |||
284 | record->sub_system, | 335 | record->sub_system, |
285 | GNUNET_i2s (record->peer), | 336 | GNUNET_i2s (record->peer), |
286 | record->key); | 337 | record->key); |
287 | if(GNUNET_OK == db->store_record(db->cls, | 338 | if(GNUNET_OK != db->store_record(db->cls, |
288 | record->sub_system, | 339 | record->sub_system, |
289 | record->peer, | 340 | record->peer, |
290 | record->key, | 341 | record->key, |
@@ -292,18 +343,15 @@ void handle_store (void *cls, | |||
292 | record->value_size, | 343 | record->value_size, |
293 | *record->expiry)) | 344 | *record->expiry)) |
294 | { | 345 | { |
295 | response_type = GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK; | 346 | /* FIXME: Destroy record */ |
296 | } | ||
297 | else | ||
298 | { | ||
299 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to store requested value, sqlite database error."); | 347 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Failed to store requested value, sqlite database error."); |
300 | response_type = GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_FAIL; | 348 | GNUNET_SERVER_receive_done(client, GNUNET_SYSERR); |
349 | return; | ||
301 | } | 350 | } |
302 | |||
303 | tc = GNUNET_SERVER_transmit_context_create (client); | 351 | tc = GNUNET_SERVER_transmit_context_create (client); |
304 | GNUNET_SERVER_transmit_context_append_data(tc, NULL, 0, response_type); | 352 | GNUNET_SERVER_transmit_context_append_data(tc, NULL, 0, GNUNET_MESSAGE_TYPE_PEERSTORE_STORE_RESULT_OK); |
305 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); | 353 | GNUNET_SERVER_transmit_context_run (tc, GNUNET_TIME_UNIT_FOREVER_REL); |
306 | //TODO: notify watchers, if a client is disconnected, remove its watch entry | 354 | GNUNET_SCHEDULER_add_continuation(&watch_notifier, record, -1); |
307 | } | 355 | } |
308 | 356 | ||
309 | /** | 357 | /** |
@@ -343,6 +391,8 @@ run (void *cls, | |||
343 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n", db_lib_name); | 391 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, "Could not load database backend `%s'\n", db_lib_name); |
344 | else | 392 | else |
345 | { | 393 | { |
394 | nc = GNUNET_SERVER_notification_context_create (server, 16); | ||
395 | watchers = GNUNET_CONTAINER_multihashmap_create(10, GNUNET_NO); | ||
346 | GNUNET_SCHEDULER_add_now(&cleanup_expired_records, NULL); | 396 | GNUNET_SCHEDULER_add_now(&cleanup_expired_records, NULL); |
347 | GNUNET_SERVER_add_handlers (server, handlers); | 397 | GNUNET_SERVER_add_handlers (server, handlers); |
348 | GNUNET_SERVER_disconnect_notify (server, | 398 | GNUNET_SERVER_disconnect_notify (server, |