From 4f56587844db4a9ef9f6330fb82f3e8568afc54d Mon Sep 17 00:00:00 2001 From: Junghyun Kim Date: Fri, 3 Feb 2017 20:52:05 +0900 Subject: [PATCH] Compensation for BUILD_START, BUILD_SUCCESS, BUILD_UNCHANGED PROBLEM: - Since obs-2.7, all events are gathered to src_server. - src_server delivers all notify events to plugins - There is possibility that BUILD_SUCCESS has been processed before BUILD_START is processed. SOLUTION: - For BUILD_SUCCESS, BUILD_FAILED and BUILD_UNCHANGED, it is recorded even if there is no row for this build. - For BUILD_START, it updates to prior BUILD_SUCCESS data if time is prior to the time of BUILD_SUCCESS. Change-Id: Ifcc48504e23679ee3a9518f37f1ea21f35237020 Signed-off-by: Junghyun Kim --- BuildMonitorDB.pm | 108 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 93 insertions(+), 15 deletions(-) diff --git a/BuildMonitorDB.pm b/BuildMonitorDB.pm index c99a65a..ad57c3c 100644 --- a/BuildMonitorDB.pm +++ b/BuildMonitorDB.pm @@ -37,6 +37,8 @@ my $package_build_finished_sth; my $search_not_succeeded_packages_sth; my $build_status_sth; my $build_status_exists_sth; +my $check_prior_to_build_success_sth; +my $update_build_start_time_sth; my $package_disable_last_flag_sth; my $insert_package_build_if_not_exist_sth; my $package_build_status_sth; @@ -138,6 +140,33 @@ sub check_proj_pattern { return 0; } + +sub check_prior_to_build_success { + my ($build_project_id, $build_target_id, $info_package_id, $package_build_time) = @_; + + $check_prior_to_build_success_sth->execute($build_project_id, $build_target_id, + $info_package_id, $package_build_time); + + my $arr_ref = $check_prior_to_build_success_sth->fetchrow_arrayref; + if( ! $arr_ref ) { + # if not found, return 0. + return 0; + } + + my $bpa_id = @$arr_ref[0]; + + print "[", __LINE__, "] returning bpa_id = $bpa_id\n"; + + # return bpa.id + return $bpa_id; +} + +sub update_build_start_time { + my ($bpa_id, $package_build_time) = @_; + + $update_build_start_time_sth->execute($package_build_time, $bpa_id); +} + #------------------------------------------------------------------------------- # event handlers #------------------------------------------------------------------------------- @@ -1252,17 +1281,27 @@ sub package_build_start { } else { $reason=parse_reason($reason); } + $reason = substr($reason, 0, 1000); my $state = "Building"; my $project_build_time = $time; my $package_build_time = $project_build_time; - # start the project build if this is the first building of a package in this project. - project_build_start($build_project_id, $proj_name, $repo, $arch, $state, $project_build_time); + # At first, we need to check this BUILD_START is an event that should be processed before BUILD_SUCCESS. my $build_target_id=get_build_target_id($build_project_id, $repo, $arch); - insert_package_build($build_target_id, $info_package_id); - print "[", __LINE__, "][package_build_start($package_name)] $reason, $build_target_id, $info_package_id, $build_log_url\n"; - $package_build_start_sth->execute($package_build_time, $state, $reason, $build_log_url, $build_target_id, $info_package_id); + print "[", __LINE__, "] $build_project_id, $build_target_id, $info_package_id, $package_build_time\n"; + if( my $bpa_id = check_prior_to_build_success($build_project_id, $build_target_id, $info_package_id, $package_build_time) ) { + print "[", __LINE__, "] update build time only!!! $bpa_id, $package_build_time\n"; + update_build_start_time($bpa_id, $package_build_time); + } else { + # start the project build if this is the first building of a package in this project. + project_build_start($build_project_id, $proj_name, $repo, $arch, $state, $project_build_time); + $build_target_id=get_build_target_id($build_project_id, $repo, $arch); + + insert_package_build($build_target_id, $info_package_id); + print "[", __LINE__, "][package_build_start($package_name)] $reason, $build_target_id, $info_package_id, $build_log_url\n"; + $package_build_start_sth->execute($package_build_time, $state, $reason, $build_log_url, $build_target_id, $info_package_id); + } my $elapsed_time = get_cur_time() - $start_time; print "[",__LINE__,"] took $elapsed_time seconds.\n"; @@ -1305,7 +1344,7 @@ sub insert_package_build { #------------------------------------------------------------------------------- sub insert_package_build_if_not_exist { - my ($build_target_id, $repo, $arch, $info_package_id, $current_status) = @_; + my ($build_target_id, $info_package_id, $current_status) = @_; $check_package_build_sth->execute($build_target_id, $info_package_id); my $arr_ref = $check_package_build_sth->fetchrow_arrayref; @@ -1421,7 +1460,7 @@ sub package_build_status { } # if no row for this package_build. insert a row. - my $affected_rows = insert_package_build_if_not_exist($build_target_id, $repo, $arch, $info_package_id, $status); + my $affected_rows = insert_package_build_if_not_exist($build_target_id, $info_package_id, $status); if( $affected_rows == 0 ) { if( $status eq "broken" ) { @@ -1589,18 +1628,37 @@ sub package_build_finished { return; } - if ( $package_name =~ ".*_aggregate") { + # Since _aggregate packages does not trigger BUILD_START, it always calls package_build_start(). + if ( $package_name =~ ".*_aggregate" ) { package_build_start("test", $projid, $repo, $arch, $package_name, $time); } + my $build_target_id=get_build_target_id($build_project_id, $repo, $arch); print "[", __LINE__, "][package_build_finished($package_name)] $pre_install_time, $install_time, $main_build_time, $status, $build_target_id, $repo, $arch, $info_package_id\n"; - eval { - $g_dbh->begin_work(); - $package_build_finished_sth->execute($time, $pre_install_time, $install_time, $main_build_time, "$status", "$detail", $build_target_id, $info_package_id); - $g_dbh->commit(); - }; - if($@) { - warn "[", __LINE__, "] Transaction aborted because $@\n"; + my $transaction_aborted = 1; + while( $transaction_aborted ) { + $transaction_aborted = 0; + eval { + $g_dbh->begin_work(); + + # if there is no 'Building' rows, insert a row. + # This happens when BUILD_SUCCESS is processed before BUILD_START is processed. + if( insert_package_build_if_not_exist($build_target_id, $info_package_id, 'Building') ) { + my $state = "Building"; + my $reason = ""; + my $build_log_url = ""; + + print "[", __LINE__, "][NO_BUILDING! package_build_start($package_name)] $reason, $build_target_id, $info_package_id, $build_log_url\n"; + $package_build_start_sth->execute(1, $state, $reason, $build_log_url, $build_target_id, $info_package_id); + } + + $package_build_finished_sth->execute($time, $pre_install_time, $install_time, $main_build_time, "$status", "$detail", $build_target_id, $info_package_id); + $g_dbh->commit(); + }; + if($@) { + $transaction_aborted = 1; + warn "[", __LINE__, "] Transaction aborted because $@\n"; + } } if( $status eq 'failed' ) { @@ -1744,6 +1802,26 @@ sub connect_db { my $build_status_exists_sql = qq/SELECT bp.id FROM build_project bp, build_target bt, build_package bpa WHERE bp.id = bt.build_project_id AND bpa.build_target_id = bt.id AND bp.id = ? AND bt.repository = ? AND bt.arch = ? AND bpa.info_package_id = ? LIMIT 1;/; $build_status_exists_sth = $g_dbh->prepare($build_status_exists_sql); + my $check_prior_to_build_success_sql = +qq/ +SELECT bpa.id +FROM build_project bp, build_target bt, build_package bpa +WHERE bt.build_project_id = bp.id +AND bpa.build_target_id = bt.id +AND bp.id = ? +AND bt.id = ? +AND bpa.info_package_id = ? +AND bpa.end_time > FROM_UNIXTIME(?) +AND bpa.start_time = FROM_UNIXTIME(1) +/; + $check_prior_to_build_success_sth = $g_dbh->prepare($check_prior_to_build_success_sql); + + my $update_build_start_time_sql = +qq/ +UPDATE build_package SET start_time=FROM_UNIXTIME(?) WHERE id=? +/; + $update_build_start_time_sth = $g_dbh->prepare($update_build_start_time_sql); + #----------------------------------------------------------------------------- # build_project TABLE my $get_build_project_id_sql=qq/SELECT id FROM build_project WHERE info_project_id=? ORDER BY id DESC LIMIT 1;/; -- 2.7.4