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\">&nbsp;<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\">&nbsp;<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\">&nbsp;<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\">&nbsp;<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\">&nbsp;<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\">&nbsp<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\">&nbsp;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\">&nbsp;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\">&nbsp<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\">&nbsp<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\">&nbsp<b>%s</b> %s\n", $k, $msg);
  +            }
  +        }
       }
  +    $html .= "</registry>\n" if (&uao());
       return($html);
   }
   
  @@ .
______________________________________________________________________
The OpenPKG Project                                    www.openpkg.org
CVS Repository Commit List                     openpkg-cvs@openpkg.org

Reply via email to