183 lines
4.0 KiB
C#
183 lines
4.0 KiB
C#
using System;
|
|
using System.Threading;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Security.Permissions;
|
|
using sharp.extensions;
|
|
using sharp.json;
|
|
using System.IO;
|
|
namespace sharp.trading.services
|
|
{
|
|
public class ServiceManager
|
|
{
|
|
public static ServiceManager Default { get; private set; } = new ServiceManager();
|
|
|
|
public static void ReplaceDefault(ServiceManager newDefault){
|
|
if (Default != null){
|
|
Default.Shutdown();
|
|
}
|
|
Default = newDefault;
|
|
}
|
|
|
|
Thread serviceThread;
|
|
bool shutdown = false;
|
|
|
|
List<ScheduledService> scheduledServices = new List<ScheduledService>();
|
|
|
|
public ServiceManager()
|
|
{
|
|
serviceThread = new Thread(_scheduler);
|
|
serviceThread.Start();
|
|
|
|
Load();
|
|
}
|
|
|
|
public void Shutdown(){
|
|
lock (this){
|
|
shutdown = true;
|
|
}
|
|
|
|
while (serviceThread.IsAlive){
|
|
Thread.Sleep(250);
|
|
}
|
|
|
|
foreach (ScheduledService service in scheduledServices){
|
|
while (service.IsRunning){
|
|
Thread.Sleep(250);
|
|
}
|
|
service.TradingService.Shutdown();
|
|
}
|
|
|
|
Save();
|
|
}
|
|
|
|
private void Load(){
|
|
if (File.Exists(Path.Combine(TradingEnvironment.DataDirectory, "services.json"))){
|
|
JSON json = JSON.ReadFrom(Path.Combine(TradingEnvironment.DataDirectory, "services.json"));
|
|
ConstructableObject[] cos = json.To<ConstructableObject[]>();
|
|
foreach (ConstructableObject co in cos){
|
|
ITradingService its = (ITradingService)co.Construct();
|
|
Schedule(its,true);
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
public void Save(){
|
|
List<ConstructableObject> col = new List<ConstructableObject>();
|
|
lock (this){
|
|
foreach (ScheduledService sservice in scheduledServices){
|
|
ConstructableObject co = new ConstructableObject(sservice.TradingService);
|
|
col.Add(co);
|
|
}
|
|
}
|
|
|
|
JSON json = JSONConverter.From(col.ToArray());
|
|
json.WriteTo(Path.Combine(TradingEnvironment.DataDirectory,"services.json"),true);
|
|
}
|
|
|
|
|
|
public void Schedule(ITradingService service, bool RunImmediate = false){
|
|
lock (this){
|
|
ScheduledService sservice = new ScheduledService(service);
|
|
if (RunImmediate){
|
|
sservice.ScheduledRun = DateTime.UtcNow.Ticks;
|
|
}
|
|
scheduledServices.Add(sservice);
|
|
}
|
|
}
|
|
public void Unschedule(ITradingService service){
|
|
lock (this){
|
|
foreach (ScheduledService sserv in scheduledServices.ToArray()){
|
|
if (sserv.TradingService == service){
|
|
scheduledServices.Remove(sserv);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void _scheduler(){
|
|
while (true){
|
|
try {
|
|
Thread.Sleep(1000);
|
|
} catch (Exception e){
|
|
}
|
|
|
|
if (shutdown){
|
|
break;
|
|
}
|
|
|
|
lock(this){
|
|
|
|
foreach (ScheduledService sservice in scheduledServices){
|
|
if (sservice.HasElapsed){
|
|
//ThreadPool.QueueUserWorkItem((state) => sservice.Run());
|
|
sservice.Run();
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
|
|
class ScheduledService {
|
|
public Int64 ScheduledRun { get; set; }
|
|
public Int64 ScheduledIntervall { get; private set; }
|
|
|
|
public ITradingService TradingService { get; private set; }
|
|
|
|
bool isRunning;
|
|
public bool IsRunning {
|
|
get { lock (this) { return isRunning; } }
|
|
private set { lock(this) { this.isRunning = value; } }
|
|
}
|
|
|
|
public ScheduledService(ITradingService tradingService){
|
|
this.TradingService = tradingService;
|
|
this.ScheduledRun = DateTime.UtcNow.Ticks + (tradingService.SchedulingIntervall() * 10000000);
|
|
}
|
|
|
|
public bool HasElapsed {
|
|
get
|
|
{
|
|
return ScheduledRun <= DateTime.UtcNow.Ticks;
|
|
}
|
|
}
|
|
|
|
|
|
public void Run(){
|
|
lock(this){
|
|
|
|
if (!IsRunning){
|
|
IsRunning = true;
|
|
} else {
|
|
Console.WriteLine("Service already running, re-scheduling...");
|
|
ScheduledRun += ScheduledIntervall;
|
|
return;
|
|
//throw new Exception("Tried to run ScheduledService while already running");
|
|
}
|
|
|
|
ScheduledIntervall = TradingService.SchedulingIntervall() * 10000000;
|
|
ScheduledRun += ScheduledIntervall;
|
|
}
|
|
|
|
try {
|
|
|
|
TradingService.RunService();
|
|
|
|
} catch (Exception e){
|
|
Console.WriteLine("ScheduledService threw exception: {0}",e.ToString());
|
|
}
|
|
|
|
IsRunning = false;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|