|
From: <jom...@us...> - 2008-09-10 09:42:30
|
Revision: 1363
http://jason.svn.sourceforge.net/jason/?rev=1363&view=rev
Author: jomifred
Date: 2008-09-10 09:42:28 +0000 (Wed, 10 Sep 2008)
Log Message:
-----------
use agent scheduler instead of a new thread for send ask with timeout
Modified Paths:
--------------
trunk/src/jason/asSemantics/SuspendInternalAction.java
trunk/src/jason/stdlib/send.java
Modified: trunk/src/jason/asSemantics/SuspendInternalAction.java
===================================================================
--- trunk/src/jason/asSemantics/SuspendInternalAction.java 2008-09-09 11:44:01 UTC (rev 1362)
+++ trunk/src/jason/asSemantics/SuspendInternalAction.java 2008-09-10 09:42:28 UTC (rev 1363)
@@ -10,11 +10,11 @@
/**
- This class can be used in place of DefaultInternalAction to create IA that
- suspend/resume the intention.
+ This class can be used in place of DefaultInternalAction to create an IA that
+ suspend the intention while it is being executed.
- Example: a plan should to ask something to an user and wait until he/she answer some.
- If DefaultInternalAction is used for that, all the agent thread is suspended until
+ Example: a plan may ask something to an user and wait the answer.
+ If DefaultInternalAction is used for that, all the agent thread is blocked until
the answer. With SuspendInternalAction, only the intention using the IA is
suspended. See demos/gui/gui1.
Modified: trunk/src/jason/stdlib/send.java
===================================================================
--- trunk/src/jason/stdlib/send.java 2008-09-09 11:44:01 UTC (rev 1362)
+++ trunk/src/jason/stdlib/send.java 2008-09-10 09:42:28 UTC (rev 1363)
@@ -25,18 +25,20 @@
package jason.stdlib;
import jason.JasonException;
-import jason.asSemantics.Circumstance;
import jason.asSemantics.DefaultInternalAction;
import jason.asSemantics.Intention;
import jason.asSemantics.Message;
import jason.asSemantics.TransitionSystem;
import jason.asSemantics.Unifier;
+import jason.asSyntax.Atom;
import jason.asSyntax.ListTerm;
import jason.asSyntax.NumberTerm;
import jason.asSyntax.StringTerm;
import jason.asSyntax.Structure;
import jason.asSyntax.Term;
+import java.util.concurrent.TimeUnit;
+
/**
<p>Internal action: <b><code>.send</code></b>.
@@ -121,18 +123,15 @@
private boolean lastSendWasSynAsk = false;
@Override
- public Object execute(TransitionSystem ts, Unifier un, Term[] args) throws Exception {
- Term to = null;
- Term ilf = null;
- Term pcnt = null;
- // check parameters
+ public Object execute(final TransitionSystem ts, Unifier un, Term[] args) throws Exception {
try {
- to = args[0];
- ilf = args[1];
- pcnt = args[2];
+ // check parameters
+ Term to = args[0];
+ Term ilf = args[1];
+ Term pcnt = args[2];
if (!to.isAtom() && !to.isList() && !to.isString()) {
- throw new JasonException("The TO parameter ('"+to+"') of the internal action 'send' is not an atom or list of atoms!");
+ throw new JasonException("The TO parameter ('"+to+"') of the internal action 'send' is not an atom, a string nor a list of receivers!");
}
if (! ilf.isAtom()) {
@@ -145,28 +144,26 @@
// ((Pred)pcnt).delSources();
//} catch (Exception e) {}
- } catch (ArrayIndexOutOfBoundsException e) {
- throw new JasonException("The internal action 'send' to '"+to+"' has not received three arguments.");
- }
- Message m = new Message(ilf.toString(), ts.getUserAgArch().getAgName(), null, pcnt);
-
- // async ask has a fourth argument and should suspend the intention
- lastSendWasSynAsk = m.isAsk() && args.length > 3;
- if (lastSendWasSynAsk) {
- ts.getC().getPendingIntentions().put(m.getMsgId(), ts.getC().getSelectedIntention());
- }
-
- // (un)tell or unknown performative with 4 args is a reply to
- if ( (m.isTell() || m.isUnTell() || !m.isKnownPerformative()) && args.length > 3) {
- Term mid = args[3];
- if (! mid.isAtom()) {
- throw new JasonException("The Message ID ('"+mid+"') parameter of the internal action 'send' is not an atom!");
+
+ // create a message to be sent
+ final Message m = new Message(ilf.toString(), ts.getUserAgArch().getAgName(), null, pcnt);
+
+ // async ask has a fourth argument and should suspend the intention
+ lastSendWasSynAsk = m.isAsk() && args.length > 3;
+ if (lastSendWasSynAsk) {
+ ts.getC().getPendingIntentions().put(m.getMsgId(), ts.getC().getSelectedIntention());
}
- m.setInReplyTo(mid.toString());
- }
+
+ // (un)tell or unknown performative with 4 args is a reply to
+ if ( (m.isTell() || m.isUnTell() || !m.isKnownPerformative()) && args.length > 3) {
+ Term mid = args[3];
+ if (! mid.isAtom()) {
+ throw new JasonException("The Message ID ('"+mid+"') parameter of the internal action 'send' is not an atom!");
+ }
+ m.setInReplyTo(mid.toString());
+ }
- // send the message
- try {
+ // send the message
if (to.isList()) {
if (m.isAsk() && args.length > 3) {
throw new JasonException("Cannot send 'ask' to a list of receivers!");
@@ -197,54 +194,37 @@
// get the timeout deadline
Term tto = (Term)args[4];
if (tto.isNumeric()) {
- new CheckTimeout((long)((NumberTerm)tto).solve(), m.getMsgId(), ts.getC()).start();
+ ts.getAg().getScheduler().schedule( new Runnable() {
+ public void run() {
+ // if the intention is still in PI, brings it back to C.I
+ Intention intention = ts.getC().getPendingIntentions().remove(m.getMsgId());
+ if (intention != null) {
+ // unify "timeout" with the fourth parameter of .send
+ Structure send = (Structure)intention.peek().removeCurrentStep();
+ intention.peek().getUnif().unifies(send.getTerm(3), new Atom("timeout"));
+ // add the intention back in C.I
+ ts.getC().addIntention(intention);
+ System.out.println("OK");
+ }
+ }
+ }, (long)((NumberTerm)tto).solve(), TimeUnit.MILLISECONDS);
} else {
throw new JasonException("The 5th parameter of send must be a number (timeout) and not '"+tto+"'!");
}
}
return true;
+ } catch (ArrayIndexOutOfBoundsException e) {
+ throw new JasonException("The internal action 'send' to '"+args[0]+"' has not received three arguments.");
+ } catch (JasonException e) {
+ throw e;
} catch (Exception e) {
- throw new JasonException("Error sending message " + m + "\nError: "+e, e);
+ throw new JasonException("Error sending message " + args + "\nError: "+e, e);
}
}
@Override
public boolean suspendIntention() {
return lastSendWasSynAsk;
- }
-
-
- private static Structure timeoutTerm = new Structure("timeout");
-
- class CheckTimeout extends Thread {
-
- private long timeout = 0;
- private String idInPending;
- private Circumstance c;
-
- public CheckTimeout(long to, String rw, Circumstance c) {
- this.timeout = to;
- this.idInPending = rw;
- this.c = c;
- }
-
- public void run() {
- try {
- sleep(timeout);
-
- // if the intention is still in PI, brings it back to C.I
- Intention intention = c.getPendingIntentions().remove(idInPending);
- if (intention != null) {
- // unify "timeout" with the fourth parameter of .send
- Structure send = (Structure)intention.peek().removeCurrentStep();
- intention.peek().getUnif().unifies(send.getTerm(3), timeoutTerm);
- // add the intention back in C.I
- c.addIntention(intention);
- }
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- }
- }
+ }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|