[prev in list] [next in list] [prev in thread] [next in thread] 

List:       intermezzo-cvs
Subject:    CVS: intermezzo/lento/Lento/InterMezzo ReqHandler.pm,1.148,1.149
From:       Shirish Hemant Phatak <shirish () users ! sourceforge ! net>
Date:       2001-10-27 0:14:52
[Download RAW message or body]

Update of /cvsroot/intermezzo/intermezzo/lento/Lento/InterMezzo
In directory usw-pr-cvs1:/tmp/cvs-serv20198/InterMezzo

Modified Files:
	ReqHandler.pm 
Log Message:

 ***Note that this code creates a new RPC***

 Add a new RPC to flush KML to a specific peer. Currently the RPC spawns
 a sendKML session which in turn uses a ReintegrateKML RPC. In future, we
 should be able to avoid this nesting. If Peter approves, this can also
 go into the branch.

 We also modify the fset->sync path on a client by adding an extra step 
 that just flushes KML from the server without actually revoking the permit.
 This is done right after the ReplicatorStatus RPC but before trying to 
 fetch a permit. Thus, the server remains available even as initial
 reintegration of pending KML is taking place on the client. By the time
 the client actually does a GetPermit, most of the KML should already be
 at the client which makes the movememnt of the permit faster and prevents
 a blocked/deadlocked server for long periods of time.

 Note that this code might be prone to livelocks since the client's initial
 getKML request does not revoke permits on the serveri which allows the
 server to continue generating KML even as reintegration proceeds on the 
 client.  In general, just before we do a GetPermit, we can use a GetKML 
 to flush KML without revoking permits. This code does not yet do that 
 because of livelock concerns, however, clearly this is an easy way to
 improve reliability.

 The next step is to prevent the client from requesting permits 
 during sync unless it has pending kml to send.



Index: ReqHandler.pm
===================================================================
RCS file: /cvsroot/intermezzo/intermezzo/lento/Lento/InterMezzo/ReqHandler.pm,v
retrieving revision 1.148
retrieving revision 1.149
diff -U2 -r1.148 -r1.149
--- ReqHandler.pm	2001/10/16 17:11:08	1.148
+++ ReqHandler.pm	2001/10/27 00:14:50	1.149
@@ -313,4 +313,112 @@
 }
 
+# Send pending KML to client 
+# useful during the initial synchronization phase to avoid locked systems
+# Conceivable might happen in other situations as well such as when a
+# client explicitly wants the server to send pending KML before disconnection.
+
+sub FlushKML {
+    my $packet = shift;
+    
+    new POE::Session
+        ([$packet, "FlushKML"], # two arguments to _start
+         'Lento::EventSupport', ['alias_set', 'alias_remove', 
+                                 'get_cookie', '_stop',
+                                 '_child', '_signal', 'AddWaiter',
+                                 'RemoveUpcallWaiter'], 
+         'Lento::InterMezzo::ReqHandler', ['_start', 'finish'],
+         REQ => sub {
+             my $packet = $_[HEAP]->{req_packet};
+             my $connection = $packet->[PKT_CONNECTION];
+             my $fsetname = @{$packet->[PKT_PARMS]}[0];
+
+             # strip the hyphenated prefix if any
+             $fsetname =~ s/^$::prefix//;
+
+             $_[HEAP]->{fsetname} = $fsetname;
+             $_[HEAP]->{connection}= $connection;
+             $_[HEAP]->{session}= $_[SESSION];
+             $_[HEAP]->{session_name} .= " ($fsetname)";
+             
+             # All errors go through at minimum connection level
+             $_[HEAP]->{session_level}=LVL_BIND;
+            
+             if (!defined($fsetname)) {
+                DEBUG "No repinfo or fsetname...invalid repstatus request\n";
+                $_[KERNEL]->yield('sendrep', EINVAL); 
+                return;
+             }
+                         
+             if (!$::fsetdb->find_by_name($fsetname)) {
+                DEBUG " This fset is not known here! \n";
+                $_[KERNEL]->yield('sendrep', ENOENT); 
+                return;
+             }
+
+             my $replicator = $_[HEAP]->{replicator} =
+                 Lento::Replicator::find($connection->{sysid}, $fsetname);
+             my $fset = $replicator->{fileset};
+             
+             if (!defined $replicator) {
+                 DEBUG "no replicator\n";
+                 $_[KERNEL]->yield('sendrep', EPERM);
+                 return;
+             }
+             
+             Lento::Debuggable::set_option
+                 ($_[SESSION], trace => 1, default => 1);
+             
+             # KML movement can take place at LVL_RECOVER
+             $_[HEAP]->{session_level} = LVL_RECOVER;
+
+             # Now send KML to remote
+             my $count=$fset->{kml}->ReintegrateRep($replicator, 
+                                'sendrep');
+             $_[KERNEL]->yield('sendrep') unless $count;
+             return;
+         },
+         sendrep => sub {  
+             # get here when $fset->{permit} has reintegrated
+             my $status = $_[ARG0];
+             my $packet = $_[HEAP]->{req_packet};
+             my $connection = $_[HEAP]->{connection};
+             my $replicator = $_[HEAP]->{replicator}; 
+             
+             confess "Heap changed" if !defined $connection; 
+             
+             if (!Lento::Connection::connected($connection)) {
+                DEBUG "No connection\n";
+                $_[KERNEL]->yield('got_error',"sendrep",ENOTCONN,
+                    "no connection");
+                return;
+             }
+             
+             if (!defined $replicator) {
+                $status=ENOENT unless defined $status;
+                $connection->sendpacket('REP', $packet, [$status]);
+                $_[KERNEL]->yield
+                    ('got_error',"sendrep", ENOTCONN,"no replicator");
+                $connection->set_error
+                    ("repstatus", ENOTCONN, "no replicator");
+                return;
+             }
+
+             $status = 0 unless defined $status;
+
+             $connection->sendpacket('REP', $packet, [$status]);
+
+             $_[HEAP]->{state}="finished";
+             $_[KERNEL]->yield('finish');
+         },
+         got_error => sub {
+             LOG "Error in FlushKML handler\n";
+             
+             $_[HEAP]->{state}='error';
+             $_[KERNEL]->call($_[SESSION],'finish');
+         }, 
+        );
+
+}
+
 #
 # Get the KML from current permit holder


_______________________________________________
intermezzo-commit mailing list
intermezzo-commit@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/intermezzo-commit

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic