From 57e4d2e5080bc9ecfb676fae4852b1e6e7e68356 Mon Sep 17 00:00:00 2001 From: jbjohnso Date: Sun, 29 Apr 2012 00:36:48 +0000 Subject: [PATCH] Rework Client to be more responsive to server code even with the XML coalescing in effect git-svn-id: https://svn.code.sf.net/p/xcat/code/xcat-core/branches/2.7@12396 8638fb3e-16cb-4fca-ae20-7b5d299a9bcd --- perl-xCAT/xCAT/Client.pm | 51 ++++++++++++++++++++++++++++++---------- 1 file changed, 38 insertions(+), 13 deletions(-) diff --git a/perl-xCAT/xCAT/Client.pm b/perl-xCAT/xCAT/Client.pm index f5ba2fa16..f5837ca0e 100644 --- a/perl-xCAT/xCAT/Client.pm +++ b/perl-xCAT/xCAT/Client.pm @@ -35,6 +35,9 @@ unless ($inet6support) { use XML::Simple; #smaller than libxml.... +use Fcntl; +use POSIX qw/:errno_h/; +use IO::Select; $XML::Simple::PREFERRED_PARSER='XML::Parser'; #require Data::Dumper; my $xcathost='localhost:3001'; @@ -220,30 +223,52 @@ $request->{clienttype}->[0] = "cli"; # setup clienttype for auditlog my $cleanexit=0; my $massresponse=""; my $nextcoalescetime=time()+1; - while (<$client>) { - $response .= $_; - if (m/<\/xcatresponse>/) { - #replace ESC with xxxxESCxxx because XMLin cannot handle it - $response =~ s/\e/xxxxESCxxxx/g; - - if ($ENV{XCATXMLTRACE}) { print $response; } - $massresponse.=$response; - if($ENV{XCATXMLWARNING}) { - validateXML($response); - } + my $coalescenow=0; + my $flags; + fcntl($client,F_GETFL,$flags); + $flags |= O_NONBLOCK; #select can be a bit.. fickle, make sysread work more easily... + fcntl($client,F_SETFL,$flags); + my $clientsel = new IO::Select; + $clientsel->add($client); + my $line; + my $newdata=0; + while (1) { my $shouldexit; - if (time() > $nextcoalescetime) { + if ($newdata and ($coalescenow or time() > $nextcoalescetime)) { + $coalescenow=0; + $newdata=0; $nextcoalescetime=time()+1; $massresponse .= ""; $shouldexit = rspclean($massresponse,$callback); $massresponse=""; } - $response=''; if ($shouldexit) { $cleanexit=1; last; } + $line = ""; + $clientsel->can_read(0.5); + my $readbytes; + do { $readbytes=sysread($client,$line,65535,length($line)); } while ($readbytes); + unless (length($line)) { + if (not defined $readbytes and $! == EAGAIN) { next; } + last; + } + $newdata=1; + $response .= $line; + if ($line =~ m/<\/xcatresponse>/) { + if ($line =~ /serverdone/) { $coalescenow=1; } #if serverdone was detected, hint at coalesce code to flush things out now + #this means that coalesce can be triggered by stray words in the output prematurely, but that's harmless + #replace ESC with xxxxESCxxx because XMLin cannot handle it + $response =~ s/\e/xxxxESCxxxx/g; + + if ($ENV{XCATXMLTRACE}) { print $response; } + $massresponse.=$response; + $response=''; + if($ENV{XCATXMLWARNING}) { + validateXML($response); + } } } if (not $cleanexit and $massresponse ne "") {