All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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