/* LIME 1.1 - A middleware for coordination of mobile agents and mobile hosts * Copyright (C) 2003, * Chien-Liang Fok, Christine Julien, Radu Handorean, Rohan Sen, Tom Elgin, * Amy L. Murphy, Gian Pietro Picco, and Gruia-Catalin Roman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ import lights.interfaces.*; import lights.adapters.*; import java.net.*; import java.io.*; import java.util.*; import lime.*; /** *

This class provides an extension to the regular LimeTupleSpace which * provides weak, ubiquitous operations on the federated tuple space. These * operations are not performed atomically over a snapshot of the federated * tuple space, but instead are performed individually and incrementally over * the hosts which are present when the operation is invoked. For example, if * hosts A, B and C have agents with transiently shared tuple spaces of the * same name, if an agent on host A issues one of these weak operations, the * result returned will be the cumulative result of probing operation * performed first on A, then on B, then on C. If B or C disconnect before * the operation is complete, it is as if the result of the probe of that host * returned null. If host D connects during the operation, D is * ignored for this operation. * *

To use this class, an agent should create an instance of a * WeakProbeLimeTupleSpace instead of a * LimeTupleSpace. All normal operations of a * LimeTupleSpace are available through a * WeakProbeLimeTupleSpace, and it is possible for an agent with * an instance of this class to issue one of the specific operations of this * class on tuple spaces which are not of this type. In other words, the * agents on host B and C of the example above need not have tuple spaces of * type WeakProbeLimeTupleSpace...only the agent issuing the * operation must have a tuple space of this type. * *

It should be noted that none of the weak ubiquitous operations should be * called from within a reaction as an exception will be thrown. * * @author Amy L. Murphy * @version 1.0 * @see LimeTupleSpace */ public class WeakProbeLimeTupleSpace extends LimeTupleSpace { // a vector containing the set of hosts in the current Lime configuration. // Each entry of the vector is a HostLocation Vector hostsInSystem = new Vector(10); HostLocation thisHostLocation = new HostLocation(LimeServer.getServer().getServerID()); ITuple hostPattern = new Tuple().addActual("_host").addFormal(LimeServerID.class); static final short WEAKRDP = 1; static final short WEAKINP = 2; static final short WEAKING = 3; static final short WEAKRDG = 4; // This is done to allow the WeakProbeLimeTupleSpace to be used inside a // mobile agent. A mobile agent does not migrate with its LSTS, but // instead rebinds to the new one at each destination. private transient LimeSystemTupleSpace tlsts = new LimeSystemTupleSpace(); LimeSystemTupleSpace lsts() { if(tlsts==null) tlsts = new LimeSystemTupleSpace(); if(tlsts==null) throw new NullPointerException("Problems in the system tuple space"); return tlsts; } /** * Creates a new WeakProbeLimeTupleSpace instance. Note, all * the usual LimeTupleSpace operations can be called on an object of this * type. * * @param name a String for the name of the tuple space * @exception TupleSpaceEngineException if an error occurs */ public WeakProbeLimeTupleSpace (String name) throws TupleSpaceEngineException { super (name); } /** * Creates a new WeakProbeLimeTupleSpace instance with the * default name. Note, all the usual LimeTupleSpace operations can be called * on an object of this type. * * @exception TupleSpaceEngineException if an error occurs */ public WeakProbeLimeTupleSpace () throws TupleSpaceEngineException { super(); } /////////////////////////////////////////// // operations without destination specified /////////////////////////////////////////// /** * Retrieves a copy of a tuple that matches a given template, or returns * null if no matching tuple exists. The whole transiently * shared tuple space is searched, but the search is NOT done on a snapshot * of the federated space. Instead, the operation sequentially searches the * hosts which are connected when the operation is issued. If multiple * tuples match the template, one is selected non-deterministically. If * no matching tuple is present, null is returned. * * @param template the template the return tuple must be matched against. * @return a copy of a tuple that matches the template, or null * if the tuple cannot be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple weakRdp(ITuple template) throws TupleSpaceEngineException { return weakRdp(AgentLocation.UNSPECIFIED, template); } /** * Retrieves a tuple that matches a given template and removes it from the * tuple space, or returns null if no matching tuple exists. * The whole transiently shared tuple space is searched, but the search is * NOT done on a snapshot of the federated space. Instead, the operation * sequentially searches the hosts which are connected when the operation is * issued. If multiple tuples match the template, one is selected * non-deterministically. If no matching tuple is present, * null is returned. * * @param template the template the return tuple must be matched against. * @return a copy of a tuple that matches the template, or null * if the tuple cannot be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple weakInp (ITuple template) throws TupleSpaceEngineException { return weakInp(AgentLocation.UNSPECIFIED, template); } /** * Retrieves all tuples that match a given template and removes them from * the tuple space, or returns null if no matching tuples * exist. The whole transiently shared tuple space is searched, but the * search is NOT done on a snapshot of the federated space. Instead, the * operation sequentially searches the hosts which are connected when the * operation is issued. If no matching tuples are present, * null is returned. * * @param template the template the return tuples must be matched against. * @return a copy of a tuples that match the template, or null * if no tuples can be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple[] weakIng (ITuple template) throws TupleSpaceEngineException { return weakIng(AgentLocation.UNSPECIFIED, template); } /** * Retrieves all tuples that match a given template, or returns * null if no matching tuples exist. The whole transiently * shared tuple space is searched, but the search is NOT done on a snapshot * of the federated space. Instead, the operation sequentially searches the * hosts which are connected when the operation is issued. If no * matching tuples are present, null is returned. * * @param template the template the return tuples must match against. * @return a copy of a tuples that match the template, or null * if no tuples can be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple[] weakRdg (ITuple template) throws TupleSpaceEngineException { return weakRdg(AgentLocation.UNSPECIFIED, template); } // operations with a specified destination /** * Retrieves a copy of a tuple that matches a given template, or returns * null if no matching tuple exists. The whole transiently * shared tuple space is searched, but the search is NOT done on a snapshot * of the federated space. Instead, the operation sequentially searches the * hosts which are connected when the operation is issued. If multiple * tuples match the template, one is selected non-deterministically. If no * matching tuple is present, null is returned. * * @param destination the destination location of the tuple that can be * searched. The value AgentLocation.UNSPECIFIED is allowed, * in which case only the current location will matter. * @param template the template the return tuple must be matched against. * @return a copy of a tuple that matches the template, or null * if the tuple cannot be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple weakRdp (AgentLocation destination, ITuple template) throws TupleSpaceEngineException { return doWeak(destination, template, WEAKRDP); } /** * Retrieves a tuple that matches a given template and removes it from the * tuple space, or returns null if no matching tuple exists. * The whole transiently shared tuple space is searched, but the search is * NOT done on a snapshot of the federated space. Instead, the operation * sequentially searches the hosts which are connected when the operation is * issued. If multiple tuples match the template, one is selected * non-deterministically. If no matching tuple is present, * null is returned. * * @param destination the destination location of the tuple that can be * searched. The value AgentLocation.UNSPECIFIED is allowed, * in which case only the current location will matter. * @param template the template the return tuple must be matched against. * @return a copy of a tuple that matches the template, or null * if the tuple cannot be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple weakInp (AgentLocation destination, ITuple template) throws TupleSpaceEngineException { return doWeak(destination, template, WEAKINP); } /** * Retrieves all tuples that match a given template and removes them from * the tuple space, or returns null if no matching tuples * exist. The whole transiently shared tuple space is searched, but the * search is NOT done on a snapshot of the federated space. Instead, the * operation sequentially searches the hosts which are connected when the * operation is issued. If no matching tuples are present, * null is returned. * * @param destination the destination location of the tuple that can be * searched. The value AgentLocation.UNSPECIFIED is allowed, * in which case only the current location will matter. * @param template the template the return tuple must be matched against. * @return a copy of a tuples that match the template, or null * if no tuples can be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple[] weakIng (AgentLocation destination, ITuple template) throws TupleSpaceEngineException { ITuple t = doWeak(destination, template, WEAKING); if (t==null) return null; else return (ITuple[]) t.get(0).getValue(); } /** * Retrieves all tuples that match a given template, or returns * null if no matching tuples exist. The whole transiently * shared tuple space is searched, but the search is NOT done on a snapshot * of the federated space. Instead, the operation sequentially searches the * hosts which are connected when the operation is issued. If no matching * tuples are present, null is returned. * * @param destination the destination location of the tuple that can be * searched. The value AgentLocation.UNSPECIFIED is allowed, * in which case only the current location will matter. * @param template the template the return tuple must be matched against. * @return a copy of a tuples that match the template, or null * if the tuple cannot be found. * @exception TupleSpaceEngineException if a problem is encountered in the * processing. */ public ITuple[] weakRdg (AgentLocation destination, ITuple template) throws TupleSpaceEngineException { ITuple t = doWeak(destination, template, WEAKRDG); if (t==null) return null; else return (ITuple[]) t.get(0).getValue(); } // returns either the tuple returned, or an array of tuples as the first // field of the returned tuple ITuple doWeak(AgentLocation destination, ITuple template, short type) throws TupleSpaceEngineException { ITuple result = null; ITuple [] matchingTuples = null; // always look locally switch(type){ case WEAKRDP: result = rdp(thisHostLocation, destination, template); break; case WEAKINP: result = inp(thisHostLocation, destination, template); break; case WEAKRDG: matchingTuples = rdg(thisHostLocation, destination, template); break; case WEAKING: matchingTuples = ing(thisHostLocation, destination, template); break; } // if the ts is public, then cycle through all connected hosts. If one // is found (for inp and rdp), stop cycling. Note, in the case of group // operations, the result variable will remain null until all hosts have // been proved (keeping the loop from exiting early without checking all // of the connected hosts). if (isShared() && result == null) { ITuple[] hosts = lsts().rdgp(hostPattern); int i = 0; while (result == null && i