OpenPKG CVS Repository
http://cvs.openpkg.org/
____________________________________________________________________________
Server: cvs.openpkg.org Name: Thomas Lotterer
Root: /v/openpkg/cvs Email: [EMAIL PROTECTED]
Module: openpkg-registry Date: 13-Jul-2006 09:32:41
Branch: HEAD Handle: 2006071308324100
Modified files:
openpkg-registry registry-ui.pl
Log:
Fix transactional problems. When multiple XML requests are dropped for
reregistration, "insert, on error update" logic breaks transaction and
hearbeat is lost on all but the last request being processed (in perl
random hash order). Reorganize to use "update or insert" (w/o error)
logic; Defer result printing until transaction is completed. If
transaction fails as a whole or because of one or more "ERROR"
conditions are detected during processing, good requests are lost,
too, so print "IGNORED" for them and do not mark them "DONE". Order
response printing in processing order; Simplify user agent vs. HTML
output formatting doing it in one place.
Summary:
Revision Changes Path
1.72 +75 -73 openpkg-registry/registry-ui.pl
____________________________________________________________________________
patch -p0 <<'@@ .'
Index: openpkg-registry/registry-ui.pl
============================================================================
$ cvs diff -u -r1.71 -r1.72 registry-ui.pl
--- openpkg-registry/registry-ui.pl 13 Jul 2006 07:14:13 -0000 1.71
+++ openpkg-registry/registry-ui.pl 13 Jul 2006 07:32:41 -0000 1.72
@@ -1601,12 +1601,10 @@
}
return $html;
}
+ my $res = {};
my $commit = 1;
-
- if (&uao()) {
- $html .= "<registry>\n";
- }
- foreach my $k (keys %{$ref->{request}}) {
+ my @keys = keys %{$ref->{request}};
+ foreach my $k (@keys) {
my $username;
$username = $ref->{request}->{$k}->{registry_user};
@@ -1617,110 +1615,78 @@
if (not defined $rv) {
$msg = $dbh->errstr;
$msg =~ s/[ ]*ERROR:?[ ]*//;
- if (&uao()) {
- $html .= sprintf(" <response id=\"%s\" done=\"no\">ERROR
DataBase reports %s</response>\n", $k, $msg);
- }
- else {
- $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> <b>%s</b> ERROR DataBase reports %s\n", $k,
$msg);
- }
+ $res->{$k} = sprintf("ERROR DataBase reports %s", $msg);
$commit = 0;
next;
}
- if ($rv != 1) {
- if (&uao()) {
- $html .= sprintf(" <response id=\"%s\" done=\"no\">ERROR
username %s not found</response>\n", $k, $username);
- }
- else {
- $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> <b>%s</b> ERROR username <i>%s</i> not
found\n", $k, $username);
- }
+ elsif ($rv < 1) {
+ $res->{$k} = sprintf("ERROR username \"%s\" not found",
$username);
$commit = 0;
next;
}
- # insert instance, possibly fall back to update
+ # update instance
#
+ my $rowkey;
+ $rowkey = undef;
my ($fields, $fieldlist, $fieldbind, $fieldvals, $sth);
($sql, $fields, $fieldlist, $fieldbind, $fieldvals, $sth) = undef;
for my $field (sort keys %{$ref->{request}->{$k}}) {
if (not ref($ref->{request}->{$k}->{$field})) {
- $fieldlist = (defined $fieldlist ? $fieldlist . ", " : "") .
$field;
- $fieldbind = (defined $fieldbind ? $fieldbind . ", " : "") .
"?";
- push @{$fieldvals}, $ref->{request}->{$k}->{$field};
- #FIXME here we could check the validity of all fields with
string 'uuid' in their names
+ if ($field eq "uuid_registry") {
+ $rowkey = $ref->{request}->{$k}->{$field}
+ }
+ else {
+ $fieldlist = (defined $fieldlist ? $fieldlist . ", " :
"") . $field . " = ?";
+ push @{$fieldvals}, $ref->{request}->{$k}->{$field};
+ }
}
else {
; # reserved for nested structures
}
}
- $sql = sprintf("INSERT INTO reg_instance (%s) VALUES (%s);",
$fieldlist, $fieldbind);
+ $sql = sprintf("UPDATE reg_instance SET registry_date = now(), %s
WHERE ( uuid_registry = '%s' );", $fieldlist, $rowkey);
$sth = $dbh->prepare($sql);
$rv = $sth->execute(@{$fieldvals});
if (not defined $rv) {
$msg = $dbh->errstr;
$msg =~ s/[ ]*ERROR:?[ ]*//;
- unless ($msg =~ m|duplicate key violates unique constraint|) {
- if (&uao()) {
- $html .= sprintf(" <response id=\"%s\"
done=\"no\">ERROR DataBase reports %s</response>\n", $k, $msg);
- }
- else {
- $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> <b>%s</b> ERROR DataBase reports %s\n", $k,
$msg);
- }
- $commit = 0;
- next;
- }
+ $res->{$k} = sprintf("ERROR DataBase reports %s", $msg);
+ $commit = 0;
+ next;
}
- if ($rv != 1) {
- my $rowkey;
- $rowkey = undef;
+ elsif ($rv < 1) {
+ # insert instance
+ #
($sql, $fields, $fieldlist, $fieldbind, $fieldvals, $sth) =
undef;
- $fieldlist = 'registry_date = ?';
- push @{$fieldvals}, 'now()'; #FIXME this should read DEFAULT or
COLUMN_DEF but does not work here for unknown reasons
for my $field (sort keys %{$ref->{request}->{$k}}) {
if (not ref($ref->{request}->{$k}->{$field})) {
- if ($field eq "uuid_registry") {
- $rowkey = $ref->{request}->{$k}->{$field}
- }
- else {
- $fieldlist = (defined $fieldlist ? $fieldlist . ", "
: "") . $field . " = ?";
- push @{$fieldvals}, $ref->{request}->{$k}->{$field};
- }
+ $fieldlist = (defined $fieldlist ? $fieldlist . ", " :
"") . $field;
+ $fieldbind = (defined $fieldbind ? $fieldbind . ", " :
"") . "?";
+ push @{$fieldvals}, $ref->{request}->{$k}->{$field};
+ #FIXME here we could check the validity of all fields
with string 'uuid' in their names
}
else {
; # reserved for nested structures
}
}
- $sql = sprintf("UPDATE reg_instance SET %s WHERE ( uuid_registry
= ? );", $fieldlist);
+ $sql = sprintf("INSERT INTO reg_instance (%s) VALUES (%s);",
$fieldlist, $fieldbind);
$sth = $dbh->prepare($sql);
- $rv = $sth->execute(@{$fieldvals}, $rowkey);
+ $rv = $sth->execute(@{$fieldvals});
if (not defined $rv) {
$msg = $dbh->errstr;
$msg =~ s/[ ]*ERROR:?[ ]*//;
- if (&uao()) {
- $html .= sprintf(" <response id=\"%s\"
done=\"no\">ERROR DataBase reports %s</response>\n", $k, $msg);
- }
- else {
- $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> <b>%s</b> ERROR DataBase reports %s\n", $k,
$msg);
- }
- $commit = 0;
- next;
- }
- if ($rv != 1) {
- if (&uao()) {
- $html .= sprintf(" <response id=\"%s\"
done=\"no\">ERROR update failed rv=%s</response>\n", $k, $msg);
- }
- else {
- $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> <b>%s</b> ERROR update failed rv=$rv\n",
$k);
- }
+ $res->{$k} = sprintf("ERROR DataBase reports %s", $msg);
$commit = 0;
next;
}
}
- if (&uao()) {
- $html .= sprintf(" <response id=\"%s\"
done=\"yes\">%s</response>\n", $k, $ref->{request}->{$k}->{registry_desc});
- }
- else {
- $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-ok\"> <b>%s</b> %s\n", $k,
$ref->{request}->{$k}->{registry_desc});
+ if ($rv < 1) {
+ $res->{$k} = sprintf("ERROR update and insert failed");
+ $commit = 0;
+ next;
}
+ $res->{$k} = "DONE";
}
if ($commit == 1) {
@@ -1729,11 +1695,14 @@
$msg = $@;
$msg =~ s/[ ]*ERROR:?[ ]*//;
if (&uao()) {
- $html .= sprintf(" <response id=\"FIXME\"
done=\"no\">ERROR commit transaction failed, DataBase reports %s</response>\n",
$msg);
+ $html .= "<registry>\n";
+ $html .= sprintf("ERROR: commit transaction failed, DataBase
reports %s\n", $msg);
+ $html .= "</registry>\n";
}
else {
$html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> ERROR commit transaction failed, DataBase
reports %s\n", $msg);
}
+ return($html)
}
$cgi->delete(-name=>'data');
}
@@ -1743,16 +1712,49 @@
$msg = $@;
$msg =~ s/[ ]*ERROR:?[ ]*//;
if (&uao()) {
- $html .= sprintf(" <response id=\"FIXME\"
done=\"no\">ERROR rollback transaction failed, DataBase reports
%s</response>\n", $msg);
+ $html .= "<registry>\n";
+ $html .= sprintf("ERROR: rollback transaction failed,
DataBase reports %s\n", $msg);
+ $html .= "</registry>\n";
}
else {
$html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> ERROR rollback transaction failed, DataBase
reports %s\n", $msg);
}
+ return($html)
}
}
- if (&uao()) {
- $html .= "</registry>\n";
+
+ $html .= "<registry>\n" if (&uao());
+ foreach my $k (@keys) {
+ $msg = $res->{$k};
+ if ($msg eq "DONE") {
+ $msg = $ref->{request}->{$k}->{registry_desc};
+ if ($commit == 1) {
+ if (&uao()) {
+ $html .= sprintf(" <response id=\"%s\"
done=\"yes\">%s</response>\n", $k, $msg);
+ }
+ else {
+ $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-ok\"> <b>%s</b> %s\n", $k, $msg);
+ }
+ }
+ else {
+ if (&uao()) {
+ $html .= sprintf(" <response id=\"%s\"
done=\"no\">IGNORED: %s</response>\n", $k, $msg);
+ }
+ else {
+ $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-dot\"> <b>%s</b> IGNORED: %s\n", $k, $msg);
+ }
+ }
+ }
+ else {
+ if (&uao()) {
+ $html .= sprintf(" <response id=\"%s\"
done=\"no\">%s</response>\n", $k, $msg);
+ }
+ else {
+ $html .= sprintf("<br/><img
src=\"?page=gif;name=icon-x\"> <b>%s</b> %s\n", $k, $msg);
+ }
+ }
}
+ $html .= "</registry>\n" if (&uao());
return($html);
}
@@ .
______________________________________________________________________
The OpenPKG Project www.openpkg.org
CVS Repository Commit List [email protected]