flex.messaging.FlexSessionManager Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 flex.messaging;
import flex.management.ManageableComponent;
import flex.messaging.log.LogCategories;
import java.util.concurrent.ConcurrentHashMap;
/**
* Manages FlexSession instances for a MessageBroker.
*/
public class FlexSessionManager extends ManageableComponent
{
public static final String TYPE = "FlexSessionManager";
private static final long MILLIS_IN_HOUR = 3600000;
//--------------------------------------------------------------------------
//
// Constructors
//
//--------------------------------------------------------------------------
/**
*
* Constructs a FlexSessionManager for the passed MessageBroker.
*
* @param broker The root MessageBroker using this FlexSessionManager.
*/
public FlexSessionManager(MessageBroker broker)
{
this(false, broker);
}
/**
*
* Constructs a FlexSessionManager for the passed MessageBroker and optionally enables management.
*
* @param enableManagement true
if the FlexSessionManager
* is manageable; otherwise false
.
* @param broker the message broker
*/
public FlexSessionManager(boolean enableManagement, MessageBroker broker)
{
super(enableManagement);
super.setId(TYPE);
this.broker = broker;
this.setParent(broker);
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* Instance-level lock.
*/
private final Object lock = new Object();
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// logCategory
//----------------------------------
/**
* Returns the log category for this component.
*
* @return The log category for this component.
*/
@Override
protected String getLogCategory()
{
return LogCategories.ENDPOINT_FLEXSESSION;
}
//----------------------------------
// flexSessionCount
//----------------------------------
private int flexSessionCount;
/**
* Returns the total count of active FlexSessions.
*
* @return The total count of active FlexSessions.
*/
public int getFlexSessionCount()
{
synchronized (lock)
{
return flexSessionCount;
}
}
//----------------------------------
// flexSessionProviders
//----------------------------------
private final ConcurrentHashMap, AbstractFlexSessionProvider> providers = new ConcurrentHashMap, AbstractFlexSessionProvider>();
/**
* Returns the registered FlexSessionProvider implementation for the specified FlexSession type.
*
* @param sessionClass The specific FlexSession type to get a provider for.
* @return The registered FlexSessionProvider or null
if no provider is registered.
*/
public AbstractFlexSessionProvider getFlexSessionProvider(Class extends FlexSession> sessionClass)
{
return providers.get(sessionClass);
}
/**
* Registers a FlexSessionProvider implementation for a specified FlexSession type.
*
* @param sessionClass The specific FlexSession type to register a provider for.
* @param provider The corresponding FlexSessionProvider to register.
* @return The previously registered provider, or null
if no provider was registered for this session type.
*/
public AbstractFlexSessionProvider registerFlexSessionProvider(Class extends FlexSession> sessionClass, AbstractFlexSessionProvider provider)
{
provider.setFlexSessionManager(this);
AbstractFlexSessionProvider previousProvider = providers.putIfAbsent(sessionClass, provider);
if (previousProvider != null)
{
previousProvider.stop();
previousProvider.setFlexSessionManager(null);
}
if (isStarted())
provider.start();
return previousProvider;
}
/**
* Unregisters a FlexSessionProvider implementation for a specified FlexSession type.
*
* @param sessionClass The specific FlexSession type to unregister a provider for.
*/
public void unregisterFlexSessionProvider(Class extends FlexSession> sessionClass)
{
AbstractFlexSessionProvider provider = providers.remove(sessionClass);
if (provider != null)
{
provider.stop();
provider.setFlexSessionManager(null);
}
}
//----------------------------------
// flexSessions
//----------------------------------
/**
* Registers a new FlexSession with the FlexSessionManager.
*
* @param session The new FlexSession.
*/
public void registerFlexSession(FlexSession session)
{
synchronized (lock)
{
++flexSessionCount;
resetMaxFlexSessionsInCurrentHour(flexSessionCount);
}
}
/**
* Unregisters an invalidated FlexSession from the FlexSessionManager.
*
* @param session The invalidated FlexSession.
*/
public void unregisterFlexSession(FlexSession session)
{
synchronized (lock)
{
--flexSessionCount;
resetMaxFlexSessionsInCurrentHour(flexSessionCount);
}
}
//----------------------------------
// maxFlexSessionsInCurrentHour
//----------------------------------
private int maxSessionCountInCurrentHour;
private long currentHourStartTimestamp = System.currentTimeMillis();
public int getMaxFlexSessionsInCurrentHour()
{
synchronized (lock)
{
// Make sure we report the correct value if the system has been idle across an hour transition.
resetMaxFlexSessionsInCurrentHour(flexSessionCount);
return maxSessionCountInCurrentHour;
}
}
/* Must be called within a synchronized block. */
private void resetMaxFlexSessionsInCurrentHour(int currentCount)
{
long offset = (System.currentTimeMillis() - currentHourStartTimestamp) / MILLIS_IN_HOUR;
if (offset > 0) // Shift to the current hour and reset to the current session count.
{
currentHourStartTimestamp += (MILLIS_IN_HOUR * offset);
maxSessionCountInCurrentHour = currentCount;
}
else if (maxSessionCountInCurrentHour < currentCount)
{
maxSessionCountInCurrentHour = currentCount;
}
}
//----------------------------------
// messageBroker
//----------------------------------
private final MessageBroker broker;
/**
* Returns the MessageBroker instance that owns this FlexSessionManager.
*
* @return The parent MessageBroker instance.
*/
public MessageBroker getMessageBroker()
{
return broker;
}
//--------------------------------------------------------------------------
//
// Public Methods
//
//--------------------------------------------------------------------------
/**
* Starts the FlexSessionManager.
* Any registered FlexSessions providers are also started.
*/
@Override
public void start()
{
if (isStarted())
return;
for (AbstractFlexSessionProvider provider : providers.values())
{
if (!provider.isStarted())
provider.start();
}
super.start();
}
/**
* Stops the FlexSessionManager.
* Any registered FlexSession providers are stopped and unregistered.
*/
@Override
public void stop()
{
if (!isStarted())
return;
super.stop();
for (Class extends FlexSession> sessionClass : providers.keySet())
{
unregisterFlexSessionProvider(sessionClass);
}
providers.clear();
}
}