--WorkUnit.cs
public class WorkUnit
{
public int Id { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public string FilePath { get; set; }
public int ExecutionTimeForWorkUnit { get; set; }
}
--WorkUnitManager.cs
public class WorkUnitManager {
private List<WorkUnit> _tasks;
public WorkUnitManager()
{
}
public IList<WorkUnit> GenerateWorkUnits()
{
var filePath = ConfigurationManager.AppSettings["feedLocation"];
var workUnits = new List<WorkUnit>();
for (var i = 0; i < 2; i++)
{
var workUnit = new WorkUnit { Id = i, Code = "workUnit" + i, FilePath = filePath + @"\ModelData" + i + ".csv", ExecutionTimeForWorkUnit = ( i==0) ? 1000 : 2000 * i};
workUnits.Add(workUnit);
}
return workUnits;
}
public bool Process(IList<WorkUnit> workUnits )
{
try
{
WaitHandle[] waitHandles = new WaitHandle[workUnits.Count];
for (var i = 0; i < workUnits.Count; i++)
waitHandles[i] = new AutoResetEvent(false) ;
int index = 0;
foreach (var unit in workUnits)
{
//starting the thread
int index1 = index;
WorkUnit unit1 = unit;
var thread = new Thread(parameter =>
{
ProcessWorkUnit(unit1);
((AutoResetEvent) waitHandles[index1]).Set();
});
thread.Start(unit);
index++;
}
WaitHandle.WaitAll(waitHandles);
return true;
}
catch(Exception exception)
{
return false;
}
}
private void ProcessWorkUnit(WorkUnit workUnit)
{
//Thread.Sleep(workUnit.ExecutionTimeForWorkUnit);
ModelManager modelManager = new ModelManager();
modelManager.ProcessModel(workUnit);
var threadId = Thread.CurrentThread.ManagedThreadId;
string logMessage = string.Format("Work Unit processed => {0} after {1} ms. on thread {2} ", workUnit.Code, workUnit.ExecutionTimeForWorkUnit, threadId);
ApplicationLogger.Instance.Log(typeof(WorkUnitManager), "------------------------------Start : Work Unit Information---------------------------", LogLevel.Info);
ApplicationLogger.Instance.Log(typeof(WorkUnitManager), logMessage, LogLevel.Info);
ApplicationLogger.Instance.Log(typeof(WorkUnitManager), "------------------------------End : Work Unit Information---------------------------", LogLevel.Info);
}
}
--
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string InvestmentCode { get; set; }
public double FxRate { get; set; }
public double DailyPnl { get; set; }
}
public class ModelValidation
{
public string Id { get; set; }
public int ModelId { get; set; }
public bool IsValid { get; set; }
public string Exception { get; set; }
}
--ModelTransaction.cs
public class ModelTransaction
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string InvestmentCode { get; set; }
public int FundId { get; set; }
public int InvestmentId { get; set; }
public double FxRate { get; set; }
public double DailyPnl { get; set; }
public double RepPnl { get; set; }
}
--
public enum LogLevel
{
Debug,
Info,
Warn,
Error
}
public sealed class ApplicationLogger
{
private static readonly ApplicationLogger _instance = new ApplicationLogger();
private static ILog logger;
static ApplicationLogger()
{
XmlConfigurator.Configure();
}
public static ApplicationLogger Instance
{
get { return _instance; }
}
public void Log(Type type, string message, LogLevel logLevel)
{
logger = LogManager.GetLogger(type);
switch (logLevel)
{
case LogLevel.Debug:
logger.Debug(message);
break;
case LogLevel.Warn:
logger.Warn(message);
break;
case LogLevel.Info:
logger.Info(message);
break;
case LogLevel.Error:
logger.Error(message);
break;
}
}
}
--ModelManager.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeSnippets.Shared;
using CodeSnippets.Shared.Domain;
namespace CodeSnippets.Domain
{
public class ModelManager : IModelManager
{
private IList<Model> _models;
private IList<ModelTransaction> _modelTransactions;
public ModelManager()
{
}
public bool ProcessModel(WorkUnit workUnit)
{
Stopwatch stopwatch = new Stopwatch();
// Begin timing
stopwatch.Start();
var modelRepository = new ModelRepository();
//Load Models
_models = modelRepository.Load(workUnit.FilePath);
stopwatch.Stop();
string logMessage = string.Format(" Operation : Load List<Model> : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
//Transform Models
stopwatch.Start();
_modelTransactions = modelRepository.Transform(_models);
stopwatch.Stop();
logMessage = string.Format(" Operation : Transform List<Model> : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
//Compute Models
stopwatch.Start();
modelRepository.Compute(_modelTransactions);
stopwatch.Stop();
logMessage = string.Format(" Operation : Compute RepPnL : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
//Enrich Models
stopwatch.Start();
modelRepository.Enrich(_modelTransactions);
stopwatch.Stop();
logMessage = string.Format(" Operation : Enrich Model Transactions : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
return true;
}
public IList<Model> GetModels()
{
return _models;
}
public IList<ModelTransaction> GetModelTransactions()
{
return _modelTransactions;
}
}
}
--ModelRepository.cs
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeSnippets.Shared;
using CodeSnippets.Shared.Domain;
namespace CodeSnippets.Domain
{
public class ModelRepository
{
private readonly List<ModelValidation> _modelValidations;
private readonly IRepository<Fund> _fundRepository;
private readonly IRepository<Investment> _investmentRepository;
public ModelRepository()
{
_fundRepository = new FundRepository();
_investmentRepository = new InvestmentRepository();
_modelValidations = new List<ModelValidation>();
}
public IList<Model> Load(string filePath)
{
var models = new List<Model>();
try
{
int rowIndex = 0;
using (var readFile = new StreamReader(filePath))
{
string line;
while ((line = readFile.ReadLine()) != null)
{
string[] row = line.Split(',');
if (rowIndex != 0)
{
var model = new Model
{
Name = row[0],
Description = row[1],
InvestmentCode = row[2],
FxRate = Convert.ToDouble(row[3]),
DailyPnl = Convert.ToDouble(row[4])
};
models.Add(model);
}
rowIndex++;
}
}
}
catch (Exception e)
{
string logMessage = "ModelRepository > Load " + "[" + e.StackTrace + "]";
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Error);
}
return models;
}
public IList<ModelTransaction> Transform(IList<Model> models)
{
return models.Select(model => new ModelTransaction
{
Name = model.Name,
Description = model.Description,
InvestmentCode = model.InvestmentCode,
FxRate = model.FxRate,
DailyPnl = model.DailyPnl
}).ToList();
}
public IList<ModelTransaction> Compute(IList<ModelTransaction> modelTransactions)
{
foreach (var modelTransaction in modelTransactions)
modelTransaction.RepPnl = modelTransaction.FxRate*modelTransaction.DailyPnl;
return modelTransactions;
}
public void Enrich(IList<ModelTransaction> modelTransactions)
{
List<Fund> funds = _fundRepository.GetAll().ToList();
List<Investment> investments = _investmentRepository.GetAll().ToList();
var enrichQuery = (from i in investments
join f in funds on i.FundId equals f.Id
select new { FundName = f.Name, FundID = f.Id, InvestmentCode = i.Code, InvestmentId = i.Id, InvestmentName = i.Name });
foreach (var modelTransaction in modelTransactions)
{
var fundQuery = enrichQuery.FirstOrDefault(e => e.InvestmentCode == modelTransaction.InvestmentCode);
modelTransaction.FundId = (fundQuery == null) ? -1 : fundQuery.FundID;
var investmentQuery = enrichQuery.FirstOrDefault(e => e.InvestmentCode == modelTransaction.InvestmentCode);
modelTransaction.InvestmentId = (investmentQuery == null) ? -1 : investmentQuery.InvestmentId;
}
}
public void Validate(IList<ModelTransaction> modelTransactions)
{
throw new NotImplementedException();
}
public void Persist(IList<ModelTransaction> modelTransactions)
{
throw new NotImplementedException();
}
}
}
public class WorkUnit
{
public int Id { get; set; }
public string Code { get; set; }
public string Description { get; set; }
public string FilePath { get; set; }
public int ExecutionTimeForWorkUnit { get; set; }
}
--WorkUnitManager.cs
public class WorkUnitManager {
private List<WorkUnit> _tasks;
public WorkUnitManager()
{
}
public IList<WorkUnit> GenerateWorkUnits()
{
var filePath = ConfigurationManager.AppSettings["feedLocation"];
var workUnits = new List<WorkUnit>();
for (var i = 0; i < 2; i++)
{
var workUnit = new WorkUnit { Id = i, Code = "workUnit" + i, FilePath = filePath + @"\ModelData" + i + ".csv", ExecutionTimeForWorkUnit = ( i==0) ? 1000 : 2000 * i};
workUnits.Add(workUnit);
}
return workUnits;
}
public bool Process(IList<WorkUnit> workUnits )
{
try
{
WaitHandle[] waitHandles = new WaitHandle[workUnits.Count];
for (var i = 0; i < workUnits.Count; i++)
waitHandles[i] = new AutoResetEvent(false) ;
int index = 0;
foreach (var unit in workUnits)
{
//starting the thread
int index1 = index;
WorkUnit unit1 = unit;
var thread = new Thread(parameter =>
{
ProcessWorkUnit(unit1);
((AutoResetEvent) waitHandles[index1]).Set();
});
thread.Start(unit);
index++;
}
WaitHandle.WaitAll(waitHandles);
return true;
}
catch(Exception exception)
{
return false;
}
}
private void ProcessWorkUnit(WorkUnit workUnit)
{
//Thread.Sleep(workUnit.ExecutionTimeForWorkUnit);
ModelManager modelManager = new ModelManager();
modelManager.ProcessModel(workUnit);
var threadId = Thread.CurrentThread.ManagedThreadId;
string logMessage = string.Format("Work Unit processed => {0} after {1} ms. on thread {2} ", workUnit.Code, workUnit.ExecutionTimeForWorkUnit, threadId);
ApplicationLogger.Instance.Log(typeof(WorkUnitManager), "------------------------------Start : Work Unit Information---------------------------", LogLevel.Info);
ApplicationLogger.Instance.Log(typeof(WorkUnitManager), logMessage, LogLevel.Info);
ApplicationLogger.Instance.Log(typeof(WorkUnitManager), "------------------------------End : Work Unit Information---------------------------", LogLevel.Info);
}
}
--
public class Model
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string InvestmentCode { get; set; }
public double FxRate { get; set; }
public double DailyPnl { get; set; }
}
public class ModelValidation
{
public string Id { get; set; }
public int ModelId { get; set; }
public bool IsValid { get; set; }
public string Exception { get; set; }
}
--ModelTransaction.cs
public class ModelTransaction
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public string InvestmentCode { get; set; }
public int FundId { get; set; }
public int InvestmentId { get; set; }
public double FxRate { get; set; }
public double DailyPnl { get; set; }
public double RepPnl { get; set; }
}
--
public enum LogLevel
{
Debug,
Info,
Warn,
Error
}
public sealed class ApplicationLogger
{
private static readonly ApplicationLogger _instance = new ApplicationLogger();
private static ILog logger;
static ApplicationLogger()
{
XmlConfigurator.Configure();
}
public static ApplicationLogger Instance
{
get { return _instance; }
}
public void Log(Type type, string message, LogLevel logLevel)
{
logger = LogManager.GetLogger(type);
switch (logLevel)
{
case LogLevel.Debug:
logger.Debug(message);
break;
case LogLevel.Warn:
logger.Warn(message);
break;
case LogLevel.Info:
logger.Info(message);
break;
case LogLevel.Error:
logger.Error(message);
break;
}
}
}
--ModelManager.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeSnippets.Shared;
using CodeSnippets.Shared.Domain;
namespace CodeSnippets.Domain
{
public class ModelManager : IModelManager
{
private IList<Model> _models;
private IList<ModelTransaction> _modelTransactions;
public ModelManager()
{
}
public bool ProcessModel(WorkUnit workUnit)
{
Stopwatch stopwatch = new Stopwatch();
// Begin timing
stopwatch.Start();
var modelRepository = new ModelRepository();
//Load Models
_models = modelRepository.Load(workUnit.FilePath);
stopwatch.Stop();
string logMessage = string.Format(" Operation : Load List<Model> : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
//Transform Models
stopwatch.Start();
_modelTransactions = modelRepository.Transform(_models);
stopwatch.Stop();
logMessage = string.Format(" Operation : Transform List<Model> : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
//Compute Models
stopwatch.Start();
modelRepository.Compute(_modelTransactions);
stopwatch.Stop();
logMessage = string.Format(" Operation : Compute RepPnL : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
//Enrich Models
stopwatch.Start();
modelRepository.Enrich(_modelTransactions);
stopwatch.Stop();
logMessage = string.Format(" Operation : Enrich Model Transactions : {0}, Processing Time : {1}", workUnit.FilePath, stopwatch.Elapsed.Milliseconds);
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Info);
stopwatch.Reset();
return true;
}
public IList<Model> GetModels()
{
return _models;
}
public IList<ModelTransaction> GetModelTransactions()
{
return _modelTransactions;
}
}
}
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CodeSnippets.Shared;
using CodeSnippets.Shared.Domain;
namespace CodeSnippets.Domain
{
public class ModelRepository
{
private readonly List<ModelValidation> _modelValidations;
private readonly IRepository<Fund> _fundRepository;
private readonly IRepository<Investment> _investmentRepository;
public ModelRepository()
{
_fundRepository = new FundRepository();
_investmentRepository = new InvestmentRepository();
_modelValidations = new List<ModelValidation>();
}
public IList<Model> Load(string filePath)
{
var models = new List<Model>();
try
{
int rowIndex = 0;
using (var readFile = new StreamReader(filePath))
{
string line;
while ((line = readFile.ReadLine()) != null)
{
string[] row = line.Split(',');
if (rowIndex != 0)
{
var model = new Model
{
Name = row[0],
Description = row[1],
InvestmentCode = row[2],
FxRate = Convert.ToDouble(row[3]),
DailyPnl = Convert.ToDouble(row[4])
};
models.Add(model);
}
rowIndex++;
}
}
}
catch (Exception e)
{
string logMessage = "ModelRepository > Load " + "[" + e.StackTrace + "]";
ApplicationLogger.Instance.Log(typeof(ModelRepository), logMessage, LogLevel.Error);
}
return models;
}
public IList<ModelTransaction> Transform(IList<Model> models)
{
return models.Select(model => new ModelTransaction
{
Name = model.Name,
Description = model.Description,
InvestmentCode = model.InvestmentCode,
FxRate = model.FxRate,
DailyPnl = model.DailyPnl
}).ToList();
}
public IList<ModelTransaction> Compute(IList<ModelTransaction> modelTransactions)
{
foreach (var modelTransaction in modelTransactions)
modelTransaction.RepPnl = modelTransaction.FxRate*modelTransaction.DailyPnl;
return modelTransactions;
}
public void Enrich(IList<ModelTransaction> modelTransactions)
{
List<Fund> funds = _fundRepository.GetAll().ToList();
List<Investment> investments = _investmentRepository.GetAll().ToList();
var enrichQuery = (from i in investments
join f in funds on i.FundId equals f.Id
select new { FundName = f.Name, FundID = f.Id, InvestmentCode = i.Code, InvestmentId = i.Id, InvestmentName = i.Name });
foreach (var modelTransaction in modelTransactions)
{
var fundQuery = enrichQuery.FirstOrDefault(e => e.InvestmentCode == modelTransaction.InvestmentCode);
modelTransaction.FundId = (fundQuery == null) ? -1 : fundQuery.FundID;
var investmentQuery = enrichQuery.FirstOrDefault(e => e.InvestmentCode == modelTransaction.InvestmentCode);
modelTransaction.InvestmentId = (investmentQuery == null) ? -1 : investmentQuery.InvestmentId;
}
}
public void Validate(IList<ModelTransaction> modelTransactions)
{
throw new NotImplementedException();
}
public void Persist(IList<ModelTransaction> modelTransactions)
{
throw new NotImplementedException();
}
}
}
--
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<appSettings>
<add key="feedLocation" value="C:\Data\Professional\TechnologySkills\Software Engg Principles\SourceCode\MultiThreading\ThreadPool\QueueWorkUserItem\Feeds" />
</appSettings>
<log4net>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="C:\Data\Professional\TechnologySkills\Software Engg Principles\SourceCode\MultiThreading\ThreadPool\QueueWorkUserItem\Logs\MDT.UnitTests.log" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern"
value="%-5p%d{yyyy-MM-dd hh:mm:ss} – %m%n" />
<conversionPattern value="%date %logger >> %message%newline" />
</layout>
</appender>
<root>
<level value="ALL" />
<appender-ref ref="LogFileAppender" />
</root>
</log4net>
</configuration>
--InvestmentRepository
public IEnumerable<Investment> GetAll()
{
return new List<Investment>
{
new Investment(){ Name = "MS Boston", Code = "MSB", Id=1, FundId = 1},
new Investment(){ Name = "MS Woodbarn", Code = "MSW", Id=2, FundId = 1 },
new Investment(){ Name = "MS Cash Eq", Id=3, Code = "MCE", FundId = 2 },
new Investment(){ Name = "MS Cash Eq1", Id=4, Code = "MCE1", FundId = 2 },
new Investment(){ Name = "MS Cash Eq2", Id=5, Code = "MCE2", FundId = 2 },
new Investment(){ Name = "MS Comm", Id=6, Code = "MSCOM", FundId = 3 }
};
}
--FundRepositoy
public IEnumerable<Fund> GetAll()
{
return new List<Fund>
{
new Fund(){ Name = "MS REF 1", Code = "MSR1", Id=1 },
new Fund(){ Name = "MS REF 2", Code = "MSR2", Id=2 },
new Fund(){ Name = "MS REF 3", Code = "MSR#", Id=3 }
};
}
---Feeds
Name,Description,InvestmentCode, FXRate,DailyPnl
MCE2 test,MCE2 test DESCR,MCE2,1.0,4575
MSCOM test,MSCOM test DESCR,MSCOM,2,357
MCE test,MCE test DESCR,MCE,.6,34
MCE1 test,MCE1 test DESCR,MCE1, 2.5, 1000
MSE test,MSE test DESCR,MSE,3,489
TSE test,TSE test DESCR,TSE,4,900
MSB Test1,MSB Test1 DESCR,MSB, 2.4,12
MSW test,MSW test DESCR,MSW, 3.4,200
MCE test,MCE test DESCR,MCE, 5.6, 34
MCE1 test,MCE1 test DESCR,MCE1, 3.2,1000
WorkUnitManager workUnitManager = new WorkUnitManager();
IList<WorkUnit> workUnits = workUnitManager.GenerateWorkUnits();
foreach (var workUnit in workUnits)
{
Console.WriteLine(" Work Unit {0} ", workUnit.Code);
}
workUnitManager.Process(workUnits);
--InvestmentRepository
public IEnumerable<Investment> GetAll()
{
return new List<Investment>
{
new Investment(){ Name = "MS Boston", Code = "MSB", Id=1, FundId = 1},
new Investment(){ Name = "MS Woodbarn", Code = "MSW", Id=2, FundId = 1 },
new Investment(){ Name = "MS Cash Eq", Id=3, Code = "MCE", FundId = 2 },
new Investment(){ Name = "MS Cash Eq1", Id=4, Code = "MCE1", FundId = 2 },
new Investment(){ Name = "MS Cash Eq2", Id=5, Code = "MCE2", FundId = 2 },
new Investment(){ Name = "MS Comm", Id=6, Code = "MSCOM", FundId = 3 }
};
}
--FundRepositoy
public IEnumerable<Fund> GetAll()
{
return new List<Fund>
{
new Fund(){ Name = "MS REF 1", Code = "MSR1", Id=1 },
new Fund(){ Name = "MS REF 2", Code = "MSR2", Id=2 },
new Fund(){ Name = "MS REF 3", Code = "MSR#", Id=3 }
};
}
---Feeds
Name,Description,InvestmentCode, FXRate,DailyPnl
MCE2 test,MCE2 test DESCR,MCE2,1.0,4575
MSCOM test,MSCOM test DESCR,MSCOM,2,357
MCE test,MCE test DESCR,MCE,.6,34
MCE1 test,MCE1 test DESCR,MCE1, 2.5, 1000
MSE test,MSE test DESCR,MSE,3,489
TSE test,TSE test DESCR,TSE,4,900
MSB Test1,MSB Test1 DESCR,MSB, 2.4,12
MSW test,MSW test DESCR,MSW, 3.4,200
MCE test,MCE test DESCR,MCE, 5.6, 34
MCE1 test,MCE1 test DESCR,MCE1, 3.2,1000
WorkUnitManager workUnitManager = new WorkUnitManager();
IList<WorkUnit> workUnits = workUnitManager.GenerateWorkUnits();
foreach (var workUnit in workUnits)
{
Console.WriteLine(" Work Unit {0} ", workUnit.Code);
}
workUnitManager.Process(workUnits);
No comments:
Post a Comment