/*
* festivoice
*
* Copyright 2009 FURUHASHI Sadayuki, KASHIHARA Shuzo, SHIBATA Yasuharu
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.festivoice;
import java.lang.*;
import java.util.*;
import java.net.*;
import java.io.*;
public class StepTimeoutChannelManager extends Thread implements IChannelManager
{
private LinkedHashMap<String, ChannelInfo> channels;
private LinkedHashMap<String, ChannelInfo> channelsCache;
private int interval;
private int limit;
/**
* @param interval_millis タイムアウトカウントをインクリメントする間隔(単位はミリ秒)
* @param limit_step タイムアウトカウントの上限
*
*/
StepTimeoutChannelManager(int interval_millis, int limit_step)
{
channels = new LinkedHashMap<String, ChannelInfo>();
updateChannelsCache();
interval = interval_millis;
limit = limit_step;
}
public Iterable<? extends IChannelInfo> getChannels()
{
return channelsCache.values();
}
public IChannelInfo channelData(String channelName,
String userName, InetSocketAddress userAddress)
{
//System.out.println("channelName channel:"+channelName+" user:"+userName+" addr:"+userAddress);
ChannelInfo channel = channelsCache.get(channelName);
if(channel == null) {
synchronized(channels) {
channel = channels.get(channelName);
if(channel == null) {
channel = new ChannelInfo(channelName);
channels.put(channelName, channel);
updateChannelsCache();
ServerLogger.getInstance().channelCreated(channelName);
}
}
}
boolean updated = channel.userData(userName, userAddress);
if(updated) {
ServerLogger.getInstance().channelJoined(channelName, userName, userAddress);
}
return channel;
}
private void updateChannelsCache()
{
channelsCache = (LinkedHashMap)channels.clone();
}
public int getInterval() { return interval; }
public void setInterval(int millis) { interval = millis; }
public int getTimeoutLimit() { return limit; }
public void setTimeoutLimit(int steps) { limit = steps; }
public void run()
{
while(true) {
try {
Thread.sleep(interval);
} catch (InterruptedException ignore) { }
stepTimeout();
}
}
private void stepTimeout()
{
boolean updated = false;
synchronized(channels) {
Iterator<ChannelInfo> it = channels.values().iterator();
while(it.hasNext()) {
ChannelInfo channel = it.next();
Iterator<UserInfo> removed = channel.stepTimeout(getTimeoutLimit());
if(removed != null) {
updated = true;
String channelName = channel.getChannelName();
while(removed.hasNext()) {
UserInfo user = removed.next();
ServerLogger.getInstance().channelLeaved(channelName, user.getUserName(), user.getInetSocketAddress());
}
if(channel.isEmpty()) {
it.remove();
ServerLogger.getInstance().channelRemoved(channelName);
}
}
}
if(updated) {
updateChannelsCache();
}
}
}
}