//==============================================================
// Copyright (C) 2019 Inc. All rights reserved.
//
//==============================================================
// Create by 种道洋 at 2019/12/27 18:45:02.
// Version 1.0
// 种道洋
//==============================================================
using Cdy.Tag.Driver;
using DBRuntime;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Cdy.Tag
{
///
///
///
public class Runner
{
#region ... Variables ...
public static string CurrentDatabase = "";
public static string CurrentDatabaseVersion = "";
public static string CurrentDatabaseLastUpdateTime = "";
///
///
///
public static Runner RunInstance = new Runner();
///
///
///
private string mDatabaseName = "local";
private Database mDatabase;
private RealDatabase mRealDatabase;
private HisDatabase mHisDatabase;
private RealEnginer realEnginer;
private HisEnginer2 hisEnginer;
private CompressEnginer2 compressEnginer;
private SeriseEnginer2 seriseEnginer;
private DataFileManager mHisFileManager;
private QuerySerivce querySerivce;
private SecurityRunner mSecurityRunner;
private bool mIsStarted = false;
#endregion ...Variables...
#region ... Events ...
#endregion ...Events...
#region ... Constructor...
///
///
///
static Runner()
{
RDDCManager.Manager.StartTime = DateTime.Now;
//注册日志
ServiceLocator.Locator.Registor(new ConsoleLogger());
//注册线性转换器
ValueConvertManager.manager.Registor(new LinerConvert());
}
///
///
///
public Runner()
{
RDDCManager.Manager.SwitchWorkStateAction = new Func((state) =>
{
if(state == WorkState.Primary)
{
return SwitchToPrimary();
}
else
{
return SwitchToStandby();
}
});
}
#endregion ...Constructor...
#region ... Properties ...
///
///
///
public WorkState State
{
get
{
return RDDCManager.Manager.CurrentState;
}
}
///
/// 数据库存访路径
///
public string DatabasePath { get; set; }
///
///
///
public Database Database { get { return mDatabase; } }
///
///
///
public bool IsStarted
{
get
{
return mIsStarted;
}
}
#endregion ...Properties...
#region ... Methods ...
///
///
///
private void InitPath()
{
PathHelper.helper.CheckDataPathExist();
}
///
///
///
///
///
private bool CheckDatabaseExist(string name)
{
return System.IO.File.Exists(PathHelper.helper.GetDataPath(name, name + ".db"));
}
///
///
///
private void LoadDatabase()
{
Stopwatch sw = new Stopwatch();
sw.Start();
this.mDatabase = new DatabaseSerise().Load(mDatabaseName);
this.mRealDatabase = this.mDatabase.RealDatabase;
this.mHisDatabase = this.mDatabase.HisDatabase;
CurrentDatabaseVersion = this.mRealDatabase.Version;
CurrentDatabase = mRealDatabase.Name;
CurrentDatabaseLastUpdateTime = mRealDatabase.UpdateTime;
RDDCManager.Manager.Load(mDatabaseName);
sw.Stop();
LoggerService.Service.Info("LoadDatabase", "load " +mDatabaseName +" take " + sw.ElapsedMilliseconds.ToString() +" ms");
}
///
/// 重新加载数据库
///
public void ReStartDatabase()
{
LoggerService.Service.Info("ReStartDatabase", "start to restart database.",ConsoleColor.DarkYellow);
Stopwatch sw = new Stopwatch();
sw.Start();
var db = new DatabaseSerise().Load(mDatabaseName);
List ltmp = new List();
List htmp = new List();
foreach(var vv in db.RealDatabase.Tags.Where(e=>this.mRealDatabase.Tags.ContainsKey(e.Key)))
{
ltmp.Add(vv.Value);
}
foreach(var vv in ltmp)
{
if(db.HisDatabase.HisTags.ContainsKey(vv.Id))
{
htmp.Add(db.HisDatabase.HisTags[vv.Id]);
}
}
LoggerService.Service.Info("ReStartDatabase", "reload " + mDatabaseName + " take " + sw.ElapsedMilliseconds.ToString() + " ms");
compressEnginer.WaitForReady();
sw.Reset();
sw.Start();
hisEnginer.Pause();
realEnginer.Lock();
realEnginer.ReLoadTags(ltmp,db.RealDatabase);
realEnginer.UnLock();
hisEnginer.ReLoadTags(htmp, db.HisDatabase);
compressEnginer.ReSizeTagCompress(htmp);
hisEnginer.Resume();
this.mDatabase = db;
this.mRealDatabase = db.RealDatabase;
this.mHisDatabase = db.HisDatabase;
CurrentDatabaseVersion = db.Version;
CurrentDatabase = db.Name;
CurrentDatabaseLastUpdateTime = mRealDatabase.UpdateTime;
sw.Stop();
LoggerService.Service.Info("ReStartDatabase", "ReInit" + mDatabaseName + " take " + sw.ElapsedMilliseconds.ToString() + " ms");
LoggerService.Service.Info("ReStartDatabase", "start to restart database finish.", ConsoleColor.DarkYellow);
}
///
///
///
///
private async Task InitAsync(string database)
{
if (System.IO.Path.IsPathRooted(database))
{
this.mDatabaseName = System.IO.Path.GetFileNameWithoutExtension(database);
this.DatabasePath = System.IO.Path.GetDirectoryName(database);
}
else
{
this.mDatabaseName = database;
}
InitPath();
CPUAssignHelper.Helper.Init();
if (CheckDatabaseExist(mDatabaseName))
{
LoadDatabase();
mHisFileManager = new DataFileManager(mDatabaseName);
mHisFileManager.TagCountOneFile = mHisDatabase.Setting.TagCountOneFile;
var task = mHisFileManager.Int();
realEnginer = new RealEnginer(mRealDatabase);
realEnginer.Init();
ServiceLocator.Locator.Registor(realEnginer);
ServiceLocator.Locator.Registor(realEnginer);
ServiceLocator.Locator.Registor(realEnginer);
ServiceLocator.Locator.Registor(realEnginer);
ServiceLocator.Locator.Registor(realEnginer);
hisEnginer = new HisEnginer2(mHisDatabase, realEnginer);
hisEnginer.MergeMemoryTime = mHisDatabase.Setting.DataBlockDuration * 60;
hisEnginer.LogManager = new LogManager2() { Database = mDatabaseName,Parent=hisEnginer };
hisEnginer.Init();
ServiceLocator.Locator.Registor(hisEnginer);
compressEnginer = new CompressEnginer2();
compressEnginer.TagCountOneFile = mHisDatabase.Setting.TagCountOneFile;
compressEnginer.Init();
ServiceLocator.Locator.Registor(compressEnginer);
seriseEnginer = new SeriseEnginer2() { DatabaseName = database };
seriseEnginer.FileDuration = mHisDatabase.Setting.FileDataDuration;
seriseEnginer.BlockDuration = mHisDatabase.Setting.DataBlockDuration;
seriseEnginer.TagCountOneFile = mHisDatabase.Setting.TagCountOneFile;
seriseEnginer.DataSeriser = mHisDatabase.Setting.DataSeriser;
seriseEnginer.Init();
ServiceLocator.Locator.Registor(seriseEnginer);
querySerivce = new QuerySerivce(this.mDatabaseName);
mSecurityRunner = new SecurityRunner() { Document = mDatabase.Security };
RegistorInterface();
DriverManager.Manager.Init(realEnginer);
HisQueryManager.Instance.Registor(mDatabaseName);
await task;
return true;
}
else
{
LoggerService.Service.Erro("Runner", string.Format(DBRuntime.Res.Get("databasenotexist"), mDatabaseName));
return false;
}
}
///
///
///
private void RegistorInterface()
{
ServiceLocator.Locator.Registor(querySerivce);
ServiceLocator.Locator.Registor(mRealDatabase);
ServiceLocator.Locator.Registor(mSecurityRunner);
}
///
///
///
public void ReStart()
{
Stop();
Start();
}
///
///
///
public void Start(int port = 14330)
{
StartAsync("local");
}
///
/// 启动
///
///
public async void StartAsync(string database,int port = 14330)
{
LoggerService.Service.Info("Runner", " 数据库 " + database+" 开始启动");
RDDCManager.Manager.Start();
var re = await InitAsync(database);
if (!re)
{
return;
}
DBRuntime.Api.DataService.Service.Start(port);
if (RDDCManager.Manager.CurrentState == WorkState.Primary)
{
seriseEnginer.Start();
compressEnginer.Start();
hisEnginer.Start();
DriverManager.Manager.Start();
}
mIsStarted = true;
LoggerService.Service.Info("Runner", " 数据库 " + database + " 启动完成");
}
///
///
///
private bool SwitchToStandby()
{
try
{
hisEnginer.Stop();
compressEnginer.Stop();
seriseEnginer.Stop();
DriverManager.Manager.Stop();
}
catch
{
return false;
}
return true;
}
///
///
///
private bool SwitchToPrimary()
{
try
{
DriverManager.Manager.Start();
seriseEnginer.Start();
compressEnginer.Start();
hisEnginer.Start();
}
catch
{
return false;
}
return true;
}
///
/// 停止
///
public void Stop()
{
DBRuntime.Api.DataService.Service.Stop();
hisEnginer.Stop();
DriverManager.Manager.Stop();
compressEnginer.Stop();
seriseEnginer.Stop();
hisEnginer.Dispose();
compressEnginer.Dispose();
seriseEnginer.Dispose();
mIsStarted = false;
}
#endregion ...Methods...
#region ... Interfaces ...
#endregion ...Interfaces...
}
}