/* ************************************************************************* *
* *
* Copyright (c) 2012 Peter Cappello <cappello@cs.ucsb.edu> *
* *
* Permission is hereby granted, free of charge, to any person obtaining *
* a copy of this software and associated documentation files (the *
* "Software"), to deal in the Software without restriction, including *
* without limitation the rights to use, copy, modify, merge, publish, *
* distribute, sublicense, and/or sell copies of the Software, and to *
* permit persons to whom the Software is furnished to do so, subject to *
* the following conditions: *
* *
* The above copyright notice and this permission notice shall be *
* included in all copies or substantial portions of the Software. *
* *
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, *
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF *
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. *
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY *
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, *
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE *
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
* *
* ************************************************************************* */
/**
* Encapsulates a List of Commands to be sent to a particular Service.
*
* @version 1.0
* @author Peter Cappello
*/
package jicosfoundation;
import java.util.Iterator;
import java.util.Queue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class Mailer extends Processor
{
private Service fromAddress;
private Service toAddress; // the destination of this Mail
private Queue<Command> commandQ = new ConcurrentLinkedQueue<Command>();
private BlockingQueue<Mailer> mailQ; // queue of references to this.
private RemoteExceptionHandler remoteExceptionHandler;
private Proxy myProxy;
private final ReadWriteLock commandQLock = new ReentrantReadWriteLock();
private final Lock r = commandQLock.readLock();
private final Lock w = commandQLock.writeLock();
public Mailer(Service fromAddress, RemoteExceptionHandler remoteExceptionHandler,
BlockingQueue<Mailer> mailQ, Proxy myProxy)
{
super(mailQ, "Mailer");
assert fromAddress != null;
assert remoteExceptionHandler != null;
this.fromAddress = fromAddress;
this.remoteExceptionHandler = remoteExceptionHandler;
this.mailQ = mailQ;
this.myProxy = myProxy;
toAddress = myProxy.getService();
}
/**
* Add a Command to the list.
*
* @param command The Command object to be added.
*/
public void add(Command command)
{
assert command != null;
// synchronization is necessary to ensure add completes before copyCommandQ makes commandQ garbage.
r.lock();
try
{
commandQ.add(command);
} finally
{
r.unlock();
}
try
{
mailQ.add(this); // notify mail processor: send commandQ
} catch (Exception e)
{
e.printStackTrace();
}
}
private Queue copyCommandQ()
{
Queue<Command> commandQCopy;
Queue<Command> temp = new ConcurrentLinkedQueue<Command>();
w.lock();
try
{
commandQCopy = commandQ;
commandQ = temp;
} finally
{
w.unlock();
}
return commandQCopy;
}
/**
* Mail command queue to destination distributed component
*/
@Override
void process(Object object)
{
if (commandQ.isEmpty())
{
return;
}
Queue<Command> commandQCopy = copyCommandQ();
try
{
toAddress.receiveCommands(fromAddress, commandQCopy);
} catch (Exception exception)
{
exception.printStackTrace();
System.out.println("Mail: toAddress: " + toAddress + "\n Command Q: \n");
for (Iterator iterator = commandQCopy.iterator(); iterator.hasNext();)
{
System.out.println(((Command) iterator.next()));
}
myProxy.evict();
System.exit(1); // !! TODO modify when jPregel becomes fault-tolerant
//remoteExceptionHandler.handle ( exception, fromAddress, toAddress );
}
}
/**
* Returns a String representation of the object.
*
* @return A String representation of the object.
*/
public String toString()
{
StringBuffer stringBuffer = new StringBuffer("Mail: toAddress: " + toAddress);
stringBuffer.append("\n Command Q: \n");
for (Iterator iterator = commandQ.iterator(); iterator.hasNext();)
{
stringBuffer.append(((Command) iterator.next()).toString());
}
return new String(stringBuffer);
}
}