org.piax.gtrans.tsd.TSDDiscoverable Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of piax-compat Show documentation
Show all versions of piax-compat Show documentation
A backward compatibility package for PIAX
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);
}
}