Line data Source code
1 : #include "fd_catchup.h" 2 : #include <stdio.h> 3 : 4 : #include "../types/fd_types.h" 5 : #include "../../disco/metrics/fd_metrics.h" 6 : 7 : void * 8 0 : fd_catchup_new( void * mem ) { 9 0 : fd_catchup_t * catchup = (fd_catchup_t *)mem; 10 0 : catchup->st = UINT_MAX; 11 0 : catchup->en = UINT_MAX; 12 0 : catchup->turbine_slot0 = 0; 13 : 14 0 : return catchup; 15 0 : } 16 : 17 : fd_catchup_t * 18 0 : fd_catchup_join( void * catchup ) { 19 0 : return (fd_catchup_t *)catchup; 20 0 : } 21 : 22 : void 23 0 : fd_catchup_set_turbine_slot0( fd_catchup_t * catchup, ulong turbine_slot0 ) { 24 0 : catchup->turbine_slot0 = turbine_slot0; 25 0 : } 26 : 27 : void 28 : fd_catchup_add_slot( fd_catchup_t * catchup, 29 : ulong slot, 30 : long first_ts, 31 : long slot_complete_ts, 32 : uint repair_cnt, 33 0 : uint turbine_cnt ) { 34 0 : uint next_en = (catchup->en + 1) % FD_CATCHUP_METRICS_MAX; 35 0 : if( FD_UNLIKELY( next_en == catchup->st || catchup->st == UINT_MAX ) ) { 36 0 : catchup->st = (catchup->st + 1) % FD_CATCHUP_METRICS_MAX; 37 0 : } 38 0 : catchup->metrics[ next_en ].slot = slot; 39 0 : catchup->metrics[ next_en ].first_ts = first_ts; 40 0 : catchup->metrics[ next_en ].slot_complete_ts = slot_complete_ts; 41 0 : catchup->metrics[ next_en ].repair_cnt = repair_cnt; 42 0 : catchup->metrics[ next_en ].turbine_cnt = turbine_cnt; 43 0 : catchup->en = next_en; 44 0 : } 45 : 46 0 : #define MAX_WIDTH 120 47 : static char dashes[MAX_WIDTH + 1] = "========================================================================================================================"; 48 : static char spaces[MAX_WIDTH + 1] = " "; 49 : 50 : void 51 0 : fd_catchup_print( fd_catchup_t * catchup ) { 52 0 : long min_ts = catchup->metrics[ catchup->st ].first_ts; 53 0 : long max_ts = catchup->metrics[ catchup->en ].slot_complete_ts; 54 0 : long turbine_ts = 0; 55 0 : uint cnt = 0; 56 0 : for( uint i = catchup->st;; i = (i + 1) % FD_CATCHUP_METRICS_MAX ) { 57 0 : cnt++; 58 0 : min_ts = fd_min( min_ts, catchup->metrics[ i ].first_ts ); 59 0 : max_ts = fd_max( max_ts, catchup->metrics[ i ].slot_complete_ts ); 60 0 : if( catchup->metrics[ i ].slot == catchup->turbine_slot0 ) { 61 0 : turbine_ts = catchup->metrics[ i ].slot_complete_ts; 62 0 : } 63 0 : if( i == catchup->en ) break; 64 0 : } 65 : 66 0 : FD_LOG_NOTICE(( "Showing %u slots", cnt )); 67 : 68 0 : if( FD_LIKELY( turbine_ts > 0 ) ) { /* still have turbine slot0 in the catchup metrics */ 69 0 : FD_LOG_NOTICE(( "took %.3fs to complete catchup.", (double)(turbine_ts - min_ts) / 1e9 )); 70 0 : } 71 : 72 : /* prints a stacked depth chart of the catchup metrics like this: 73 : slot |===============| (duration in ms) 74 : slot |================| 75 : etc. */ 76 : 77 0 : double tick_sz = (double)(max_ts - min_ts) / (double)MAX_WIDTH; 78 : 79 0 : for( uint i = catchup->st;;i = (i + 1) % FD_CATCHUP_METRICS_MAX ) { 80 0 : long duration = catchup->metrics[ i ].slot_complete_ts - catchup->metrics[ i ].first_ts; 81 0 : int width = (int)((double)(duration) / tick_sz); 82 0 : int start = (int)((double)(catchup->metrics[ i ].first_ts - min_ts) / tick_sz); 83 : // print slot number, then start spaces, then '=' width times, then '|' 84 0 : printf( "%lu %.*s|%.*s| (%.2f ms)", catchup->metrics[ i ].slot, start, spaces, width, dashes, (double)fd_metrics_convert_ticks_to_nanoseconds((ulong)duration) / 1e6 ); 85 0 : if( catchup->metrics[ i ].slot == catchup->turbine_slot0 ) { 86 0 : printf( " <--- (first turbine shred received)" ); 87 0 : } 88 0 : printf( "\n" ); 89 0 : if( i == catchup->en ) break; 90 0 : } 91 0 : fflush( stdout ); 92 : 93 0 : } 94 : 95 : #undef MAX_WIDTH 96 :