
de.jiac.micro.interaction.AbstractInteractionProtocol Maven / Gradle / Ivy
/*
* MicroJIAC - A Lightweight Agent Framework
* This file is part of MicroJIAC Interaction.
*
* Copyright (c) 2007-2011 DAI-Labor, Technische Universität Berlin
*
* This library includes software developed at DAI-Labor, Technische
* Universität Berlin (http://www.dai-labor.de)
*
* 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 3 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, see .
*/
/*
* $Id$
*/
package de.jiac.micro.interaction;
import de.jiac.micro.core.feature.AbstractPeriodicRunnable;
import de.jiac.micro.core.io.IMessage;
import de.jiac.micro.util.List;
import de.jiac.micro.util.List.Node;
/**
* @author Marcel Patzlaff
* @version $Revision:$
*/
public abstract class AbstractInteractionProtocol {
protected static class Interaction {
public final long startTime;
public final long deadline;
public final String id;
public final Object context;
protected Interaction(long timeout, Object ctx) {
startTime= System.currentTimeMillis();
deadline= startTime + timeout;
id= String.valueOf(hashCode());
context= ctx;
}
}
private final class ProtocolTimer extends AbstractPeriodicRunnable {
private long _lastExecution= 0L;
protected ProtocolTimer() {}
protected void runShort() {
final long currentTime= System.currentTimeMillis();
long minDeadline= Long.MAX_VALUE;
synchronized (interactions) {
for(Node n= interactions.head(), end= interactions.tail(); (n= n.next()) != end;) {
Interaction i= (Interaction) n.value();
if(i.deadline <= currentTime) {
Node tmp= n.previous();
interactions.delete(n);
n= tmp;
timeoutInteraction(i);
} else {
if(i.deadline < minDeadline) {
minDeadline= i.deadline;
}
}
}
setPeriod(minDeadline - currentTime);
_lastExecution= currentTime;
}
}
protected void adjustPeriod(long deadline) {
if(isEnabled()) {
long oldStart= getStart();
if(deadline < oldStart) {
setStart(deadline);
} else {
long oldNextExec= _lastExecution + getPeriod();
if(oldNextExec > deadline) {
disable();
setStart(deadline);
enable();
}
}
} else {
setStart(deadline);
enable();
}
}
}
private final ProtocolTimer _timer;
protected final List interactions;
protected final String name;
protected AbstractInteractionProtocol(String protocolName) {
_timer= new ProtocolTimer();
interactions= new List();
name= protocolName;
}
/**
* Caller must hold the lock on interactions!
*/
protected final Interaction newInteraction(long timeout, Object ctx) {
Interaction i= new Interaction(timeout, ctx);
// TODO: insert the new interaction in deadlines ascending order
interactions.addLast(i);
_timer.adjustPeriod(i.deadline);
return i;
}
/**
* Caller must hold the lock on interactions!
*/
protected final Interaction findInteraction(String id) {
for(Node n= interactions.head(), end= interactions.tail(); (n= n.next()) != end;) {
Interaction i= (Interaction)n.value();
if(i.id.equals(id)) {
return i;
}
}
return null;
}
protected final void setProtocolHeader(IMessage message) {
message.setHeader(InteractionManagerElement.INTERACTION_HEADER_KEY, name);
}
protected abstract void handleMessage(IMessage message);
protected abstract void timeoutInteraction(Interaction ia);
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy