diff --git a/src/ssb.c b/src/ssb.c index 8b706c21..f5f51e0f 100644 --- a/src/ssb.c +++ b/src/ssb.c @@ -25,6 +25,10 @@ #include #include +#if !defined(_countof) +#define _countof(a) ((int)(sizeof((a)) / sizeof(*(a)))) +#endif + static_assert(k_id_base64_len == sodium_base64_ENCODED_LEN(9 + crypto_box_PUBLICKEYBYTES, sodium_base64_VARIANT_ORIGINAL), "k_id_base64_len"); static_assert(k_id_bin_len == crypto_box_PUBLICKEYBYTES, "k_id_bin_len"); static_assert(k_blob_id_len == (sodium_base64_ENCODED_LEN(crypto_hash_sha256_BYTES, sodium_base64_VARIANT_ORIGINAL) + 8), "k_blob_id_len"); @@ -135,6 +139,7 @@ typedef struct _tf_ssb_t { uv_udp_t broadcast_listener; uv_udp_t broadcast_sender; uv_timer_t broadcast_timer; + uv_timer_t trace_timer; uv_tcp_t server; uint8_t pub[crypto_sign_PUBLICKEYBYTES]; @@ -1455,6 +1460,57 @@ static bool _tf_ssb_save_keys(tf_ssb_t* ssb) return result; } +static void _tf_ssb_trace_timer(uv_timer_t* timer) +{ + tf_ssb_t* ssb = timer->data; + int connections = 0; + int broadcasts = 0; + int rpc = 0; + int connections_changed = 0; + int message_added = 0; + int blob_want_added = 0; + int broadcasts_changed = 0; + +#define COUNT(type, name) \ + for (type* it = ssb->name; it; it = it->next) \ + { \ + name++; \ + } + + COUNT(tf_ssb_connection_t, connections); + COUNT(tf_ssb_broadcast_t, broadcasts); + COUNT(tf_ssb_rpc_callback_node_t, rpc); + COUNT(tf_ssb_connections_changed_callback_node_t, connections_changed); + COUNT(tf_ssb_message_added_callback_node_t, message_added); + COUNT(tf_ssb_blob_want_added_callback_node_t, blob_want_added); + COUNT(tf_ssb_broadcasts_changed_callback_node_t, broadcasts_changed); + +#undef COUNT + + const char* names[] = + { + "connections", + "broadcasts", + "rpc", + "connections_changed", + "message_added", + "blob_want_added", + "broadcasts_changed", + }; + int64_t values[] = + { + connections, + broadcasts, + rpc, + connections_changed, + message_added, + blob_want_added, + broadcasts_changed, + }; + + tf_trace_counter(ssb->trace, "lists", _countof(values), names, values); +} + tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db, const char* secrets_path) { tf_ssb_t* ssb = malloc(sizeof(tf_ssb_t)); @@ -1512,6 +1568,11 @@ tf_ssb_t* tf_ssb_create(uv_loop_t* loop, JSContext* context, sqlite3* db, const uv_udp_bind(&ssb->broadcast_sender, (struct sockaddr*)&broadcast_from, 0); uv_udp_set_broadcast(&ssb->broadcast_sender, 1); + ssb->trace_timer.data = ssb; + uv_timer_init(ssb->loop, &ssb->trace_timer); + uv_timer_start(&ssb->trace_timer, _tf_ssb_trace_timer, 100, 100); + uv_unref((uv_handle_t*)&ssb->trace_timer); + if (!_tf_ssb_load_keys(ssb)) { printf("Generating a new keypair.\n"); @@ -1583,6 +1644,11 @@ void tf_ssb_destroy(tf_ssb_t* ssb) uv_close((uv_handle_t*)&ssb->broadcast_timer, _tf_ssb_on_handle_close); } + if (ssb->trace_timer.data && !uv_is_closing((uv_handle_t*)&ssb->trace_timer)) + { + uv_close((uv_handle_t*)&ssb->trace_timer, _tf_ssb_on_handle_close); + } + if (ssb->server.data && !uv_is_closing((uv_handle_t*)&ssb->server)) { uv_close((uv_handle_t*)&ssb->server, _tf_ssb_on_handle_close); @@ -1591,6 +1657,7 @@ void tf_ssb_destroy(tf_ssb_t* ssb) while (ssb->broadcast_listener.data || ssb->broadcast_sender.data || ssb->broadcast_timer.data || + ssb->trace_timer.data || ssb->server.data) { uv_run(ssb->loop, UV_RUN_ONCE);