[LON-CAPA-cvs] cvs: loncom /homework bridgetask.pm lonhomework.pm

albertel lon-capa-cvs@mail.lon-capa.org
Tue, 03 May 2005 00:05:41 -0000


albertel		Mon May  2 20:05:41 2005 EDT

  Modified files:              
    /loncom/homework	lonhomework.pm bridgetask.pm 
  Log:
  - adding gradding queus mechanism
     - submissions adds to grading queue
     - webgrade attempts to find a suitable user to grade and lock it to myself with proper error handling for a variety of failure modes (i.e tries to do a 2 phase commit)
  
  
Index: loncom/homework/lonhomework.pm
diff -u loncom/homework/lonhomework.pm:1.205 loncom/homework/lonhomework.pm:1.206
--- loncom/homework/lonhomework.pm:1.205	Fri Apr 29 17:22:33 2005
+++ loncom/homework/lonhomework.pm	Mon May  2 20:05:41 2005
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # The LON-CAPA Homework handler
 #
-# $Id: lonhomework.pm,v 1.205 2005/04/29 21:22:33 albertel Exp $
+# $Id: lonhomework.pm,v 1.206 2005/05/03 00:05:41 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -245,7 +245,7 @@
 #	return ($status,$datemsg);
 #    }
     my $slotstatus='NOT_IN_A_SLOT';
-    my $returned_slot;
+    my ($returned_slot,$slot_name);
     foreach my $slot (@slots) {
 	&Apache::lonxml::debug("getting $slot");
 	my %slot=&Apache::lonnet::get_slot($slot);
@@ -256,6 +256,7 @@
 	    &Apache::lonxml::debug("$slot is good");
 	    $slotstatus='NEEDS_CHECKIN';
 	    $returned_slot=\%slot;
+	    $slot_name=$slot;
 	    last;
 	}
     }
@@ -264,7 +265,7 @@
 	&Apache::lonxml::debug("protoctor checked in");
 	$slotstatus='CAN_ANSWER';
     }
-    return ($slotstatus,$datemsg,$returned_slot);
+    return ($slotstatus,$datemsg,$slot_name,$returned_slot);
 }
 
 # JB, 9/24/2002: Any changes in this function may require a change
Index: loncom/homework/bridgetask.pm
diff -u loncom/homework/bridgetask.pm:1.13 loncom/homework/bridgetask.pm:1.14
--- loncom/homework/bridgetask.pm:1.13	Fri Apr 29 17:22:33 2005
+++ loncom/homework/bridgetask.pm	Mon May  2 20:05:41 2005
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA 
 # definition of tags that give a structure to a document
 #
-# $Id: bridgetask.pm,v 1.13 2005/04/29 21:22:33 albertel Exp $
+# $Id: bridgetask.pm,v 1.14 2005/05/03 00:05:41 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -112,9 +112,10 @@
     }
     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
 	$target eq 'tex') {
-	($status,$accessmsg,$slot) = 
+	($status,$accessmsg,my $slot_name,$slot) = 
 	    &Apache::lonhomework::check_task_access('0');
 	push(@Apache::inputtags::status,$status);
+	$Apache::inputtags::slot_name=$slot_name;
 	my $expression='$external::datestatus="'.$status.'";';
 	$expression.='$external::gradestatus="'.$Apache::lonhomework::history{"resource.0.solved"}.'";';
 	&Apache::run::run($expression,$safeeval);
@@ -175,6 +176,9 @@
     } elsif ($target eq 'webgrade') {
 	$result.=$head_tag_start.$body_tag_start.$form_tag_start.
 	    'Yahoo!';
+	$result.=&show_queue();
+	$result.=&get_from_queue();
+
     } else {
 	# page_start returned a starting result, delete it if we don't need it
 	$result = '';
@@ -207,13 +211,18 @@
 	}
 	if ($target eq 'grade') {
 	    my $award='SUBMITTED';
-	    &Apache::essayresponse::file_submission('0','bridgetask','portfiles',$award);
-	    if ($Apache::lonhomework::results{"resource.0.bridgetask.portfiles"}) {
+	    &Apache::essayresponse::file_submission('0','bridgetask','portfiles',\$award);
+	    if ($award eq 'SUBMITTED' &&
+		$Apache::lonhomework::results{"resource.0.bridgetask.portfiles"}) {
 		$Apache::lonhomework::results{"resource.0.tries"}=
 		    1+$Apache::lonhomework::history{"resource.0.tries"};
 	    }
+	    $Apache::lonhomework::results{"resource.0.award"}=$award;
 	    &Apache::lonhomework::showhash(%Apache::lonhomework::results);
 	    &Apache::structuretags::finalize_storage();
+	    if ($award eq 'SUBMITTED') {
+		&add_to_queue();
+	    }
 	}
     } elsif ($target eq 'meta') {
 	$result.='<parameter part="0" package="Task"></parameter>'."\n";
@@ -224,6 +233,123 @@
     return $result;
 }
 
+sub add_to_queue {
+    my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
+    my $cnum=$env{'course.'.$cid.'.num'};
+    my $cdom=$env{'course.'.$cid.'.domain'};
+    my %data;
+    #$data{"$symb\0timestamp"}=time;
+    $data{"$symb\0queue\0$uname\@$udom"}=[$Apache::inputtags::slot_name];
+    &Apache::lonnet::put('gradingqueue',\%data,$cdom,$cnum);
+}
+
+sub show_queue {
+    my $result;
+    my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
+    my $cnum=$env{'course.'.$cid.'.num'};
+    my $cdom=$env{'course.'.$cid.'.domain'};
+    my $regexp="^$symb\0queue";
+    my %queue=&Apache::lonnet::dump('gradingqueue',$cdom,$cnum,$regexp);
+    $result.="<table><tr><th>resource</th><th>user</th><th>Time available for grading</th></tr>";
+    foreach my $key (sort(keys(%queue))) {
+	my ($symb,undef,$user) = split("\0",$key);
+	my ($uname,$udom) = split('@',$user);
+	my $title=&Apache::lonnet::gettitle($symb);
+	$result.="<tr><td>$title</td><td>$uname</td><td>";
+	my $slot=$queue{$key}->[0];
+	my %slot_data=&Apache::lonnet::get_slot($slot);
+	$result.="End time: ".&Apache::lonlocal::locallocaltime($slot_data{'endtime'})."</td></tr>";
+    }
+    $result.="</table>";
+    return $result;
+}
+
+sub decode_queue_key {
+    my ($key)=@_;
+    my ($symb,undef,$user) = split("\0",$key);
+    my ($uname,$udom) = split('@',$user);
+    return ($symb,$uname,$udom);
+}
+
+sub queue_key_locked {
+    my ($key)=@_;
+    my ($key_locked,$value)=
+	&Apache::lonnet::get('gradingqueue',["$key\0locked"],$cdom,$cnum);
+    if ($key_locked eq "$key\0locked") {
+	return $value;
+    }
+    return undef;
+}
+
+sub pick_from_queue_data {
+    my ($check_section,$queue)=@_;
+    foreach my $key (sort(keys(%$queue))) {
+	my ($symb,$uname,$udom)=&decode_queue_key($key);
+	if ($check_section) {
+	    my $section=&Apache::lonnet::getsection($uname,$udom);
+	    if ($section ne $check_section) { next; }
+	}
+	my $slot=$queue->{$key}[0];
+	my %slot_data=&Apache::lonnet::get_slot($slot);
+	if ($slot_data{'endtime'} > time) { next; }
+	if (&queue_key_locked($key)) { next; }
+	return $key;
+    }
+    return undef;
+}
+
+sub get_from_queue {
+    my $result;
+    my ($symb,$cid,$udom,$uname)=&Apache::lonxml::whichuser();
+    my $cnum=$env{'course.'.$cid.'.num'};
+    my $cdom=$env{'course.'.$cid.'.domain'};
+    my $todo;
+    while (1) {
+	my $starttime=time;
+	&Apache::lonnet::put('gradingqueue',{"$symb\0timestamp"=>$starttime},
+			     $cdom,$cnum);
+	my $regexp="^$symb\0queue\0";
+	my %queue=&Apache::lonnet::dump('gradingqueue',$cdom,$cnum,$regexp);
+	#make a pass looking for a user in my section
+	if ($env{'request.course.sec'}) {
+	    $todo=&pick_from_queue_data($env{'request.course.sec'},\%queue);
+	}
+	# no one in our section so look for any user that is ready for grading
+	if (!$todo) {
+	    $todo=&pick_from_queue_data($env{'request.course.sec'},\%queue);
+	}
+	# no user to grade 
+	if (!$todo) { last; }
+	# otherwise found someone so lets try to lock them
+	my $success=&Apache::lonnet::newput('gradingqueue',
+					    {"$todo\0locked"=>
+						 $env{'user.name'}.'@'.$env{'user.domain'}},
+					   $cdom,$cnum);
+	# someone else already picked them
+	if ($success ne 'ok') { next; }
+	my (undef,$endtime)=
+	    &Apache::lonnet::get('gradingqueue',["$symb\0timestamp"],
+				 $cdom,$cnum);
+	# someone else already modified the queue, 
+	# perhaps our picked user wass already fully graded between
+	# when we picked him and when we locked his record? so lets
+	# double check.
+	if ($endtime != $starttime) {
+	    my ($key,$value)=
+		&Apache::lonnet::get('gradingqueue',["$todo"],
+				     $cdom,$cnum);
+	    if ($key eq $todo && ref($value)) {
+	    } else {
+		&Apache::lonnet::del('gradingqueue',["$todo\0locked"],
+				     $cdom,$cnum);
+		next;
+	    }
+	}
+	last;
+    }
+    return $todo;
+}
+
 sub start_ClosingParagraph {
     my ($target,$token,$tagstack,$parstack,$parser,$safeeval)=@_;
     my $result;