diff options
author | Christian Grothoff <christian@grothoff.org> | 2014-12-23 20:37:22 +0000 |
---|---|---|
committer | Christian Grothoff <christian@grothoff.org> | 2014-12-23 20:37:22 +0000 |
commit | aae8cc8afe0bb827dc1b6601b2e5e3a14b25c2ca (patch) | |
tree | 3fb1c4132525ed37aa217bf6d61a8ae2f0fc3366 /src/datastore | |
parent | eb5224e351e70128f6f0afc4b9e7c5fe90c72213 (diff) | |
download | gnunet-aae8cc8afe0bb827dc1b6601b2e5e3a14b25c2ca.tar.gz gnunet-aae8cc8afe0bb827dc1b6601b2e5e3a14b25c2ca.zip |
fixing datastore-statistics interaction to ensure stats are properly written to disk on exit
Diffstat (limited to 'src/datastore')
-rw-r--r-- | src/datastore/gnunet-service-datastore.c | 349 |
1 files changed, 194 insertions, 155 deletions
diff --git a/src/datastore/gnunet-service-datastore.c b/src/datastore/gnunet-service-datastore.c index 98ef6d797..0aa2273b5 100644 --- a/src/datastore/gnunet-service-datastore.c +++ b/src/datastore/gnunet-service-datastore.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2004, 2005, 2006, 2007, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2004-2014 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
@@ -142,19 +142,19 @@ static struct ReservationList *reservations; | |||
142 | static struct GNUNET_CONTAINER_BloomFilter *filter; | 142 | static struct GNUNET_CONTAINER_BloomFilter *filter; |
143 | 143 | ||
144 | /** | 144 | /** |
145 | * How much space are we allowed to use? | 145 | * Name of our plugin. |
146 | */ | 146 | */ |
147 | static unsigned long long quota; | 147 | static char *plugin_name; |
148 | 148 | ||
149 | /** | 149 | /** |
150 | * Should the database be dropped on exit? | 150 | * Our configuration. |
151 | */ | 151 | */ |
152 | static int do_drop; | 152 | static const struct GNUNET_CONFIGURATION_Handle *cfg; |
153 | 153 | ||
154 | /** | 154 | /** |
155 | * Name of our plugin. | 155 | * Handle for reporting statistics. |
156 | */ | 156 | */ |
157 | static char *plugin_name; | 157 | static struct GNUNET_STATISTICS_Handle *stats; |
158 | 158 | ||
159 | /** | 159 | /** |
160 | * How much space are we using for the cache? (space available for | 160 | * How much space are we using for the cache? (space available for |
@@ -176,40 +176,45 @@ static unsigned long long reserved; | |||
176 | static unsigned long long payload; | 176 | static unsigned long long payload; |
177 | 177 | ||
178 | /** | 178 | /** |
179 | * Number of updates that were made to the | 179 | * Identity of the task that is used to delete |
180 | * payload value since we last synchronized | 180 | * expired content. |
181 | * it with the statistics service. | ||
182 | */ | 181 | */ |
183 | static unsigned int lastSync; | 182 | static GNUNET_SCHEDULER_TaskIdentifier expired_kill_task; |
184 | 183 | ||
185 | /** | 184 | /** |
186 | * Did we get an answer from statistics? | 185 | * Minimum time that content should have to not be discarded instantly |
186 | * (time stamp of any content that we've been discarding recently to | ||
187 | * stay below the quota). FOREVER if we had to expire content with | ||
188 | * non-zero priority. | ||
187 | */ | 189 | */ |
188 | static int stats_worked; | 190 | static struct GNUNET_TIME_Absolute min_expiration; |
189 | 191 | ||
190 | /** | 192 | /** |
191 | * Identity of the task that is used to delete | 193 | * How much space are we allowed to use? |
192 | * expired content. | ||
193 | */ | 194 | */ |
194 | static GNUNET_SCHEDULER_TaskIdentifier expired_kill_task; | 195 | static unsigned long long quota; |
195 | 196 | ||
196 | /** | 197 | /** |
197 | * Our configuration. | 198 | * Should the database be dropped on exit? |
198 | */ | 199 | */ |
199 | const struct GNUNET_CONFIGURATION_Handle *cfg; | 200 | static int do_drop; |
200 | 201 | ||
201 | /** | 202 | /** |
202 | * Minimum time that content should have to not be discarded instantly | 203 | * Should we refresh the BF when the DB is loaded? |
203 | * (time stamp of any content that we've been discarding recently to | ||
204 | * stay below the quota). FOREVER if we had to expire content with | ||
205 | * non-zero priority. | ||
206 | */ | 204 | */ |
207 | static struct GNUNET_TIME_Absolute min_expiration; | 205 | static int refresh_bf; |
208 | 206 | ||
209 | /** | 207 | /** |
210 | * Handle for reporting statistics. | 208 | * Number of updates that were made to the |
209 | * payload value since we last synchronized | ||
210 | * it with the statistics service. | ||
211 | */ | 211 | */ |
212 | static struct GNUNET_STATISTICS_Handle *stats; | 212 | static unsigned int last_sync; |
213 | |||
214 | /** | ||
215 | * Did we get an answer from statistics? | ||
216 | */ | ||
217 | static int stats_worked; | ||
213 | 218 | ||
214 | 219 | ||
215 | /** | 220 | /** |
@@ -221,11 +226,10 @@ sync_stats () | |||
221 | { | 226 | { |
222 | GNUNET_STATISTICS_set (stats, quota_stat_name, payload, GNUNET_YES); | 227 | GNUNET_STATISTICS_set (stats, quota_stat_name, payload, GNUNET_YES); |
223 | GNUNET_STATISTICS_set (stats, "# utilization by current datastore", payload, GNUNET_NO); | 228 | GNUNET_STATISTICS_set (stats, "# utilization by current datastore", payload, GNUNET_NO); |
224 | lastSync = 0; | 229 | last_sync = 0; |
225 | } | 230 | } |
226 | 231 | ||
227 | 232 | ||
228 | |||
229 | /** | 233 | /** |
230 | * Context for transmitting replies to clients. | 234 | * Context for transmitting replies to clients. |
231 | */ | 235 | */ |
@@ -292,7 +296,8 @@ static struct GNUNET_STATISTICS_GetHandle *stat_get; | |||
292 | * @param tc task context | 296 | * @param tc task context |
293 | */ | 297 | */ |
294 | static void | 298 | static void |
295 | delete_expired (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 299 | delete_expired (void *cls, |
300 | const struct GNUNET_SCHEDULER_TaskContext *tc); | ||
296 | 301 | ||
297 | 302 | ||
298 | /** | 303 | /** |
@@ -311,15 +316,20 @@ delete_expired (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | |||
311 | * @param uid unique identifier for the datum; | 316 | * @param uid unique identifier for the datum; |
312 | * maybe 0 if no unique identifier is available | 317 | * maybe 0 if no unique identifier is available |
313 | * | 318 | * |
314 | * @return GNUNET_SYSERR to abort the iteration, GNUNET_OK to continue | 319 | * @return #GNUNET_SYSERR to abort the iteration, #GNUNET_OK to continue |
315 | * (continue on call to "next", of course), | 320 | * (continue on call to "next", of course), |
316 | * GNUNET_NO to delete the item and continue (if supported) | 321 | * #GNUNET_NO to delete the item and continue (if supported) |
317 | */ | 322 | */ |
318 | static int | 323 | static int |
319 | expired_processor (void *cls, const struct GNUNET_HashCode * key, uint32_t size, | 324 | expired_processor (void *cls, |
320 | const void *data, enum GNUNET_BLOCK_Type type, | 325 | const struct GNUNET_HashCode *key, |
321 | uint32_t priority, uint32_t anonymity, | 326 | uint32_t size, |
322 | struct GNUNET_TIME_Absolute expiration, uint64_t uid) | 327 | const void *data, |
328 | enum GNUNET_BLOCK_Type type, | ||
329 | uint32_t priority, | ||
330 | uint32_t anonymity, | ||
331 | struct GNUNET_TIME_Absolute expiration, | ||
332 | uint64_t uid) | ||
323 | { | 333 | { |
324 | struct GNUNET_TIME_Absolute now; | 334 | struct GNUNET_TIME_Absolute now; |
325 | 335 | ||
@@ -564,7 +574,6 @@ transmit_status (struct GNUNET_SERVER_Client *client, int code, const char *msg) | |||
564 | } | 574 | } |
565 | 575 | ||
566 | 576 | ||
567 | |||
568 | /** | 577 | /** |
569 | * Function that will transmit the given datastore entry | 578 | * Function that will transmit the given datastore entry |
570 | * to the client. | 579 | * to the client. |
@@ -719,7 +728,8 @@ handle_reserve (void *cls, struct GNUNET_SERVER_Client *client, | |||
719 | * @param message the actual message | 728 | * @param message the actual message |
720 | */ | 729 | */ |
721 | static void | 730 | static void |
722 | handle_release_reserve (void *cls, struct GNUNET_SERVER_Client *client, | 731 | handle_release_reserve (void *cls, |
732 | struct GNUNET_SERVER_Client *client, | ||
723 | const struct GNUNET_MessageHeader *message) | 733 | const struct GNUNET_MessageHeader *message) |
724 | { | 734 | { |
725 | const struct ReleaseReserveMessage *msg = | 735 | const struct ReleaseReserveMessage *msg = |
@@ -730,7 +740,8 @@ handle_release_reserve (void *cls, struct GNUNET_SERVER_Client *client, | |||
730 | int rid = ntohl (msg->rid); | 740 | int rid = ntohl (msg->rid); |
731 | unsigned long long rem; | 741 | unsigned long long rem; |
732 | 742 | ||
733 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", | 743 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
744 | "Processing `%s' request\n", | ||
734 | "RELEASE_RESERVE"); | 745 | "RELEASE_RESERVE"); |
735 | next = reservations; | 746 | next = reservations; |
736 | prev = NULL; | 747 | prev = NULL; |
@@ -748,7 +759,8 @@ handle_release_reserve (void *cls, struct GNUNET_SERVER_Client *client, | |||
748 | ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * pos->entries; | 759 | ((unsigned long long) GNUNET_DATASTORE_ENTRY_OVERHEAD) * pos->entries; |
749 | GNUNET_assert (reserved >= rem); | 760 | GNUNET_assert (reserved >= rem); |
750 | reserved -= rem; | 761 | reserved -= rem; |
751 | GNUNET_STATISTICS_set (stats, gettext_noop ("# reserved"), reserved, | 762 | GNUNET_STATISTICS_set (stats, |
763 | gettext_noop ("# reserved"), reserved, | ||
752 | GNUNET_NO); | 764 | GNUNET_NO); |
753 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 765 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
754 | "Returning %llu remaining reserved bytes to storage pool\n", | 766 | "Returning %llu remaining reserved bytes to storage pool\n", |
@@ -835,7 +847,8 @@ execute_put (struct GNUNET_SERVER_Client *client, const struct DataMessage *dm) | |||
835 | GNUNET_TIME_absolute_ntoh (dm->expiration), &msg); | 847 | GNUNET_TIME_absolute_ntoh (dm->expiration), &msg); |
836 | if (GNUNET_OK == ret) | 848 | if (GNUNET_OK == ret) |
837 | { | 849 | { |
838 | GNUNET_STATISTICS_update (stats, gettext_noop ("# bytes stored"), size, | 850 | GNUNET_STATISTICS_update (stats, |
851 | gettext_noop ("# bytes stored"), size, | ||
839 | GNUNET_YES); | 852 | GNUNET_YES); |
840 | GNUNET_CONTAINER_bloomfilter_add (filter, &dm->key); | 853 | GNUNET_CONTAINER_bloomfilter_add (filter, &dm->key); |
841 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 854 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -961,7 +974,8 @@ handle_put (void *cls, struct GNUNET_SERVER_Client *client, | |||
961 | pos->entries--; | 974 | pos->entries--; |
962 | pos->amount -= size; | 975 | pos->amount -= size; |
963 | reserved -= (size + GNUNET_DATASTORE_ENTRY_OVERHEAD); | 976 | reserved -= (size + GNUNET_DATASTORE_ENTRY_OVERHEAD); |
964 | GNUNET_STATISTICS_set (stats, gettext_noop ("# reserved"), reserved, | 977 | GNUNET_STATISTICS_set (stats, |
978 | gettext_noop ("# reserved"), reserved, | ||
965 | GNUNET_NO); | 979 | GNUNET_NO); |
966 | } | 980 | } |
967 | } | 981 | } |
@@ -1007,7 +1021,8 @@ handle_get (void *cls, struct GNUNET_SERVER_Client *client, | |||
1007 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1021 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1008 | "Processing `%s' request for `%s' of type %u\n", "GET", | 1022 | "Processing `%s' request for `%s' of type %u\n", "GET", |
1009 | GNUNET_h2s (&msg->key), ntohl (msg->type)); | 1023 | GNUNET_h2s (&msg->key), ntohl (msg->type)); |
1010 | GNUNET_STATISTICS_update (stats, gettext_noop ("# GET requests received"), 1, | 1024 | GNUNET_STATISTICS_update (stats, |
1025 | gettext_noop ("# GET requests received"), 1, | ||
1011 | GNUNET_NO); | 1026 | GNUNET_NO); |
1012 | GNUNET_SERVER_client_keep (client); | 1027 | GNUNET_SERVER_client_keep (client); |
1013 | if ((size == sizeof (struct GetMessage)) && | 1028 | if ((size == sizeof (struct GetMessage)) && |
@@ -1196,7 +1211,9 @@ static void | |||
1196 | handle_drop (void *cls, struct GNUNET_SERVER_Client *client, | 1211 | handle_drop (void *cls, struct GNUNET_SERVER_Client *client, |
1197 | const struct GNUNET_MessageHeader *message) | 1212 | const struct GNUNET_MessageHeader *message) |
1198 | { | 1213 | { |
1199 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, "Processing `%s' request\n", "DROP"); | 1214 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1215 | "Processing `%s' request\n", | ||
1216 | "DROP"); | ||
1200 | do_drop = GNUNET_YES; | 1217 | do_drop = GNUNET_YES; |
1201 | GNUNET_SERVER_receive_done (client, GNUNET_OK); | 1218 | GNUNET_SERVER_receive_done (client, GNUNET_OK); |
1202 | } | 1219 | } |
@@ -1211,21 +1228,25 @@ handle_drop (void *cls, struct GNUNET_SERVER_Client *client, | |||
1211 | * 0 for "reset to empty" | 1228 | * 0 for "reset to empty" |
1212 | */ | 1229 | */ |
1213 | static void | 1230 | static void |
1214 | disk_utilization_change_cb (void *cls, int delta) | 1231 | disk_utilization_change_cb (void *cls, |
1232 | int delta) | ||
1215 | { | 1233 | { |
1216 | if ((delta < 0) && (payload < -delta)) | 1234 | if ((delta < 0) && (payload < -delta)) |
1217 | { | 1235 | { |
1218 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1236 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1219 | _ | 1237 | _("Datastore payload must have been inaccurate (%lld < %lld). Recomputing it.\n"), |
1220 | ("Datastore payload inaccurate (%lld < %lld). Trying to fix.\n"), | 1238 | (long long) payload, |
1221 | (long long) payload, (long long) -delta); | 1239 | (long long) -delta); |
1222 | payload = plugin->api->estimate_size (plugin->api->cls); | 1240 | payload = plugin->api->estimate_size (plugin->api->cls); |
1223 | sync_stats (); | 1241 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1242 | _("New payload: %lld\n"), | ||
1243 | (long long) payload); | ||
1244 | sync_stats (); | ||
1224 | return; | 1245 | return; |
1225 | } | 1246 | } |
1226 | payload += delta; | 1247 | payload += delta; |
1227 | lastSync++; | 1248 | last_sync++; |
1228 | if (lastSync >= MAX_STAT_SYNC_LAG) | 1249 | if (last_sync >= MAX_STAT_SYNC_LAG) |
1229 | sync_stats (); | 1250 | sync_stats (); |
1230 | } | 1251 | } |
1231 | 1252 | ||
@@ -1237,14 +1258,17 @@ disk_utilization_change_cb (void *cls, int delta) | |||
1237 | * @param subsystem name of subsystem that created the statistic | 1258 | * @param subsystem name of subsystem that created the statistic |
1238 | * @param name the name of the datum | 1259 | * @param name the name of the datum |
1239 | * @param value the current value | 1260 | * @param value the current value |
1240 | * @param is_persistent GNUNET_YES if the value is persistent, GNUNET_NO if not | 1261 | * @param is_persistent #GNUNET_YES if the value is persistent, #GNUNET_NO if not |
1241 | * @return GNUNET_OK to continue, GNUNET_SYSERR to abort iteration | 1262 | * @return #GNUNET_OK to continue, #GNUNET_SYSERR to abort iteration |
1242 | */ | 1263 | */ |
1243 | static int | 1264 | static int |
1244 | process_stat_in (void *cls, const char *subsystem, const char *name, | 1265 | process_stat_in (void *cls, |
1245 | uint64_t value, int is_persistent) | 1266 | const char *subsystem, |
1267 | const char *name, | ||
1268 | uint64_t value, | ||
1269 | int is_persistent) | ||
1246 | { | 1270 | { |
1247 | GNUNET_assert (stats_worked == GNUNET_NO); | 1271 | GNUNET_assert (GNUNET_NO == stats_worked); |
1248 | stats_worked = GNUNET_YES; | 1272 | stats_worked = GNUNET_YES; |
1249 | payload += value; | 1273 | payload += value; |
1250 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 1274 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
@@ -1254,17 +1278,6 @@ process_stat_in (void *cls, const char *subsystem, const char *name, | |||
1254 | } | 1278 | } |
1255 | 1279 | ||
1256 | 1280 | ||
1257 | static void | ||
1258 | process_stat_done (void *cls, int success) | ||
1259 | { | ||
1260 | struct DatastorePlugin *plugin = cls; | ||
1261 | |||
1262 | stat_get = NULL; | ||
1263 | if (stats_worked == GNUNET_NO) | ||
1264 | payload = plugin->api->estimate_size (plugin->api->cls); | ||
1265 | } | ||
1266 | |||
1267 | |||
1268 | /** | 1281 | /** |
1269 | * Load the datastore plugin. | 1282 | * Load the datastore plugin. |
1270 | */ | 1283 | */ |
@@ -1278,16 +1291,20 @@ load_plugin () | |||
1278 | ret->env.cfg = cfg; | 1291 | ret->env.cfg = cfg; |
1279 | ret->env.duc = &disk_utilization_change_cb; | 1292 | ret->env.duc = &disk_utilization_change_cb; |
1280 | ret->env.cls = NULL; | 1293 | ret->env.cls = NULL; |
1281 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, _("Loading `%s' datastore plugin\n"), | 1294 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1295 | _("Loading `%s' datastore plugin\n"), | ||
1282 | plugin_name); | 1296 | plugin_name); |
1283 | GNUNET_asprintf (&libname, "libgnunet_plugin_datastore_%s", plugin_name); | 1297 | GNUNET_asprintf (&libname, |
1298 | "libgnunet_plugin_datastore_%s", | ||
1299 | plugin_name); | ||
1284 | ret->short_name = GNUNET_strdup (plugin_name); | 1300 | ret->short_name = GNUNET_strdup (plugin_name); |
1285 | ret->lib_name = libname; | 1301 | ret->lib_name = libname; |
1286 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); | 1302 | ret->api = GNUNET_PLUGIN_load (libname, &ret->env); |
1287 | if (ret->api == NULL) | 1303 | if (NULL == ret->api) |
1288 | { | 1304 | { |
1289 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1305 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1290 | _("Failed to load datastore plugin for `%s'\n"), plugin_name); | 1306 | _("Failed to load datastore plugin for `%s'\n"), |
1307 | plugin_name); | ||
1291 | GNUNET_free (ret->short_name); | 1308 | GNUNET_free (ret->short_name); |
1292 | GNUNET_free (libname); | 1309 | GNUNET_free (libname); |
1293 | GNUNET_free (ret); | 1310 | GNUNET_free (ret); |
@@ -1312,50 +1329,85 @@ unload_plugin (struct DatastorePlugin *plug) | |||
1312 | GNUNET_free (plug->lib_name); | 1329 | GNUNET_free (plug->lib_name); |
1313 | GNUNET_free (plug->short_name); | 1330 | GNUNET_free (plug->short_name); |
1314 | GNUNET_free (plug); | 1331 | GNUNET_free (plug); |
1315 | GNUNET_free (quota_stat_name); | ||
1316 | quota_stat_name = NULL; | ||
1317 | } | 1332 | } |
1318 | 1333 | ||
1319 | 1334 | ||
1320 | /** | 1335 | /** |
1321 | * Final task run after shutdown. Unloads plugins and disconnects us from | 1336 | * Adds a given @a key to the bloomfilter in @a cls @a count times. |
1322 | * statistics. | 1337 | * |
1338 | * @param cls the bloomfilter | ||
1339 | * @param key key to add | ||
1340 | * @param count number of times to add key | ||
1323 | */ | 1341 | */ |
1324 | static void | 1342 | static void |
1325 | unload_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1343 | add_key_to_bloomfilter (void *cls, |
1344 | const struct GNUNET_HashCode *key, | ||
1345 | unsigned int count) | ||
1326 | { | 1346 | { |
1327 | if (lastSync > 0) | 1347 | struct GNUNET_CONTAINER_BloomFilter *bf = cls; |
1328 | sync_stats (); | 1348 | |
1329 | if (GNUNET_YES == do_drop) | 1349 | while (0 < count--) |
1330 | plugin->api->drop (plugin->api->cls); | 1350 | GNUNET_CONTAINER_bloomfilter_add (bf, key); |
1331 | unload_plugin (plugin); | 1351 | } |
1332 | plugin = NULL; | 1352 | |
1333 | if (filter != NULL) | 1353 | |
1354 | /** | ||
1355 | * We finished receiving the statistic. Initialize the plugin; if | ||
1356 | * loading the statistic failed, run the estimator. | ||
1357 | * | ||
1358 | * @param cls NULL | ||
1359 | * @param success #GNUNET_NO if we failed to read the stat | ||
1360 | */ | ||
1361 | static void | ||
1362 | process_stat_done (void *cls, int success) | ||
1363 | { | ||
1364 | stat_get = NULL; | ||
1365 | plugin = load_plugin (); | ||
1366 | if (NULL == plugin) | ||
1334 | { | 1367 | { |
1335 | GNUNET_CONTAINER_bloomfilter_free (filter); | 1368 | GNUNET_CONTAINER_bloomfilter_free (filter); |
1336 | filter = NULL; | 1369 | filter = NULL; |
1370 | if (NULL != stats) | ||
1371 | { | ||
1372 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); | ||
1373 | stats = NULL; | ||
1374 | } | ||
1375 | return; | ||
1337 | } | 1376 | } |
1338 | if (stat_get != NULL) | 1377 | if (GNUNET_NO == stats_worked) |
1339 | { | 1378 | { |
1340 | GNUNET_STATISTICS_get_cancel (stat_get); | 1379 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
1341 | stat_get = NULL; | 1380 | "Failed to obtain value from statistics service, recomputing it\n"); |
1381 | payload = plugin->api->estimate_size (plugin->api->cls); | ||
1342 | } | 1382 | } |
1343 | if (stats != NULL) | 1383 | if (GNUNET_YES == refresh_bf) |
1344 | { | 1384 | { |
1345 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); | 1385 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, |
1346 | stats = NULL; | 1386 | _("Rebuilding bloomfilter. Please be patient.\n")); |
1387 | if (NULL != plugin->api->get_keys) | ||
1388 | plugin->api->get_keys (plugin->api->cls, | ||
1389 | &add_key_to_bloomfilter, | ||
1390 | filter); | ||
1391 | else | ||
1392 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1393 | _("Plugin does not support get_keys function. Please fix!\n")); | ||
1394 | |||
1395 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1396 | _("Bloomfilter construction complete.\n")); | ||
1347 | } | 1397 | } |
1348 | GNUNET_free_non_null (plugin_name); | 1398 | expired_kill_task |
1349 | plugin_name = NULL; | 1399 | = GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, |
1400 | &delete_expired, | ||
1401 | NULL); | ||
1350 | } | 1402 | } |
1351 | 1403 | ||
1352 | 1404 | ||
1353 | /** | 1405 | /** |
1354 | * Last task run during shutdown. Disconnects us from | 1406 | * Task run during shutdown. |
1355 | * the transport and core. | ||
1356 | */ | 1407 | */ |
1357 | static void | 1408 | static void |
1358 | cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1409 | cleaning_task (void *cls, |
1410 | const struct GNUNET_SCHEDULER_TaskContext *tc) | ||
1359 | { | 1411 | { |
1360 | struct TransmitCallbackContext *tcc; | 1412 | struct TransmitCallbackContext *tcc; |
1361 | 1413 | ||
@@ -1376,8 +1428,31 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1376 | GNUNET_SCHEDULER_cancel (expired_kill_task); | 1428 | GNUNET_SCHEDULER_cancel (expired_kill_task); |
1377 | expired_kill_task = GNUNET_SCHEDULER_NO_TASK; | 1429 | expired_kill_task = GNUNET_SCHEDULER_NO_TASK; |
1378 | } | 1430 | } |
1379 | GNUNET_SCHEDULER_add_continuation (&unload_task, NULL, | 1431 | if (GNUNET_YES == do_drop) |
1380 | GNUNET_SCHEDULER_REASON_PREREQ_DONE); | 1432 | plugin->api->drop (plugin->api->cls); |
1433 | unload_plugin (plugin); | ||
1434 | plugin = NULL; | ||
1435 | if (NULL != filter) | ||
1436 | { | ||
1437 | GNUNET_CONTAINER_bloomfilter_free (filter); | ||
1438 | filter = NULL; | ||
1439 | } | ||
1440 | if (NULL != stat_get) | ||
1441 | { | ||
1442 | GNUNET_STATISTICS_get_cancel (stat_get); | ||
1443 | stat_get = NULL; | ||
1444 | } | ||
1445 | GNUNET_free_non_null (plugin_name); | ||
1446 | plugin_name = NULL; | ||
1447 | if (last_sync > 0) | ||
1448 | sync_stats (); | ||
1449 | if (NULL != stats) | ||
1450 | { | ||
1451 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); | ||
1452 | stats = NULL; | ||
1453 | } | ||
1454 | GNUNET_free (quota_stat_name); | ||
1455 | quota_stat_name = NULL; | ||
1381 | } | 1456 | } |
1382 | 1457 | ||
1383 | 1458 | ||
@@ -1390,13 +1465,14 @@ cleaning_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1390 | * @param client identification of the client | 1465 | * @param client identification of the client |
1391 | */ | 1466 | */ |
1392 | static void | 1467 | static void |
1393 | cleanup_reservations (void *cls, struct GNUNET_SERVER_Client *client) | 1468 | cleanup_reservations (void *cls, |
1469 | struct GNUNET_SERVER_Client *client) | ||
1394 | { | 1470 | { |
1395 | struct ReservationList *pos; | 1471 | struct ReservationList *pos; |
1396 | struct ReservationList *prev; | 1472 | struct ReservationList *prev; |
1397 | struct ReservationList *next; | 1473 | struct ReservationList *next; |
1398 | 1474 | ||
1399 | if (client == NULL) | 1475 | if (NULL == client) |
1400 | return; | 1476 | return; |
1401 | prev = NULL; | 1477 | prev = NULL; |
1402 | pos = reservations; | 1478 | pos = reservations; |
@@ -1424,24 +1500,6 @@ cleanup_reservations (void *cls, struct GNUNET_SERVER_Client *client) | |||
1424 | 1500 | ||
1425 | 1501 | ||
1426 | /** | 1502 | /** |
1427 | * Adds a given key to the bloomfilter 'count' times. | ||
1428 | * | ||
1429 | * @param cls the bloomfilter | ||
1430 | * @param key key to add | ||
1431 | * @param count number of times to add key | ||
1432 | */ | ||
1433 | static void | ||
1434 | add_key_to_bloomfilter (void *cls, | ||
1435 | const struct GNUNET_HashCode *key, | ||
1436 | unsigned int count) | ||
1437 | { | ||
1438 | struct GNUNET_CONTAINER_BloomFilter *bf = cls; | ||
1439 | while (0 < count--) | ||
1440 | GNUNET_CONTAINER_bloomfilter_add (bf, key); | ||
1441 | } | ||
1442 | |||
1443 | |||
1444 | /** | ||
1445 | * Process datastore requests. | 1503 | * Process datastore requests. |
1446 | * | 1504 | * |
1447 | * @param cls closure | 1505 | * @param cls closure |
@@ -1449,7 +1507,8 @@ add_key_to_bloomfilter (void *cls, | |||
1449 | * @param c configuration to use | 1507 | * @param c configuration to use |
1450 | */ | 1508 | */ |
1451 | static void | 1509 | static void |
1452 | run (void *cls, struct GNUNET_SERVER_Handle *server, | 1510 | run (void *cls, |
1511 | struct GNUNET_SERVER_Handle *server, | ||
1453 | const struct GNUNET_CONFIGURATION_Handle *c) | 1512 | const struct GNUNET_CONFIGURATION_Handle *c) |
1454 | { | 1513 | { |
1455 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { | 1514 | static const struct GNUNET_SERVER_MessageHandler handlers[] = { |
@@ -1476,7 +1535,6 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1476 | char *fn; | 1535 | char *fn; |
1477 | char *pfn; | 1536 | char *pfn; |
1478 | unsigned int bf_size; | 1537 | unsigned int bf_size; |
1479 | int refresh_bf; | ||
1480 | 1538 | ||
1481 | cfg = c; | 1539 | cfg = c; |
1482 | if (GNUNET_OK != | 1540 | if (GNUNET_OK != |
@@ -1516,11 +1574,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1516 | { | 1574 | { |
1517 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, | 1575 | GNUNET_log (GNUNET_ERROR_TYPE_WARNING, |
1518 | _("Could not use specified filename `%s' for bloomfilter.\n"), | 1576 | _("Could not use specified filename `%s' for bloomfilter.\n"), |
1519 | fn != NULL ? fn : ""); | 1577 | NULL != fn ? fn : ""); |
1520 | GNUNET_free_non_null (fn); | 1578 | GNUNET_free_non_null (fn); |
1521 | fn = NULL; | 1579 | fn = NULL; |
1522 | } | 1580 | } |
1523 | if (fn != NULL) | 1581 | if (NULL != fn) |
1524 | { | 1582 | { |
1525 | GNUNET_asprintf (&pfn, "%s.%s", fn, plugin_name); | 1583 | GNUNET_asprintf (&pfn, "%s.%s", fn, plugin_name); |
1526 | if (GNUNET_YES == GNUNET_DISK_file_test (pfn)) | 1584 | if (GNUNET_YES == GNUNET_DISK_file_test (pfn)) |
@@ -1576,23 +1634,11 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1576 | refresh_bf = GNUNET_YES; | 1634 | refresh_bf = GNUNET_YES; |
1577 | } | 1635 | } |
1578 | GNUNET_free_non_null (fn); | 1636 | GNUNET_free_non_null (fn); |
1579 | if (filter == NULL) | 1637 | if (NULL == filter) |
1580 | { | 1638 | { |
1581 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | 1639 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, |
1582 | _("Failed to initialize bloomfilter.\n")); | 1640 | _("Failed to initialize bloomfilter.\n")); |
1583 | if (stats != NULL) | 1641 | if (NULL != stats) |
1584 | { | ||
1585 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); | ||
1586 | stats = NULL; | ||
1587 | } | ||
1588 | return; | ||
1589 | } | ||
1590 | plugin = load_plugin (); | ||
1591 | if (NULL == plugin) | ||
1592 | { | ||
1593 | GNUNET_CONTAINER_bloomfilter_free (filter); | ||
1594 | filter = NULL; | ||
1595 | if (stats != NULL) | ||
1596 | { | 1642 | { |
1597 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); | 1643 | GNUNET_STATISTICS_destroy (stats, GNUNET_YES); |
1598 | stats = NULL; | 1644 | stats = NULL; |
@@ -1600,28 +1646,19 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1600 | return; | 1646 | return; |
1601 | } | 1647 | } |
1602 | stat_get = | 1648 | stat_get = |
1603 | GNUNET_STATISTICS_get (stats, "datastore", quota_stat_name, | 1649 | GNUNET_STATISTICS_get (stats, |
1604 | GNUNET_TIME_UNIT_SECONDS, &process_stat_done, | 1650 | "datastore", |
1605 | &process_stat_in, plugin); | 1651 | quota_stat_name, |
1606 | GNUNET_SERVER_disconnect_notify (server, &cleanup_reservations, NULL); | 1652 | GNUNET_TIME_UNIT_SECONDS, |
1653 | &process_stat_done, | ||
1654 | &process_stat_in, | ||
1655 | NULL); | ||
1656 | GNUNET_SERVER_disconnect_notify (server, | ||
1657 | &cleanup_reservations, | ||
1658 | NULL); | ||
1607 | GNUNET_SERVER_add_handlers (server, handlers); | 1659 | GNUNET_SERVER_add_handlers (server, handlers); |
1608 | if (GNUNET_YES == refresh_bf) | 1660 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, |
1609 | { | 1661 | &cleaning_task, |
1610 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1611 | _("Rebuilding bloomfilter. Please be patient.\n")); | ||
1612 | if (NULL != plugin->api->get_keys) | ||
1613 | plugin->api->get_keys (plugin->api->cls, &add_key_to_bloomfilter, filter); | ||
1614 | else | ||
1615 | GNUNET_log (GNUNET_ERROR_TYPE_ERROR, | ||
1616 | _("Plugin does not support get_keys function. Please fix!\n")); | ||
1617 | |||
1618 | GNUNET_log (GNUNET_ERROR_TYPE_INFO, | ||
1619 | _("Bloomfilter construction complete.\n")); | ||
1620 | } | ||
1621 | expired_kill_task = | ||
1622 | GNUNET_SCHEDULER_add_with_priority (GNUNET_SCHEDULER_PRIORITY_IDLE, | ||
1623 | &delete_expired, NULL); | ||
1624 | GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_UNIT_FOREVER_REL, &cleaning_task, | ||
1625 | NULL); | 1662 | NULL); |
1626 | } | 1663 | } |
1627 | 1664 | ||
@@ -1634,13 +1671,15 @@ run (void *cls, struct GNUNET_SERVER_Handle *server, | |||
1634 | * @return 0 ok, 1 on error | 1671 | * @return 0 ok, 1 on error |
1635 | */ | 1672 | */ |
1636 | int | 1673 | int |
1637 | main (int argc, char *const *argv) | 1674 | main (int argc, |
1675 | char *const *argv) | ||
1638 | { | 1676 | { |
1639 | int ret; | 1677 | int ret; |
1640 | 1678 | ||
1641 | ret = | 1679 | ret = |
1642 | (GNUNET_OK == | 1680 | (GNUNET_OK == |
1643 | GNUNET_SERVICE_run (argc, argv, "datastore", GNUNET_SERVICE_OPTION_NONE, | 1681 | GNUNET_SERVICE_run (argc, argv, "datastore", |
1682 | GNUNET_SERVICE_OPTION_NONE, | ||
1644 | &run, NULL)) ? 0 : 1; | 1683 | &run, NULL)) ? 0 : 1; |
1645 | return ret; | 1684 | return ret; |
1646 | } | 1685 | } |