Move evaluation errors from evaluations to EvaluationErrors, a new table

DBIx likes to eagerly select all columns without a way to really tell
it so. Therefore, this splits this one large column in to its own
table.

I'd also like to make "jobsets" use this table too, but that is on hold
to stop the bleeding caused by the extreme amount of traffic this is
causing.
This commit is contained in:
Graham Christensen 2021-02-01 18:35:48 -05:00
parent aaf16d542c
commit f1e75c8bff
No known key found for this signature in database
GPG key ID: FE918C3A98C1030F
9 changed files with 196 additions and 27 deletions

View file

@ -211,8 +211,8 @@ sub getEvals {
my @evals = $evals->search( my @evals = $evals->search(
{ hasnewbuilds => 1 }, { hasnewbuilds => 1 },
{ order_by => "id DESC", rows => $rows, offset => $offset }); { order_by => "me.id DESC", rows => $rows, offset => $offset
, prefetch => { evaluationerror => [ ] } });
my @res = (); my @res = ();
my $cache = {}; my $cache = {};

View file

@ -0,0 +1,108 @@
use utf8;
package Hydra::Schema::EvaluationErrors;
# Created by DBIx::Class::Schema::Loader
# DO NOT MODIFY THE FIRST PART OF THIS FILE
=head1 NAME
Hydra::Schema::EvaluationErrors
=cut
use strict;
use warnings;
use base 'DBIx::Class::Core';
=head1 COMPONENTS LOADED
=over 4
=item * L<Hydra::Component::ToJSON>
=back
=cut
__PACKAGE__->load_components("+Hydra::Component::ToJSON");
=head1 TABLE: C<evaluationerrors>
=cut
__PACKAGE__->table("evaluationerrors");
=head1 ACCESSORS
=head2 id
data_type: 'integer'
is_auto_increment: 1
is_nullable: 0
sequence: 'evaluationerrors_id_seq'
=head2 errormsg
data_type: 'text'
is_nullable: 1
=head2 errortime
data_type: 'integer'
is_nullable: 1
=cut
__PACKAGE__->add_columns(
"id",
{
data_type => "integer",
is_auto_increment => 1,
is_nullable => 0,
sequence => "evaluationerrors_id_seq",
},
"errormsg",
{ data_type => "text", is_nullable => 1 },
"errortime",
{ data_type => "integer", is_nullable => 1 },
);
=head1 PRIMARY KEY
=over 4
=item * L</id>
=back
=cut
__PACKAGE__->set_primary_key("id");
=head1 RELATIONS
=head2 jobsetevals
Type: has_many
Related object: L<Hydra::Schema::JobsetEvals>
=cut
__PACKAGE__->has_many(
"jobsetevals",
"Hydra::Schema::JobsetEvals",
{ "foreign.evaluationerror_id" => "self.id" },
undef,
);
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-02-01 20:17:39
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:sZIg35KWCO8MOsQ5cfN1IA
__PACKAGE__->add_column(
"+id" => { retrieve_on_insert => 1 }
);
1;

View file

@ -48,14 +48,10 @@ __PACKAGE__->table("jobsetevals");
is_foreign_key: 1 is_foreign_key: 1
is_nullable: 0 is_nullable: 0
=head2 errormsg =head2 evaluationerror_id
data_type: 'text'
is_nullable: 1
=head2 errortime
data_type: 'integer' data_type: 'integer'
is_foreign_key: 1
is_nullable: 1 is_nullable: 1
=head2 timestamp =head2 timestamp
@ -120,10 +116,8 @@ __PACKAGE__->add_columns(
}, },
"jobset_id", "jobset_id",
{ data_type => "integer", is_foreign_key => 1, is_nullable => 0 }, { data_type => "integer", is_foreign_key => 1, is_nullable => 0 },
"errormsg", "evaluationerror_id",
{ data_type => "text", is_nullable => 1 }, { data_type => "integer", is_foreign_key => 1, is_nullable => 1 },
"errortime",
{ data_type => "integer", is_nullable => 1 },
"timestamp", "timestamp",
{ data_type => "integer", is_nullable => 0 }, { data_type => "integer", is_nullable => 0 },
"checkouttime", "checkouttime",
@ -160,6 +154,26 @@ __PACKAGE__->set_primary_key("id");
=head1 RELATIONS =head1 RELATIONS
=head2 evaluationerror
Type: belongs_to
Related object: L<Hydra::Schema::EvaluationErrors>
=cut
__PACKAGE__->belongs_to(
"evaluationerror",
"Hydra::Schema::EvaluationErrors",
{ id => "evaluationerror_id" },
{
is_deferrable => 0,
join_type => "LEFT",
on_delete => "SET NULL",
on_update => "NO ACTION",
},
);
=head2 jobset =head2 jobset
Type: belongs_to Type: belongs_to
@ -206,8 +220,8 @@ __PACKAGE__->has_many(
); );
# Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-01-25 14:44:07 # Created by DBIx::Class::Schema::Loader v0.07049 @ 2021-02-01 20:17:39
# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:OVxeYH+eoZZrAsAJ2/mAAA # DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:SGtK0PwRkbxiMuitQvs4wQ
__PACKAGE__->has_many( __PACKAGE__->has_many(
"buildIds", "buildIds",

View file

@ -476,7 +476,7 @@ BLOCK renderEvals %]
ELSE %] ELSE %]
- -
[% END %] [% END %]
[% IF eval.errormsg %] [% IF eval.evaluationerror.errormsg %]
<span class="label label-warning">Eval Errors</span> <span class="label label-warning">Eval Errors</span>
[% END %] [% END %]
</td> </td>

View file

@ -89,7 +89,7 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
[% END %] [% END %]
<li><a href="#tabs-inputs" data-toggle="tab">Inputs</a></li> <li><a href="#tabs-inputs" data-toggle="tab">Inputs</a></li>
[% IF eval.errormsg %] [% IF eval.evaluationerror.errormsg %]
<li><a href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation errors</span></a></li> <li><a href="#tabs-errors" data-toggle="tab"><span class="text-warning">Evaluation errors</span></a></li>
[% END %] [% END %]
@ -108,10 +108,10 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
<div class="tab-content"> <div class="tab-content">
[% IF eval.errormsg %] [% IF eval.evaluationerror.errormsg %]
<div id="tabs-errors" class="tab-pane"> <div id="tabs-errors" class="tab-pane">
<p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.errortime || eval.timestamp) %].</p> <p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.evaluationerror.errortime || eval.timestamp) %].</p>
<pre class="alert alert-error">[% HTML.escape(eval.errormsg) %]</pre> <pre class="alert alert-error">[% HTML.escape(eval.evaluationerror.errormsg) %]</pre>
</div> </div>
[% END %] [% END %]
@ -172,10 +172,10 @@ c.uri_for(c.controller('JobsetEval').action_for('view'),
[% END %] [% END %]
</div> </div>
[% IF eval.errormsg %] [% IF eval.evaluationerror.errormsg %]
<div id="tabs-errors" class="tab-pane"> <div id="tabs-errors" class="tab-pane">
<p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.errortime || eval.timestamp) %].</p> <p>Errors occurred at [% INCLUDE renderDateTime timestamp=(eval.evaluationerror.errortime || eval.timestamp) %].</p>
<pre class="alert alert-error">[% HTML.escape(eval.errormsg) %]</pre> <pre class="alert alert-error">[% HTML.escape(eval.evaluationerror.errormsg) %]</pre>
</div> </div>
[% END %] [% END %]
</div> </div>

View file

@ -693,6 +693,12 @@ sub checkJobsetWrapped {
} }
setJobsetError($jobset, $evaluationErrorMsg, $evaluationErrorTime); setJobsetError($jobset, $evaluationErrorMsg, $evaluationErrorTime);
my $evaluationErrorRecord = $db->resultset('EvaluationErrors')->create(
{ errormsg => $evaluationErrorMsg
, errortime => $evaluationErrorTime
}
);
my %buildMap; my %buildMap;
$db->txn_do(sub { $db->txn_do(sub {
@ -715,12 +721,12 @@ sub checkJobsetWrapped {
(scalar(grep { $_->{new} } values(%buildMap)) > 0) (scalar(grep { $_->{new} } values(%buildMap)) > 0)
|| (defined $prevEval && $prevEval->jobsetevalmembers->count != scalar(keys %buildMap)); || (defined $prevEval && $prevEval->jobsetevalmembers->count != scalar(keys %buildMap));
my $ev = $jobset->jobsetevals->create( my $ev = $jobset->jobsetevals->create(
{ hash => $argsHash { hash => $argsHash
, evaluationerror => $evaluationErrorRecord
, timestamp => time , timestamp => time
, checkouttime => abs(int($checkoutStop - $checkoutStart)) , checkouttime => abs(int($checkoutStop - $checkoutStart))
, errormsg => $evaluationErrorMsg
, errortime => $evaluationErrorTime
, evaltime => abs(int($evalStop - $evalStart)) , evaltime => abs(int($evalStop - $evalStart))
, hasnewbuilds => $jobsetChanged ? 1 : 0 , hasnewbuilds => $jobsetChanged ? 1 : 0
, nrbuilds => $jobsetChanged ? scalar(keys %buildMap) : undef , nrbuilds => $jobsetChanged ? scalar(keys %buildMap) : undef

View file

@ -437,13 +437,17 @@ create table SystemTypes (
maxConcurrent integer not null default 2 maxConcurrent integer not null default 2
); );
create table EvaluationErrors (
id serial primary key not null,
errorMsg text, -- error output from the evaluator
errorTime integer -- timestamp associated with errorMsg
);
create table JobsetEvals ( create table JobsetEvals (
id serial primary key not null, id serial primary key not null,
jobset_id integer not null, jobset_id integer not null,
errorMsg text, -- error output from the evaluator evaluationerror_id integer,
errorTime integer, -- timestamp associated with errorMsg
timestamp integer not null, -- when this entry was added timestamp integer not null, -- when this entry was added
checkoutTime integer not null, -- how long obtaining the inputs took (in seconds) checkoutTime integer not null, -- how long obtaining the inputs took (in seconds)
@ -471,7 +475,8 @@ create table JobsetEvals (
nixExprInput text, -- name of the jobsetInput containing the Nix or Guix expression nixExprInput text, -- name of the jobsetInput containing the Nix or Guix expression
nixExprPath text, -- relative path of the Nix or Guix expression nixExprPath text, -- relative path of the Nix or Guix expression
foreign key (jobset_id) references Jobsets(id) on delete cascade foreign key (jobset_id) references Jobsets(id) on delete cascade,
foreign key (evaluationerror_id) references EvaluationErrors(id) on delete set null
); );

View file

@ -21,6 +21,7 @@ make_schema_at("Hydra::Schema", {
"cachedhginputs" => "CachedHgInputs", "cachedhginputs" => "CachedHgInputs",
"cachedpathinputs" => "CachedPathInputs", "cachedpathinputs" => "CachedPathInputs",
"cachedsubversioninputs" => "CachedSubversionInputs", "cachedsubversioninputs" => "CachedSubversionInputs",
"evaluationerrors" => "EvaluationErrors",
"failedpaths" => "FailedPaths", "failedpaths" => "FailedPaths",
"jobsetevalinputs" => "JobsetEvalInputs", "jobsetevalinputs" => "JobsetEvalInputs",
"jobsetevalmembers" => "JobsetEvalMembers", "jobsetevalmembers" => "JobsetEvalMembers",

35
src/sql/upgrade-73.sql Normal file
View file

@ -0,0 +1,35 @@
create table EvaluationErrors (
id serial primary key not null,
errorMsg text, -- error output from the evaluator
errorTime integer, -- timestamp associated with errorMsg
jobsetEvalId integer not null,
FOREIGN KEY (jobsetEvalId)
REFERENCES JobsetEvals(id)
ON DELETE SET NULL
);
ALTER TABLE JobsetEvals
ADD COLUMN evaluationerror_id integer NULL,
ADD FOREIGN KEY (evaluationerror_id)
REFERENCES EvaluationErrors(id)
ON DELETE SET NULL;
INSERT INTO EvaluationErrors
(errorMsg, errorTime, jobsetEvalId)
SELECT errorMsg, errorTime, id
FROM JobsetEvals
WHERE JobsetEvals.errorMsg != '' and JobsetEvals.errorMsg is not null;
UPDATE JobsetEvals
SET evaluationerror_id = EvaluationErrors.id
FROM EvaluationErrors
WHERE JobsetEvals.id = EvaluationErrors.jobsetEvalId
AND JobsetEvals.errorMsg != '' and JobsetEvals.errorMsg is not null;
ALTER TABLE JobsetEvals
DROP COLUMN errorMsg,
DROP COLUMN errorTime;
ALTER TABLE EvaluationErrors
DROP COLUMN jobsetEvalId;