// ==========================================================================
// Author: Yee Hsu
// Date: 8/5/2008
// File: WebMiner.cpp
//
// Desc: WebMiner base architecture written using advanced C# topics
// and coding practices.
// ==========================================================================
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.IO;
using System.Threading;
using System.Reflection;
using CommonLib;
namespace WebMiner
{
public class MinerManager
{
private Queue<XmlConfStruct> qFunctionId = null;
// populates the queue and executes X number of threads on that queue
public void ProcessQueue()
{
Common.DataMineLog("-----------------------------------------------------------------");
Common.DataMineLog("WebMiner Started.");
this.qFunctionId = new Queue<XmlConfStruct>(Configuration.qFunctionId.ToArray());
Thread[] t = new Thread[Configuration.nNumThreads];
for (int i = 0; i < t.Length; i++)
{
t[i] = new Thread(this.ExecuteUpdates);
t[i].Name = "DataMineThread_" + i.ToString();
t[i].Start();
}
for (int i = 0; i < t.Length; i++)
{
t[i].Join(1000 * 60 * 30); // half hour wait for each queue thread
}
Common.DataMineLog("All Done. Waiting for next update...");
}
// each thread executes this function, but only one exclusive thread
// may enter the CS, create another thread within the CS and operate on it
private void ExecuteUpdates()
{
while (this.qFunctionId.Count > 0)
{
Thread.Sleep(100);
XmlConfStruct xmlc = new XmlConfStruct();
Thread tt = null;
////////////////////////////////// CRITICAL SECTION ///////////////////////////////////////
lock (this)
{
if (this.qFunctionId.Count > 0)
{
xmlc = this.qFunctionId.Dequeue();
tt = new Thread(this.ExecuteFunctionId);
tt.Name = Thread.CurrentThread.Name + "_" + xmlc.nFunctionId;
tt.Start(xmlc);
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////
if (tt != null)
tt.Join(1000 * 60 * 5); // five minute wait for each update id
}
}
// use reflections to actually call the underlying function
private void ExecuteFunctionId(object obj)
{
object[] objs = new object[1] { obj };
XmlConfStruct xmlconf = (XmlConfStruct)objs[0];
xmlconf.sMethodName = "UpdateMethod_" + xmlconf.nFunctionId.ToString();
xmlconf.sThreadName = Thread.CurrentThread.Name;
try
{
// Dynamic Runtime Execution with Reflections here
Type t = Assembly.GetExecutingAssembly().GetType("WebMiner.Vendors.Vendor");
t.InvokeMember(xmlconf.sMethodName, BindingFlags.InvokeMethod, null, Activator.CreateInstance(t), objs);
}
catch (Exception e)
{
Common.DataMineLog("Error In Method: " + xmlconf.sMethodName);
}
}
}
}