Alachisoft.NCache.Common.Threading.AsyncProcessor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nc-common Show documentation
Show all versions of nc-common Show documentation
Internal package of Alachisoft.
package Alachisoft.NCache.Common.Threading;
import Alachisoft.NCache.Common.Logger.ILogger;
import com.alachisoft.ncache.runtime.exceptions.CacheException;
import com.alachisoft.ncache.runtime.exceptions.LockingException;
import com.alachisoft.ncache.runtime.exceptions.OperationFailedException;
/**
* A class that helps doing things that can be done asynchronously
*/
public class AsyncProcessor implements Runnable {
Boolean _isShutdown = false;
/**
* The worker thread.
*/
//+Sami:20140203 [Commented]
//private Thread _worker;
//-Sami:20140203 [Commented]
Object _shutdownMutex = new Object();
/**
* The queue of events.
*/
private java.util.LinkedList _eventsHi, _eventsLow;
//private NewTrace nTrace = null;
// string _loggerName;
private ILogger NCacheLog;
//+Sami:20140203
private boolean _started;
private int _numProcessingThreads = 1;
//-Sami:20140203
private Thread[] _workerThreads;
/**
* Constructor
*
* @param NCacheLog Logger
*/
public AsyncProcessor(ILogger NCacheLog) {
this();
this.NCacheLog = NCacheLog;
//this.nTrace = nTrace;
//_worker = null;
//_eventsHi = new Queue(256);
//_eventsLow = new Queue(256);
}
public AsyncProcessor() {
this(1);
//+Sami:20140203 [Commencted]
// _worker = null;
// _eventsHi = new java.util.LinkedList();
// _eventsLow = new java.util.LinkedList();
//-Sami:20140203
}
//+Sami:20140203
public AsyncProcessor(int numProcessingThread) {
if (numProcessingThread < 1)
numProcessingThread = 1;
_workerThreads = null;
_numProcessingThreads = numProcessingThread;
_eventsHi = new java.util.LinkedList();
_eventsLow = new java.util.LinkedList();
}
public final void WindUpTask() {
NCacheLog.CriticalInfo("AsyncProcessor", "WindUp Task Started.");
if (_eventsHi != null) {
NCacheLog.CriticalInfo("AsyncProcessor", "Async operation(s) Queue Count: " + _eventsHi.size());
}
_isShutdown = true;
synchronized (this) {
Alachisoft.NCache.Common.Threading.Monitor.pulse(this);
}
NCacheLog.CriticalInfo("AsyncProcessor", "WindUp Task Ended.");
}
//-Sami:20140203
public final void WaitForShutDown(long interval) {
NCacheLog.CriticalInfo("AsyncProcessor", "Waiting for async process queue shutdown task completion.");
if (interval > 0) {
boolean waitlock = false;
synchronized (_shutdownMutex) {
if (_eventsHi.size() > 0) {
try {
waitlock = Alachisoft.NCache.Common.Threading.Monitor.wait(_shutdownMutex, (int) ((interval - 1) * 1000));
} catch (Exception ex) {
NCacheLog.Error("AsyncProcessor", "Asyncronous operations has intruppted. " + ex.getMessage());
}
}
}
if (!waitlock) {
if (_eventsHi.size() > 0) {
NCacheLog.CriticalInfo("AsyncProcessor", "Remaining Async operations in queue: " + _eventsHi.size());
}
}
}
NCacheLog.CriticalInfo("AsyncProcessor", "Shutdown task completed.");
}
/**
* Add a low priority event to the event queue
*
* @param evnt event
*/
public final void Enqueue(IAsyncTask evnt) {
synchronized (this) {
_eventsHi.offer(evnt);
//Basit: Monitor.Pulse(this) changed to this.notify()
//Monitor.Pulse(this);
Alachisoft.NCache.Common.Threading.Monitor.pulse(this);// this.notifyAll();
}
}
/**
* Add a low priority event to the event queue
*
* @param evnt event
*/
public final void EnqueueLowPriority(IAsyncTask evnt) {
synchronized (this) {
_eventsLow.offer(evnt);
//Monitor.Pulse(this);
Alachisoft.NCache.Common.Threading.Monitor.pulse(this);//this.notify();
}
}
/**
* Start processing
*/
public final void Start() {
//+Sami:20140203
try {
synchronized (this) {
if (!_started) {
_workerThreads = new Thread[_numProcessingThreads];
_started = true;
for (int i = 0; i < _workerThreads.length; i++) {
Thread tThread = new Thread(this);
tThread.setDaemon(true);
tThread.setName("AsyncProcessor");
tThread.start();
_workerThreads[i] = tThread;
}
//+Sami:20140203 [Commented]
// if (_workerThreads == null) {
// _workerThreads = new Thread(this);
// _workerThreads.setDaemon(true);
// _workerThreads.setName("AsyncProcessor");
// _workerThreads.start();
//-Sami:20140203 [Commented]
}
}
} catch (Exception ex) {
if (NCacheLog != null) {
NCacheLog.Error("AsyncProcessor.Start)_", ex.getMessage());
}
}
//-Sami:20140203
//+Sami:20140203
// synchronized (this)
// {
// if (_worker == null)
// {
// _worker = new Thread(this);
// _worker.setDaemon(true);
// _worker.setName("AsyncProcessor");
// _worker.start();
// }
// }
//-Sami:20140203
}
/**
* Stop processing.
*/
public final void Stop() {
synchronized (this) {
//+Sami:20140203
if(_workerThreads !=null) {
for (Thread tThread : _workerThreads) {
if (tThread != null && tThread.isAlive()) {
if (NCacheLog != null) {
NCacheLog.Flush();
}
//Basit: Remove stop with interrupt
tThread.interrupt();
tThread = null;
}
}
}
//-Sami:20140203
//+Sami:20140203 [Commented]
// if (_workerThreads != null && _workerThreads.isAlive())
// {
// if (NCacheLog != null)
// {
// NCacheLog.Flush();
// }
// //Basit: Remove stop with interrupt
// _workerThreads.stop();
// _workerThreads = null;
// }
//-Sami:20140203 [Commented]
}
}
/**
* Thread function, keeps running.
*/
@Override
public void run() {
while (_workerThreads != null && !Thread.currentThread().isInterrupted()) {
IAsyncTask evnt = null;
try {
synchronized (this) {
if ((_eventsHi.size() < 1) && (_eventsLow.size() < 1) && !_isShutdown) {
//Monitor.Wait(this);
Alachisoft.NCache.Common.Threading.Monitor.wait(this);//this.wait();
}
if ((_eventsHi.size() < 1) && _isShutdown) {
synchronized (_shutdownMutex) {
Alachisoft.NCache.Common.Threading.Monitor.pulse(_shutdownMutex);
break;
}
}
if (_eventsHi.size() > 0) {
evnt = (IAsyncTask) _eventsHi.poll();
} else if (_eventsLow.size() > 0) {
evnt = (IAsyncTask) _eventsLow.poll();
}
}
if (evnt == null && _eventsHi.size() < 1 && _isShutdown) {
synchronized (_shutdownMutex) {
Alachisoft.NCache.Common.Threading.Monitor.pulse(_shutdownMutex);
break;
}
}
if (evnt == null) {
continue;
}
evnt.Process();
} catch (NullPointerException e) {
//Basit: No logging or anything else done ?
} catch (InterruptedException e) {
break;
} catch (Exception e) {
String exceptionString = e.toString();
if (!exceptionString.equals("ChannelNotConnectedException") && !exceptionString.equals("ChannelClosedException")) {
if (NCacheLog != null) {
NCacheLog.Error("AsyncProcessor.Run()", exceptionString);
}
}
}
}
}
/**
* Interface to be implemented by all async events.
*/
public interface IAsyncTask {
/**
* Process itself.
*
* @throws Alachisoft.NCache.Cluster.ChannelClosedException
*/
void Process() throws OperationFailedException, java.io.IOException, CacheException, LockingException;
}
}
/*
using System;
using System.Collections;
using System.Threading;
namespace Alachisoft.NCache.Util
{
///
/// A class that helps doing things that can be done asynchronously
///
#if DEBUG
public class AsyncProcessor
#else
internal class AsyncProcessor
#endif
{
///
/// Interface to be implemented by all async events.
///
public interface IAsyncTask
{
/// Process itself.
void Process();
}
/// The worker thread.
private Thread _worker = null;
/// The queue of events.
private Queue _events = null;
///
/// Constructor
///
public AsyncProcessor()
{
_events = new Queue(256);
}
///
/// Add a low priority event to the event queue
///
/// event
public void Enqueue(IAsyncTask evnt)
{
lock(_events)
{
_events.Enqueue(evnt);
Monitor.Pulse(_events);
}
}
///
/// Start processing
///
public void Start()
{
lock(this)
{
if(_worker == null)
{
_worker = new Thread(new ThreadStart(Run));
_worker.IsBackground = true;
_worker.Name = "AsyncProcessor";
_worker.Start();
}
}
}
///
/// Stop processing.
///
public void Stop()
{
lock(this)
{
if(_worker != null && _worker.IsAlive)
{
_worker.Abort();
_worker = null;
}
}
}
///
/// Thread function, keeps running.
///
private void Run()
{
while(_worker != null)
{
IAsyncTask evnt = null;
try
{
lock(_events)
{
if(_events.Count < 1)
Monitor.Wait(_events);
evnt = (IAsyncTask) _events.Dequeue();
}
if(evnt == null) continue;
evnt.Process();
}
catch(ThreadAbortException)
{
break;
}
catch(Exception e)
{
Trace.error("AsyncProcessor.Run()", e.ToString());
}
}
}
}
}
* */