/*
* Copyright 2003-2004 The Apache Software Foundation
* 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.
*/
namespace Apache.Avalon.Composition.Model.Default
{
using System;
using System.Threading;
using Apache.Avalon.Framework;
/// Runnable deployment thread that handles the commissioning of an
/// arbitary number of commissionable instances. The commissioner maintains a
/// list of commissioning requests which are queued on a first come first
/// serve basis.
///
///
/// Avalon Development Team
///
/// $Revision: 1.2 $ $Date: 2004/03/07 22:06:40 $
///
///
///
class Commissioner
{
private void InitBlock()
{
m_queue = new SimpleFIFO();
}
//------------------------------------------------------------
// static
//------------------------------------------------------------
private static int m_ThreadCounter = 0;
//------------------------------------------------------------
// immutable state
//------------------------------------------------------------
private ILogger m_logger;
private SimpleFIFO m_queue;
private System.String m_message;
private bool m_flag;
//------------------------------------------------------------
// mutable static
//------------------------------------------------------------
private Thread m_thread;
//------------------------------------------------------------
// constructor
//------------------------------------------------------------
internal Commissioner(ILogger logger, bool flag)
{
InitBlock();
m_logger = logger;
m_ThreadCounter++;
System.String name = "Commissioner [" + m_ThreadCounter + "]";
m_flag = flag;
if (flag)
{
m_message = "commissioning";
}
else
{
m_message = "decommissioning";
}
// m_thread = new Thread( new System.Threading.ThreadStart(Run) );
// m_thread.Start();
}
//------------------------------------------------------------
// implementation
//------------------------------------------------------------
/// Commissions the given Commissonable, and allows a maximum time
/// for commissioning/decommissioning to complete.
///
///
/// the deployment model
///
/// @throws CommissioningException if the deployment was not
/// completed within the timeout deadline and interuption
/// of the deployment was successful
/// @throws FatalCommissioningException if the deployment was not
/// completed within the timeout deadline and interuption
/// of the deployment was not successful
/// @throws Exception any Exception or Error thrown within the
/// deployment of the component is forwarded to the caller.
/// @throws InvocationTargetException if the deployment throws a
/// Throwable subclass that is NOT of type Exception or Error.
///
///
public void Commission(IDeploymentModel model)
{
if (null == model)
{
throw new System.ArgumentNullException("model");
}
//if (null != m_thread)
{
if (m_logger.IsDebugEnabled)
{
if (model is IContainmentModel)
{
m_logger.Debug(m_message + " container [" + model.Name + "]");
}
else
{
m_logger.Debug(m_message + " component [" + model.Name + "]");
}
}
CommissionRequest request = new CommissionRequest(model, m_thread);
m_queue.Put(request);
/*long t = request.waitForCompletion();
if (m_logger.IsDebugEnabled)
{
m_logger.Debug(m_message + " of [" + model.Name + "] completed in " + t + " milliseconds");
}*/
}
/*
else
{
System.String warning = "Ignoring " + m_message + " request on a disposed commissioner.";
m_logger.Warn(warning);
}*/
}
/// Disposal of the Commissioner.
/// The Commissioner allocates a deployment thread, which needs to be
/// disposed of before releasing the Commissioner reference.
///
///
public void Dispose()
{
if (m_logger.IsDebugEnabled)
{
m_logger.Debug("disposal");
}
if (null != m_thread)
{
m_thread.Interrupt();
}
}
public void Run()
{
if (m_logger.IsDebugEnabled)
{
m_logger.Debug(m_message + " thread started");
}
try
{
while (true)
{
CommissionRequest request = (CommissionRequest) m_queue.Get();
if (request == null)
{
break;
}
IDeploymentModel model = request.DeploymentModel;
try
{
if (m_flag)
{
model.Commission();
}
else
{
model.Decommission();
}
request.done();
}
catch (System.Threading.ThreadInterruptedException )
{
request.interrupted();
}
catch (System.Exception e)
{
request.exception(e);
}
}
}
catch (System.Threading.ThreadInterruptedException)
{
// ignore, part of dispose;
}
m_thread = null;
}
}
}