[LON-CAPA-cvs] cvs: modules /gerd/maxima lonmaxima server.pl

www lon-capa-cvs@mail.lon-capa.org
Wed, 08 Mar 2006 15:58:06 -0000


www		Wed Mar  8 10:58:06 2006 EDT

  Added files:                 
    /modules/gerd/maxima	server.pl 

  Modified files:              
    /modules/gerd/maxima	lonmaxima 
  Log:
  The latest on running the server
  
  
Index: modules/gerd/maxima/lonmaxima
diff -u modules/gerd/maxima/lonmaxima:1.14 modules/gerd/maxima/lonmaxima:1.15
--- modules/gerd/maxima/lonmaxima:1.14	Wed Mar  8 09:22:14 2006
+++ modules/gerd/maxima/lonmaxima	Wed Mar  8 10:58:03 2006
@@ -3,7 +3,7 @@
 # The LearningOnline Network with CAPA
 # Connect to MAXIMA CAS
 #
-# $Id: lonmaxima,v 1.14 2006/03/08 14:22:14 www Exp $
+# $Id: lonmaxima,v 1.15 2006/03/08 15:58:03 www Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -37,8 +37,6 @@
 use IO::File;
 use Symbol;
 use POSIX;
-use Fcntl;
-use Socket;
 use lib '/home/httpd/lib/perl/';
 use LONCAPA::Configuration;
  
@@ -131,18 +129,6 @@
     die("Signal abend");
 }
 
-# -------------------------------------------------- make a socket non-blocking
-sub nonblock {
-    my $socket = shift;
-    my $flags;
-    if (ref($socket)) { 
-       $flags = fcntl($socket, F_GETFL, 0)
-            or die "Can't get flags for socket: $!\n";
-       fcntl($socket, F_SETFL, $flags | O_NONBLOCK)
-            or die "Can't make socket nonblocking: $!\n";
-    }
-}
-
 # ---------------------------------------------------------------- Main program
 # -------------------------------- Set signal handlers to record abnormal exits
  
@@ -277,9 +263,8 @@
                                               Reuse     => 1,
                                               Listen    => 10 )
                         or die "making socket: $@\n";
-        &nonblock($maximaserver);
         my $maximaselect=IO::Select->new($maximaserver);
-        sleep(2);
+        sleep(1);
 
         # open MAXIMA to talk to that port
         my ($cmd_in, $cmd_out, $cmd_err);
@@ -291,10 +276,12 @@
         # hopefully, MAXIMA calls us back
         &status("Waiting $maximapid on $maximaport");
         my $maximaclient=$maximaserver->accept();
+        $maximaclient->blocking(0);
         $maximaselect->add($maximaclient);
-        &nonblock($maximaclient);
         &status("$maximapid on $maximaport connected.");
         &logthis("Maxima $maximapid on port $maximaport connected.");
+        sleep(2);
+
         &logthis('Initial reply: '.&maximareply($maximaselect));
         # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
         for (my $i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
@@ -302,7 +289,7 @@
             my $client = $server->accept()     or last;
             while (my $cmd=<$client>) {
                 &status('Processing command by '.$maximapid.' on '.$maximaport);
-                print $maximaclient &unescape($cmd).";\n";
+                &maximawrite($maximaselect,&unescape($cmd).";\n");
                 print $client &escape(&maximareply($maximaselect))."\n";
             }
         }
@@ -323,6 +310,7 @@
 sub maximareply {
    my ($maximaselect)=@_;
    my $output='';
+   
    foreach my $ready ($maximaselect->can_read(1)) {
        my $data = '';
        my $rv   = $ready->recv($data, POSIX::BUFSIZ, 0);
@@ -331,3 +319,14 @@
    return $output;
 }
 
+sub maximawrite {
+   my ($maximaselect,$cmd)=@_;
+   my $ready=($maximaselect->can_write(1));
+   if (ref($ready)) {
+      print $ready $cmd;
+   } else {
+      &logthis("Cannot write: ".&maximareply($maximaselect));
+   }
+}
+
+

Index: modules/gerd/maxima/server.pl
+++ modules/gerd/maxima/server.pl
 
use IPC::Open3;
use IO::Select;
use IO::Socket;
use IO::File;
use Symbol;
use POSIX;
use Fcntl;
use Socket;
use lib '/home/httpd/lib/perl/';
use LONCAPA::Configuration;
 
use strict;

# global variables
my $STARTPORT              = 5664;     # port for first child's server
my $PREFORK                = 5;        # number of children to maintain
my $MAX_CLIENTS_PER_CHILD  = 5;        # number of clients each child should process
my %children               = ();       # keys are current child process IDs
my %usedmaximaports        = ();       # keys are the used maximaports
my $children               = 0;        # current number of children
my $status;                            # string for current status
my $pidfile;                           # file containg parent process pid
my $port;                              # path to UNIX socket file
my %perlvar;                           # configuration file info
my $lastlog;                           # last string that was logged
my $maximaport=5664;

use vars qw($PREFORK $MAX_CLIENTS_PER_CHILD %children $children %usedmaximaports $status
            $pidfile $port %perlvar $lastlog);
        
        # open the MAXIMA port
        my $maximaserver = IO::Socket::INET->new(LocalPort => $maximaport,
                                              Type      => SOCK_STREAM,
                                              Proto     => 'tcp',
                                              Reuse     => 1,
                                              Listen    => 10 )
                        or die "making socket: $@\n";
#        &nonblock($maximaserver);
        my $maximaselect=IO::Select->new($maximaserver);
        sleep(1);

        # hopefully, MAXIMA calls us back
        &status("Waiting  on $maximaport");
        my $maximaclient=$maximaserver->accept();
        $maximaselect->add($maximaclient);
#        &nonblock($maximaclient);

        &logthis('Initial reply: '.&maximareply($maximaselect));
#        # handle connections until we've reached $MAX_CLIENTS_PER_CHILD
#        for (my $i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
#            &status('Accepting connections for '.$maximapid.' on '.$maximaport);
#            my $client = $server->accept()     or last;
#            while (my $cmd=<$client>) {
#                &status('Processing command by '.$maximapid.' on '.$maximaport);
#                &maximawrite($maximaselect,&unescape($cmd).";\n");
#                print $client &escape(&maximareply($maximaselect))."\n";
#            }
#        }

        # this exit is VERY important, otherwise the child will become
        # a producer of more and more children, forking yourself into
        # process death.
        exit;

sub maximareply {
   my ($maximaselect)=@_;
   my $output='';
   foreach my $ready ($maximaselect->can_read(1)) {
       my $data = '';
       my $rv   = $ready->recv($data, POSIX::BUFSIZ, 0);
       $output.=$data;
   }
   return $output;
}

sub maximawrite {
   my ($maximaselect,$cmd)=@_;
   my $ready=$maximaselect->can_write(1);
   if (ref($ready)) {
      print $ready $cmd;
   } else {
      &logthis("Cannot write: ".&maximareply($maximaselect));
   }
}

# -------------------------------------------------- make a socket non-blocking
sub nonblock {
    my $socket = shift;
    my $flags;
    if (ref($socket)) { 
       $flags = fcntl($socket, F_GETFL, 0)
            or die "Can't get flags for socket: $!\n";
       fcntl($socket, F_SETFL, $flags | O_NONBLOCK)
            or die "Can't make socket nonblocking: $!\n";
    }
}

sub status {
   my ($what)=@_;
   print $what."\n";
}

sub logthis {
   my ($what)=@_;
   print $what."\n";
}