Timer now activates to clean up outdated chat room list cache.

fix-message-formatting
Danny van Heumen 12 years ago
parent d5dc556f6e
commit 74809121fa

@ -40,6 +40,18 @@
*/
public class IrcStack
{
/**
* Clean-up delay. The clean up task clears any remaining chat room list
* cache. Since there's no pointing in timing it exactly, delay the clean up
* until after expiration.
*/
private static final long CACHE_CLEAN_UP_DELAY = 1000L;
/**
* Ratio of milliseconds to nanoseconds for conversions.
*/
private static final long RATIO_MILLISECONDS_TO_NANOSECONDS = 1000000L;
/**
* Expiration time for chat room list cache.
*/
@ -519,10 +531,11 @@ public List<String> getServerChatRoomList()
}
list = listSignal.getValue();
this.channellist.set(list);
// TODO Set a timer for past channel expiration delay and clean
// up outdated cached channel list. Because it won't be cleaned
// up if a user won't list server chat rooms again.
LOGGER.trace("Finished retrieving server chat room list.");
// Set timer to clean up the cache after use, since otherwise it
// could stay in memory for a long time.
createCleanUpJob(this.channellist);
}
else
{
@ -532,6 +545,24 @@ public List<String> getServerChatRoomList()
}
}
/**
* Create a clean up job that checks the container after the cache has
* expired. If the container is still populated, then remove it. This clean
* up makes sure that there are no references left to an otherwise useless
* list of channels.
*
* @param channellist the container carrying the list of channel names
*/
private static void createCleanUpJob(
final Container<List<String>> channellist)
{
final Timer cleanUpJob = new Timer();
final long timestamp = channellist.getTimestamp();
cleanUpJob.schedule(new ChannelListCacheCleanUpTask(channellist,
timestamp), CHAT_ROOM_LIST_CACHE_EXPIRATION
/ RATIO_MILLISECONDS_TO_NANOSECONDS + CACHE_CLEAN_UP_DELAY);
}
/**
* Join a particular chat room.
*
@ -2409,5 +2440,80 @@ public void set(final T instance)
this.instance = instance;
this.time = System.nanoTime();
}
/**
* Get the timestamp from when the instance was set.
*
* @return returns the timestamp
*/
public long getTimestamp()
{
return this.time;
}
}
/**
* Task for cleaning up old channel list caches.
*
* @author Danny van Heumen
*/
private static final class ChannelListCacheCleanUpTask
extends TimerTask
{
/**
* Expected timestamp on which the list cache was created. It is used as
* an indicator to see whether the cache has been refreshed in the mean
* time.
*/
private final long timestamp;
/**
* Container holding the channel list cache.
*/
private final Container<List<String>> container;
/**
* Construct new clean up job definition.
*
* @param listContainer container that holds the channel list cache
* @param timestamp expected timestamp of list cache creation
*/
private ChannelListCacheCleanUpTask(
final Container<List<String>> listContainer, final long timestamp)
{
if (listContainer == null)
{
throw new IllegalArgumentException(
"listContainer cannot be null");
}
this.container = listContainer;
this.timestamp = timestamp;
}
/**
* Remove the list reference from the container. But only if the
* timestamp matches. This makes sure that only one clean up job will
* clean up a list.
*/
@Override
public void run()
{
synchronized (this.container)
{
// Only clean up old cache if this is the dedicated task for it.
// If the timestamp has changed, another job is responsible for
// the clean up.
if (this.container.getTimestamp() != this.timestamp)
{
LOGGER.trace("Not cleaning up channel list cache. The "
+ "timestamp does not match.");
return;
}
this.container.set(null);
}
// We cannot clear the list itself, since the contents might still
// be in use by the UI, inside the immutable wrapper.
LOGGER.debug("Old channel list cache has been cleared.");
}
}
}

Loading…
Cancel
Save