From b6beda19f1e27e908fb794fc2b80d571b29c78b6 Mon Sep 17 00:00:00 2001 From: Marc Bernard <59966492+mbtools@users.noreply.github.com> Date: Thu, 16 Mar 2023 16:53:20 +0100 Subject: [PATCH] Show performance metrics for long-running ops (#6148) Co-authored-by: abaplint[bot] <24845621+abaplint[bot]@users.noreply.github.com> Co-authored-by: Lars Hvam --- .../zcl_abapgit_code_inspector.clas.abap | 16 ++- .../zif_abapgit_code_inspector.intf.abap | 5 + .../core/zcl_abapgit_serialize.clas.abap | 14 ++- src/objects/zcl_abapgit_objects.clas.abap | 9 +- src/ui/pages/zcl_abapgit_gui_page.clas.abap | 19 +--- .../zcl_abapgit_gui_page_code_insp.clas.abap | 8 +- .../zcl_abapgit_gui_page_codi_base.clas.abap | 5 +- .../zcl_abapgit_gui_page_syntax.clas.abap | 8 +- src/utils/zcl_abapgit_timer.clas.abap | 106 ++++++++++++++++++ .../zcl_abapgit_timer.clas.testclasses.abap | 81 +++++++++++++ src/utils/zcl_abapgit_timer.clas.xml | 17 +++ 11 files changed, 266 insertions(+), 22 deletions(-) create mode 100644 src/utils/zcl_abapgit_timer.clas.abap create mode 100644 src/utils/zcl_abapgit_timer.clas.testclasses.abap create mode 100644 src/utils/zcl_abapgit_timer.clas.xml diff --git a/src/inspect/zcl_abapgit_code_inspector.clas.abap b/src/inspect/zcl_abapgit_code_inspector.clas.abap index 813f978ac..dbb3a2cfa 100644 --- a/src/inspect/zcl_abapgit_code_inspector.clas.abap +++ b/src/inspect/zcl_abapgit_code_inspector.clas.abap @@ -40,6 +40,7 @@ CLASS zcl_abapgit_code_inspector DEFINITION PRIVATE SECTION. DATA mv_success TYPE abap_bool . + DATA mv_summary TYPE string. TYPES: ty_run_mode TYPE c LENGTH 1. @@ -333,6 +334,11 @@ CLASS zcl_abapgit_code_inspector IMPLEMENTATION. ENDMETHOD. + METHOD zif_abapgit_code_inspector~get_summary. + rv_summary = mv_summary. + ENDMETHOD. + + METHOD zif_abapgit_code_inspector~is_successful. rv_success = mv_success. @@ -344,17 +350,21 @@ CLASS zcl_abapgit_code_inspector IMPLEMENTATION. DATA: lo_set TYPE REF TO cl_ci_objectset, lo_variant TYPE REF TO cl_ci_checkvariant, + lv_count TYPE i, + lo_timer TYPE REF TO zcl_abapgit_timer, lx_error TYPE REF TO zcx_abapgit_exception. - TRY. lo_set = create_objectset( ). - IF lines( lo_set->iobjlst-objects ) = 0. + lv_count = lines( lo_set->iobjlst-objects ). + IF lv_count = 0. " no objects, nothing to check RETURN. ENDIF. + lo_timer = zcl_abapgit_timer=>create( iv_count = lv_count )->start( ). + lo_variant = create_variant( iv_variant ). mo_inspection = create_inspection( @@ -378,5 +388,7 @@ CLASS zcl_abapgit_code_inspector IMPLEMENTATION. ENDTRY. + mv_summary = lo_timer->end( ). + ENDMETHOD. ENDCLASS. diff --git a/src/inspect/zif_abapgit_code_inspector.intf.abap b/src/inspect/zif_abapgit_code_inspector.intf.abap index 039ceffca..e2fcb8229 100644 --- a/src/inspect/zif_abapgit_code_inspector.intf.abap +++ b/src/inspect/zif_abapgit_code_inspector.intf.abap @@ -10,7 +10,12 @@ INTERFACE zif_abapgit_code_inspector VALUE(rt_list) TYPE scit_alvlist RAISING zcx_abapgit_exception . + METHODS is_successful RETURNING VALUE(rv_success) TYPE abap_bool . + + METHODS get_summary + RETURNING + VALUE(rv_summary) TYPE string. ENDINTERFACE. diff --git a/src/objects/core/zcl_abapgit_serialize.clas.abap b/src/objects/core/zcl_abapgit_serialize.clas.abap index a35dbb14f..64af4ff25 100644 --- a/src/objects/core/zcl_abapgit_serialize.clas.abap +++ b/src/objects/core/zcl_abapgit_serialize.clas.abap @@ -613,8 +613,10 @@ CLASS zcl_abapgit_serialize IMPLEMENTATION. * serializes only objects DATA: lv_max TYPE i, + lv_count TYPE i, li_progress TYPE REF TO zif_abapgit_progress, li_exit TYPE REF TO zif_abapgit_exit, + lo_timer TYPE REF TO zcl_abapgit_timer, lt_tadir TYPE zif_abapgit_definitions=>ty_tadir_tt. FIELD-SYMBOLS: LIKE LINE OF it_tadir. @@ -635,7 +637,13 @@ CLASS zcl_abapgit_serialize IMPLEMENTATION. CHANGING ct_tadir = lt_tadir ). - li_progress = zcl_abapgit_progress=>get_instance( lines( lt_tadir ) ). + lv_count = lines( lt_tadir ). + + li_progress = zcl_abapgit_progress=>get_instance( lv_count ). + + lo_timer = zcl_abapgit_timer=>create( + iv_text = 'Serialize:' + iv_count = lv_count )->start( ). LOOP AT lt_tadir ASSIGNING . @@ -653,6 +661,8 @@ CLASS zcl_abapgit_serialize IMPLEMENTATION. ENDIF. ENDLOOP. + li_progress->off( ). + WAIT UNTIL mv_free = lv_max UP TO 120 SECONDS. rt_files = mt_files. FREE mt_files. @@ -667,5 +677,7 @@ CLASS zcl_abapgit_serialize IMPLEMENTATION. CHANGING ct_files = rt_files ). + lo_timer->end( abap_true ). + ENDMETHOD. ENDCLASS. diff --git a/src/objects/zcl_abapgit_objects.clas.abap b/src/objects/zcl_abapgit_objects.clas.abap index 8b32a2d84..36a71cdf1 100644 --- a/src/objects/zcl_abapgit_objects.clas.abap +++ b/src/objects/zcl_abapgit_objects.clas.abap @@ -196,7 +196,7 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_OBJECTS IMPLEMENTATION. +CLASS zcl_abapgit_objects IMPLEMENTATION. METHOD changed_by. @@ -605,6 +605,7 @@ CLASS ZCL_ABAPGIT_OBJECTS IMPLEMENTATION. lx_exc TYPE REF TO zcx_abapgit_exception. DATA lo_folder_logic TYPE REF TO zcl_abapgit_folder_logic. DATA ls_i18n_params TYPE zif_abapgit_definitions=>ty_i18n_params. + DATA lo_timer TYPE REF TO zcl_abapgit_timer. FIELD-SYMBOLS: TYPE zif_abapgit_definitions=>ty_result, TYPE LINE OF zif_abapgit_definitions=>ty_deserialization_step_tt, @@ -642,6 +643,10 @@ CLASS ZCL_ABAPGIT_OBJECTS IMPLEMENTATION. lt_items = map_results_to_items( lt_results ). + lo_timer = zcl_abapgit_timer=>create( + iv_text = 'Deserialize:' + iv_count = lines( lt_items ) )->start( ). + check_objects_locked( iv_language = io_repo->get_dot_abapgit( )->get_main_language( ) it_items = lt_items ). @@ -774,6 +779,8 @@ CLASS ZCL_ABAPGIT_OBJECTS IMPLEMENTATION. zcl_abapgit_default_transport=>get_instance( )->reset( ). + lo_timer->end( abap_true ). + ENDMETHOD. diff --git a/src/ui/pages/zcl_abapgit_gui_page.clas.abap b/src/ui/pages/zcl_abapgit_gui_page.clas.abap index d5b2e678c..4f47eee3a 100644 --- a/src/ui/pages/zcl_abapgit_gui_page.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page.clas.abap @@ -40,8 +40,6 @@ CLASS zcl_abapgit_gui_page DEFINITION PUBLIC ABSTRACT zcx_abapgit_exception . PRIVATE SECTION. - TYPES: ty_time TYPE p LENGTH 10 DECIMALS 2. - DATA mo_settings TYPE REF TO zcl_abapgit_settings . DATA mx_error TYPE REF TO zcx_abapgit_exception . DATA mo_exception_viewer TYPE REF TO zcl_abapgit_exception_viewer . @@ -68,7 +66,7 @@ CLASS zcl_abapgit_gui_page DEFINITION PUBLIC ABSTRACT zcx_abapgit_exception . METHODS footer IMPORTING - !iv_time TYPE ty_time + !iv_time TYPE string RETURNING VALUE(ri_html) TYPE REF TO zif_abapgit_html . METHODS render_link_hints @@ -100,7 +98,7 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION. +CLASS zcl_abapgit_gui_page IMPLEMENTATION. METHOD constructor. @@ -140,7 +138,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION. iv_txt = ri_html->icon( 'git-alt' ) ). ri_html->add_a( iv_act = zif_abapgit_definitions=>c_action-homepage iv_txt = ri_html->icon( iv_name = 'abapgit' - iv_hint = |{ iv_time } sec| ) ). + iv_hint = iv_time ) ). ri_html->add( '' ). ri_html->add( |
{ zif_abapgit_version=>c_abap_version }{ lv_version_detail }
| ). ri_html->add( '' ). @@ -387,13 +385,11 @@ CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION. DATA: li_script TYPE REF TO zif_abapgit_html, - lv_start TYPE i, - lv_end TYPE i, - lv_total TYPE ty_time. + lo_timer TYPE REF TO zcl_abapgit_timer. register_handlers( ). - GET RUN TIME FIELD lv_start. + lo_timer = zcl_abapgit_timer=>create( )->start( ). " Real page CREATE OBJECT ri_html TYPE zcl_abapgit_html. @@ -416,10 +412,7 @@ CLASS ZCL_ABAPGIT_GUI_PAGE IMPLEMENTATION. ii_html = ri_html iv_part_category = c_html_parts-hidden_forms ). - GET RUN TIME FIELD lv_end. - lv_total = ( lv_end - lv_start ) / 1000 / 1000. - - ri_html->add( footer( lv_total ) ). + ri_html->add( footer( lo_timer->end( ) ) ). ri_html->add( '' ). diff --git a/src/ui/pages/zcl_abapgit_gui_page_code_insp.clas.abap b/src/ui/pages/zcl_abapgit_gui_page_code_insp.clas.abap index 90c897eb2..095b27229 100644 --- a/src/ui/pages/zcl_abapgit_gui_page_code_insp.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page_code_insp.clas.abap @@ -64,7 +64,7 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_GUI_PAGE_CODE_INSP IMPLEMENTATION. +CLASS zcl_abapgit_gui_page_code_insp IMPLEMENTATION. METHOD ask_user_for_check_variant. @@ -173,7 +173,9 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_CODE_INSP IMPLEMENTATION. register_handlers( ). - ri_html->add( render_variant( mv_check_variant ) ). + ri_html->add( render_variant( + iv_variant = mv_check_variant + iv_summary = mv_summary ) ). IF lines( mt_result ) = 0. ri_html->add( '
' ). @@ -199,6 +201,8 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_CODE_INSP IMPLEMENTATION. iv_variant = |{ mv_check_variant }| iv_save = abap_true ). + mv_summary = li_code_inspector->get_summary( ). + DELETE mt_result WHERE kind = 'N'. ENDMETHOD. diff --git a/src/ui/pages/zcl_abapgit_gui_page_codi_base.clas.abap b/src/ui/pages/zcl_abapgit_gui_page_codi_base.clas.abap index 87b35daba..bee484584 100644 --- a/src/ui/pages/zcl_abapgit_gui_page_codi_base.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page_codi_base.clas.abap @@ -17,10 +17,12 @@ CLASS zcl_abapgit_gui_page_codi_base DEFINITION PUBLIC ABSTRACT INHERITING FROM END OF c_actions . DATA mo_repo TYPE REF TO zcl_abapgit_repo . DATA mt_result TYPE scit_alvlist . + DATA mv_summary TYPE string. METHODS render_variant IMPORTING !iv_variant TYPE sci_chkv + !iv_summary TYPE string RETURNING VALUE(ri_html) TYPE REF TO zif_abapgit_html . METHODS render_result @@ -277,7 +279,8 @@ CLASS zcl_abapgit_gui_page_codi_base IMPLEMENTATION. CREATE OBJECT ri_html TYPE zcl_abapgit_html. ri_html->add( '
' ). - ri_html->add( |Code inspector check variant: { iv_variant }| ). + ri_html->add( |Code inspector check variant { iv_variant }| + && | completed ({ iv_summary })| ). ri_html->add( `
` ). ENDMETHOD. diff --git a/src/ui/pages/zcl_abapgit_gui_page_syntax.clas.abap b/src/ui/pages/zcl_abapgit_gui_page_syntax.clas.abap index 6a26dd88e..c23d0b1ed 100644 --- a/src/ui/pages/zcl_abapgit_gui_page_syntax.clas.abap +++ b/src/ui/pages/zcl_abapgit_gui_page_syntax.clas.abap @@ -37,7 +37,7 @@ ENDCLASS. -CLASS ZCL_ABAPGIT_GUI_PAGE_SYNTAX IMPLEMENTATION. +CLASS zcl_abapgit_gui_page_syntax IMPLEMENTATION. METHOD build_menu. @@ -66,7 +66,9 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SYNTAX IMPLEMENTATION. ri_html->add( '
' ). - ri_html->add( render_variant( c_variant ) ). + ri_html->add( render_variant( + iv_variant = c_variant + iv_summary = mv_summary ) ). IF lines( mt_result ) = 0. ri_html->add( '
' ). @@ -94,6 +96,8 @@ CLASS ZCL_ABAPGIT_GUI_PAGE_SYNTAX IMPLEMENTATION. mt_result = li_syntax_check->run( 'VERI_' && c_variant ). ENDTRY. + mv_summary = li_syntax_check->get_summary( ). + ENDMETHOD. diff --git a/src/utils/zcl_abapgit_timer.clas.abap b/src/utils/zcl_abapgit_timer.clas.abap new file mode 100644 index 000000000..9b6041b71 --- /dev/null +++ b/src/utils/zcl_abapgit_timer.clas.abap @@ -0,0 +1,106 @@ +CLASS zcl_abapgit_timer DEFINITION + PUBLIC + FINAL + CREATE PRIVATE. + + PUBLIC SECTION. + + CLASS-METHODS create + IMPORTING + !iv_text TYPE string OPTIONAL + !iv_count TYPE i OPTIONAL + PREFERRED PARAMETER iv_text + RETURNING + VALUE(ro_timer) TYPE REF TO zcl_abapgit_timer. + + METHODS constructor + IMPORTING + !iv_text TYPE string OPTIONAL + !iv_count TYPE i OPTIONAL. + + METHODS start + RETURNING + VALUE(ro_timer) TYPE REF TO zcl_abapgit_timer. + + METHODS end + IMPORTING + !iv_output_as_status_message TYPE abap_bool DEFAULT abap_false + RETURNING + VALUE(rv_result) TYPE string. + + PROTECTED SECTION. + PRIVATE SECTION. + + DATA mv_text TYPE string. + DATA mv_count TYPE i. + DATA mv_timer TYPE timestampl. + +ENDCLASS. + + + +CLASS zcl_abapgit_timer IMPLEMENTATION. + + + METHOD constructor. + mv_text = iv_text. + mv_count = iv_count. + ENDMETHOD. + + + METHOD create. + CREATE OBJECT ro_timer + EXPORTING + iv_text = iv_text + iv_count = iv_count. + ENDMETHOD. + + + METHOD end. + + DATA: + lv_timestamp TYPE timestampl, + lv_runtime TYPE timestampl, + lv_sec TYPE p LENGTH 11 DECIMALS 2. + + IF mv_timer IS INITIAL. + rv_result = 'Runtime measurement has not been started'. + ELSE. + GET TIME STAMP FIELD lv_timestamp. + + TRY. + lv_runtime = cl_abap_tstmp=>subtract( + tstmp1 = lv_timestamp + tstmp2 = mv_timer ). + + lv_sec = lv_runtime. " round to 2 decimal places + + IF mv_count = 1. + rv_result = |1 object, |. + ELSEIF mv_count > 1. + rv_result = |{ mv_count } objects, |. + ENDIF. + + rv_result = rv_result && |{ lv_sec } seconds|. + + CATCH cx_parameter_invalid. + rv_result = 'Error getting runtime measurement'. + ENDTRY. + ENDIF. + + IF iv_output_as_status_message = abap_true. + MESSAGE s000(oo) WITH mv_text rv_result. + ENDIF. + + IF mv_text IS NOT INITIAL. + rv_result = |{ mv_text } { rv_result }|. + ENDIF. + + ENDMETHOD. + + + METHOD start. + GET TIME STAMP FIELD mv_timer. + ro_timer = me. + ENDMETHOD. +ENDCLASS. diff --git a/src/utils/zcl_abapgit_timer.clas.testclasses.abap b/src/utils/zcl_abapgit_timer.clas.testclasses.abap new file mode 100644 index 000000000..b33b6addb --- /dev/null +++ b/src/utils/zcl_abapgit_timer.clas.testclasses.abap @@ -0,0 +1,81 @@ +CLASS ltcl_timer DEFINITION FOR TESTING + DURATION SHORT + RISK LEVEL HARMLESS. + PRIVATE SECTION. + + METHODS: + check_result + IMPORTING + iv_result TYPE string + iv_regex TYPE string, + + run_timer FOR TESTING, + run_timer_with_count FOR TESTING, + run_timer_with_text FOR TESTING. + +ENDCLASS. + +CLASS ltcl_timer IMPLEMENTATION. + + METHOD check_result. + + FIND REGEX iv_regex IN iv_result. + + cl_abap_unit_assert=>assert_subrc( + act = sy-subrc + msg = 'Did not return right measurement' ). + + ENDMETHOD. + + METHOD run_timer. + + DATA lo_timer TYPE REF TO zcl_abapgit_timer. + + lo_timer = zcl_abapgit_timer=>create( )->start( ). + + WAIT UP TO 1 SECONDS. + + check_result( + iv_result = lo_timer->end( ) + iv_regex = '1.0[0-9] seconds' ). + + ENDMETHOD. + + METHOD run_timer_with_count. + + DATA lo_timer TYPE REF TO zcl_abapgit_timer. + + lo_timer = zcl_abapgit_timer=>create( iv_count = 1 )->start( ). + + WAIT UP TO 1 SECONDS. + + check_result( + iv_result = lo_timer->end( ) + iv_regex = '1 object, 1.0[0-9] seconds' ). + + lo_timer = zcl_abapgit_timer=>create( iv_count = 1234 )->start( ). + + WAIT UP TO 1 SECONDS. + + check_result( + iv_result = lo_timer->end( ) + iv_regex = '1234 objects, 1.0[0-9] seconds' ). + + ENDMETHOD. + + METHOD run_timer_with_text. + + CONSTANTS lc_total TYPE string VALUE 'Total:'. + + DATA lo_timer TYPE REF TO zcl_abapgit_timer. + + lo_timer = zcl_abapgit_timer=>create( lc_total )->start( ). + + WAIT UP TO 1 SECONDS. + + check_result( + iv_result = lo_timer->end( ) + iv_regex = |{ lc_total } 1.0[0-9] seconds| ). + + ENDMETHOD. +ENDCLASS. diff --git a/src/utils/zcl_abapgit_timer.clas.xml b/src/utils/zcl_abapgit_timer.clas.xml new file mode 100644 index 000000000..bd80b7d1b --- /dev/null +++ b/src/utils/zcl_abapgit_timer.clas.xml @@ -0,0 +1,17 @@ + + + + + + ZCL_ABAPGIT_TIMER + E + abapGit - Timer + 1 + X + X + X + X + + + +