[LON-CAPA-cvs] cvs: modules /gerd/maxima lonmaxima server.py
www
lon-capa-cvs@mail.lon-capa.org
Wed, 08 Mar 2006 03:18:44 -0000
This is a MIME encoded message
--www1141787924
Content-Type: text/plain
www Tue Mar 7 22:18:44 2006 EDT
Added files:
/modules/gerd/maxima server.py
Modified files:
/modules/gerd/maxima lonmaxima
Log:
Does a lot of interesting things, except work
--www1141787924
Content-Type: text/plain
Content-Disposition: attachment; filename="www-20060307221844.txt"
Index: modules/gerd/maxima/lonmaxima
diff -u modules/gerd/maxima/lonmaxima:1.11 modules/gerd/maxima/lonmaxima:1.12
--- modules/gerd/maxima/lonmaxima:1.11 Sat Mar 4 10:47:26 2006
+++ modules/gerd/maxima/lonmaxima Tue Mar 7 22:18:42 2006
@@ -3,7 +3,7 @@
# The LearningOnline Network with CAPA
# Connect to MAXIMA CAS
#
-# $Id: lonmaxima,v 1.11 2006/03/04 15:47:26 www Exp $
+# $Id: lonmaxima,v 1.12 2006/03/08 03:18:42 www Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -43,66 +43,34 @@
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 $maximapid; # PID of Maxima process
-use vars qw($PREFORK $MAX_CLIENTS_PER_CHILD %children $children $status
- $pidfile $port %perlvar $lastlog $maximapid);
+use vars qw($PREFORK $MAX_CLIENTS_PER_CHILD %children $children %usedmaximaports $status
+ $pidfile $port %perlvar $lastlog);
sub maximareply {
- my ($cmd) = @_;
+ my ($cmd,$maximaclient,$maximapid) = @_;
my $reply='';
- my $error='';
- my $exitstatus='';
-
+ while (my $line=<$maximaclient>) {
+ $reply.=$line;
+ }
unless ($cmd=~/\;\n$/) { $cmd.=";\n"; }
-
- my ($cmd_in, $cmd_out, $cmd_err);
- $maximapid = open3($cmd_in, $cmd_out, $cmd_err, 'maxima');
- $children{$maximapid} = 1;
-
- print $cmd_in $cmd;
- close($cmd_in);
-
- &status("Command sent");
-
- $SIG{ALRM} = sub { kill(9 => $maximapid); };
- alarm(5);
-
- my $selector = IO::Select->new();
-
- $selector->add($cmd_err, $cmd_out);
-
- while (my @ready = $selector->can_read()) {
- foreach my $fh (@ready) {
- if (ref($fh)
- && ref($cmd_err)
- && fileno($fh) == fileno($cmd_err)) {
- $error.=<$cmd_err>;
- } else {
- my $line = scalar(<$cmd_out>);
- if ($line=~/^(\(\%o|\s)/) {
- $line=~s/^\(.*\)/ /;
- $reply.=$line;
- }
- }
- $selector->remove($fh) if eof($fh);
- }
+ print $maximaclient $cmd;
+ &status("Command sent to $maximapid");
+ while (my $line=<$maximaclient>) {
+ $reply.=$line;
}
- alarm(0);
- $SIG{ALRM} = 'DEFAULT';
- if (ref($cmd_out)) { close($cmd_out); }
- if (ref($cmd_err)) { close($cmd_err); }
-
- &status("Command processed");
- return ($reply,$error,$exitstatus);
+ &status("Command processed by $maximapid");
+ return $reply;
}
# ------------------------------------------------------------ Service routines
@@ -111,6 +79,7 @@
$SIG{CHLD} = \&REAPER;
my $pid = wait;
$children--;
+ delete($usedmaximaports{$children{$pid}});
delete($children{$pid});
}
@@ -252,10 +221,12 @@
# Install signal handlers.
$SIG{CHLD} = \&REAPER;
$SIG{INT} = $SIG{TERM} = \&HUNTSMAN;
-
+
+my $maximaport=$STARTPORT;
# Fork off our children.
for (1 .. $PREFORK) {
- &make_new_child($server);
+ &make_new_child($server,$maximaport);
+ $maximaport++;
}
# And maintain the population.
@@ -264,12 +235,16 @@
sleep; # wait for a signal (i.e., child's death)
for (my $i = $children; $i < $PREFORK; $i++) {
&status('Parent process, starting child');
- &make_new_child($server); # top up the child pool
+ my $newport;
+ foreach $newport ($STARTPORT .. $STARTPORT+$PREFORK-1) {
+ if (!defined($usedmaximaports{$newport})) { last; }
+ }
+ &make_new_child($server,$newport); # top up the child pool
}
}
sub make_new_child {
- my ($server) = @_;
+ my ($server,$maximaport) = @_;
# block signal for fork
my $sigset = POSIX::SigSet->new(SIGINT);
@@ -282,7 +257,7 @@
# Parent records the child's birth and returns.
sigprocmask(SIG_UNBLOCK, $sigset)
or die("Can't unblock SIGINT for fork: $!\n");
- $children{$pid} = 1;
+ $children{$pid} = $maximaport;
$children++;
return;
} else {
@@ -292,11 +267,42 @@
# unblock signals
sigprocmask(SIG_UNBLOCK, $sigset)
or die("Can't unblock SIGINT for fork: $!\n");
-
- &process_requests($server);
+
+ # 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";
+
+ # open MAXIMA to talk to that port
+ my ($cmd_in, $cmd_out, $cmd_err);
+ my $maximapid = open3($cmd_in, $cmd_out, $cmd_err, "maxima -s $maximaport");
+ $children{$maximapid} = 1;
+
+ my $prompt=<$cmd_out>;
+ &logthis("Maxima $maximapid: $prompt");
+
+ &status("Waiting $maximapid on $maximaport");
+ # Hopefully, MAXIMA calls us back
+ my $maximaclient=$maximaserver->accept();
+ &status("$maximapid on $maximaport connected.");
+ &logthis("Maxima $maximapid on port $maximaport connected.");
+
+ # Absorb initial prompts
+ &logthis(&maximareply("0;\n",$maximaclient,$maximapid));
+
+ # Ready for action
+
+ &process_requests($server,$maximaclient,$maximapid);
# tidy up gracefully and finish
+ if (ref($cmd_out)) { close($cmd_out); }
+ if (ref($cmd_err)) { close($cmd_err); }
+ if (ref($cmd_in)) { close($cmd_in); }
+
# this exit is VERY important, otherwise the child will become
# a producer of more and more children, forking yourself into
# process death.
@@ -305,14 +311,14 @@
}
sub process_requests {
- my ($server) = @_;
+ my ($server,$maximaclient,$maximapid) = @_;
# handle connections until we've reached $MAX_CLIENTS_PER_CHILD
for (my $i=0; $i < $MAX_CLIENTS_PER_CHILD; $i++) {
- &status('Accepting connections');
+ &status('Accepting connections for '.$maximapid.' on '.$maximaport);
my $client = $server->accept() or last;
while (my $cmd=<$client>) {
- &status('Processing command');
- print $client &escape((&maximareply(&unescape($cmd)))[0])."\n";
+ &status('Processing command by '.$maximapid.' on '.$maximaport);
+ print $client &escape((&maximareply(&unescape($cmd),$maximaclient,$maximapid))[0])."\n";
}
}
}
Index: modules/gerd/maxima/server.py
+++ modules/gerd/maxima/server.py
import socket
import threading
class reader (threading.Thread):
def __init__ (self, s2):
threading.Thread.__init__ (self)
self.s2 = s2
def run (self):
import sys
s = self.s2.recv (64)
while len (s) > 0:
sys.stderr.write (s)
s = self.s2.recv (64)
class writer (threading.Thread):
def __init__ (self, s2):
threading.Thread.__init__ (self)
self.s2 = s2
def run (self):
import sys
while 1:
s = sys.stdin.readline ()
self.s2.send (s)
s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
s.bind (('', 2080))
s.listen (5)
(s2, address) = s.accept ()
t1 = reader (s2)
t2 = writer (s2)
t1.start ()
t2.start ()
--www1141787924--