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

org.piax.gtrans.tsd.TSDDiscoverable Maven / Gradle / Ivy

The newest version!
/*
 * TSDDiscoverable.java
 * 
 * Copyright (c) 2012-2015 National Institute of Information and 
 * Communications Technology
 * 
 * You can redistribute it and/or modify it under either the terms of
 * the AGPLv3 or PIAX binary code license. See the file COPYING
 * included in the PIAX package for more in detail.
 * 
 * $Id: TSDDiscoverable.java 1176 2015-05-23 05:56:40Z teranisi $
 */

package org.piax.gtrans.tsd;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;

import org.piax.common.Endpoint;
import org.piax.common.PeerId;
import org.piax.common.TransportId;
import org.piax.gtrans.Discoverable;
import org.piax.gtrans.DiscoveryListener;
import org.piax.gtrans.PeerInfo;

/**
 * 
 */
public class TSDDiscoverable implements Discoverable,
        TSDListener {

    public static long DEFAULT_EXPIRATION_TIME = 30 * 1000;
    
    /*
     * ServiceInfoを入れる箱。生成時刻の管理のため。
     */
    static class InfoBox {
        final T serv;
        final long lastObserved;

        InfoBox(T info) {
            this.serv = info;
            lastObserved = System.currentTimeMillis();
        }

        @Override
        public int hashCode() {
            return (serv == null) ? 0 : serv.hashCode();
        }

        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null || !(obj instanceof InfoBox))
                return false;
            @SuppressWarnings("unchecked")
            InfoBox _obj = (InfoBox) obj;
            return (serv == null) ? (_obj.serv == null) : serv.equals(_obj.serv);
        }
    }

    public enum Type {
        MULTICAST, BROADCAST
    }
    
    final PeerId peerId;
    private final TSD> tsd;
    final TransportId transId;
    protected final Set> listeners = Collections
            .newSetFromMap(new ConcurrentHashMap, Boolean>());
    
    protected final ConcurrentLinkedQueue>> availableInfoQueue = 
            new ConcurrentLinkedQueue>>();
    private long expireTime = DEFAULT_EXPIRATION_TIME;

    public TSDDiscoverable(PeerId peerId, Type type, TransportId transId)
            throws IOException {
        this.peerId = peerId;
        switch (type) {
        case MULTICAST:
            tsd = MulticastTSD.genTSD();
            break;
        case BROADCAST:
            tsd = BroadcastTSD.genTSD();
            break;
        default:
            tsd = null;
        }
        this.transId = transId;
        tsd.setDiscoveryListener(peerId, transId, this);
    }
    
    public void fin() {
        tsd.setDiscoveryListener(peerId, transId, null);
        tsd.unregisterAllServices(peerId, transId);
        tsd.fin();
        availableInfoQueue.clear();
        listeners.clear();
    }
    
    /**
     * 近傍から受け取ったサービスの有効期限(ms)をセットする。
     * この期限を越えて更新されなかったサービス情報は破棄される。
     * 
     * @param period サービスの有効期限(ms)
     */
    public void setExpireTime(long period) {
        expireTime = period;
    }

    public void register(PeerInfo info) {
        tsd.registerService(peerId, transId, info);
    }
    
    public void unregister(PeerInfo info) {
        tsd.unregisterService(peerId, transId, info);
    }

    /**
     * peerId, receiverの区分で、有効なサービスのリストを取得する。
     * 
     * @return the list of PeerInfo.
     */
    public List> getAvailablePeerInfos() {
        List> avail = new ArrayList>();
        for (InfoBox> infoBox : availableInfoQueue) {
            avail.add(infoBox.serv);
        }
        return avail;
    }
    
    public boolean addDiscoveryListener(DiscoveryListener listener) {
        return listeners.add(listener);
    }

    public boolean removeDiscoveryListener(DiscoveryListener listener) {
        return listeners.remove(listener);
    }

    @Override
    public void scheduleDiscovery(long delay, long period) {
        tsd.scheduleDiscovery(peerId, transId, delay, period);
    }

    @Override
    public void cancelDiscovery() {
        tsd.cancelDiscovery(peerId, transId);
    }

    @SuppressWarnings("unchecked")
    @Override
    public void onDiscovered(Object info) {
        InfoBox> infoBox = new InfoBox>((PeerInfo) info);
        boolean isNew = !availableInfoQueue.remove(infoBox);
        availableInfoQueue.offer(infoBox);
        for (DiscoveryListener listener : listeners)
            listener.onDiscovered((PeerInfo) info, isNew);
    }

    @Override
    public void onFadeoutCheck() {
        long past = System.currentTimeMillis() - expireTime;
        InfoBox> infoBox = availableInfoQueue.peek();
        if (infoBox == null) return;
        if (past < infoBox.lastObserved) return;
        availableInfoQueue.poll();
        for (DiscoveryListener listener : listeners)
            listener.onFadeout(infoBox.serv);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy