diff --git a/Common/Cdy.Tag/Real/WorkState.cs b/Common/Cdy.Tag/Real/WorkState.cs new file mode 100644 index 0000000000000000000000000000000000000000..bccc8c2dc5a852f51e49bf2d4a733287178dfd0c --- /dev/null +++ b/Common/Cdy.Tag/Real/WorkState.cs @@ -0,0 +1,38 @@ +//============================================================== +// Copyright (C) 2020 Inc. All rights reserved. +// +//============================================================== +// Create by 种道洋 at 2020/8/17 13:24:21. +// Version 1.0 +// 种道洋 +//============================================================== + +using System; +using System.Collections.Generic; +using System.Text; + +namespace Cdy.Tag +{ + /// + /// + /// + public enum WorkState + { + /// + /// 未知 + /// + Unknow, + /// + /// 工作机 + /// + Primary, + /// + /// 备份机 + /// + Standby, + /// + /// 切换中 + /// + Switching + } +} diff --git a/RunTime/DBInRun/Program.cs b/RunTime/DBInRun/Program.cs index 6bee804956e9964eaaa5ed5cb0bf8014728b16d6..e22c649dcf54b15bce194d0b0e27ba14c1aedd00 100644 --- a/RunTime/DBInRun/Program.cs +++ b/RunTime/DBInRun/Program.cs @@ -13,9 +13,6 @@ namespace DBInRun { static bool mIsClosed = false; - static Thread mainThread; - - //static MarshalMemoryBlock block; static void Main(string[] args) { Console.CancelKeyPress += Console_CancelKeyPress; @@ -25,6 +22,9 @@ namespace DBInRun Console.WriteLine(Res.Get("WelcomeMsg")); PrintLogo(); + + Console.WriteLine(Res.Get("HelpMsg")); + if (args.Length>0 && args[0]== "start") { Task.Run(() => { @@ -45,10 +45,7 @@ namespace DBInRun Cdy.Tag.Runner.RunInstance.Start(); } } - - mainThread = Thread.CurrentThread; - - Console.WriteLine(Res.Get("HelpMsg")); + while (!mIsClosed) { Console.Write(">"); @@ -111,6 +108,9 @@ namespace DBInRun Cdy.Tag.Runner.RunInstance.ReStartDatabase(); }); break; + case "list": + ListDatabase(); + break; case "h": Console.WriteLine(GetHelpString()); break; @@ -121,6 +121,24 @@ namespace DBInRun } } + /// + /// + /// + private static void ListDatabase() + { + string spath = System.IO.Path.GetDirectoryName(typeof(Program).Assembly.Location); + spath = System.IO.Path.Combine(spath, "Data"); + StringBuilder sb = new StringBuilder(); + string stemp = "{0} {1}"; + foreach(var vv in System.IO.Directory.EnumerateDirectories(spath)) + { + var vvn = new System.IO.DirectoryInfo(vv).Name; + string sdb = System.IO.Path.Combine(vv, vvn+".db"); + sb.AppendLine(string.Format(stemp, vvn, System.IO.File.GetLastWriteTime(sdb))); + } + Console.WriteLine(sb.ToString()); + } + /// /// /// @@ -225,6 +243,8 @@ namespace DBInRun re.AppendLine(); re.AppendLine("start [database] // "+Res.Get("StartMsg")); re.AppendLine("stop // " + Res.Get("StopMsg")); + re.AppendLine("restart // " + Res.Get("RestartMsg")); + re.AppendLine("List // " + Res.Get("ListMsg")); re.AppendLine("h // " + Res.Get("HMsg")); return re.ToString(); } diff --git a/RunTime/DBInRun/Properties/Resources.Designer.cs b/RunTime/DBInRun/Properties/Resources.Designer.cs index f8c0bb52f3c351b1d6c1b796f9eee893f5f97b78..293e322769c2e0716549a47446ffc6936d74a92e 100644 --- a/RunTime/DBInRun/Properties/Resources.Designer.cs +++ b/RunTime/DBInRun/Properties/Resources.Designer.cs @@ -96,6 +96,24 @@ namespace DBInRun.Properties { } } + /// + /// 查找类似 List all databse 的本地化字符串。 + /// + internal static string ListMsg { + get { + return ResourceManager.GetString("ListMsg", resourceCulture); + } + } + + /// + /// 查找类似 Qucik restarted a a database without pause it. 的本地化字符串。 + /// + internal static string RestartMsg { + get { + return ResourceManager.GetString("RestartMsg", resourceCulture); + } + } + /// /// 查找类似 start to run a databse,ignor database name to run default 'local' database 的本地化字符串。 /// diff --git a/RunTime/DBInRun/Properties/Resources.resx b/RunTime/DBInRun/Properties/Resources.resx index 1796e36a527a8e318b2836f6201fa0ee19b43111..b90890aeebc22817440c5c7c99b350309ce2828f 100644 --- a/RunTime/DBInRun/Properties/Resources.resx +++ b/RunTime/DBInRun/Properties/Resources.resx @@ -129,6 +129,12 @@ display command list + + List all databse + + + Qucik restarted a a database without pause it. + start to run a databse,ignor database name to run default 'local' database diff --git a/RunTime/DBInRun/Properties/Resources.zh-CN.resx b/RunTime/DBInRun/Properties/Resources.zh-CN.resx index 577b503751c67aa51bf1ea5d264c88bc4c6f01a5..8343778c587cc39f41db1ecdbb5a7feaf286ef57 100644 --- a/RunTime/DBInRun/Properties/Resources.zh-CN.resx +++ b/RunTime/DBInRun/Properties/Resources.zh-CN.resx @@ -129,6 +129,12 @@ 显示命令列表 + + 列出所有的数据库 + + + 在不中断的情况下快速启动数据库 + 运行指定数据库,如果忽略数据库名称则启动默认'local'数据库 diff --git a/RunTime/DBInRun/Properties/launchSettings.json b/RunTime/DBInRun/Properties/launchSettings.json index 21cb4218ac8cdf7641c4cf095a7db6c95139cbf5..8316bec8e161ee7226f3073a9a4dd459e0607ad8 100644 --- a/RunTime/DBInRun/Properties/launchSettings.json +++ b/RunTime/DBInRun/Properties/launchSettings.json @@ -2,7 +2,8 @@ "profiles": { "DBInRun": { "commandName": "Executable", - "executablePath": "C:\\Users\\cdy81\\source\\repos\\mars\\Output\\DBInRun.exe" + "executablePath": "C:\\Users\\chongdaoyang\\source\\repos\\mars\\Output\\DBInRun.exe", + "commandLineArgs": "start test1 37000" } } } \ No newline at end of file diff --git a/RunTime/DBRuntime/RDDC/RDDCClient.cs b/RunTime/DBRuntime/RDDC/RDDCClient.cs new file mode 100644 index 0000000000000000000000000000000000000000..10eafb7d91d7ef07c506318a18e74d18e4831bc1 --- /dev/null +++ b/RunTime/DBRuntime/RDDC/RDDCClient.cs @@ -0,0 +1,256 @@ +//============================================================== +// Copyright (C) 2020 Inc. All rights reserved. +// +//============================================================== +// Create by 种道洋 at 2020/8/17 17:03:59. +// Version 1.0 +// 种道洋 +//============================================================== + +using Cdy.Tag; +using DotNetty.Buffers; +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Text; +using System.Threading; + +namespace DBRuntime.RDDC +{ + /// + /// + /// + public class RDDCClient:SocketClient + { + + #region ... Variables ... + + /// + /// + /// + public const byte WorkStateFun = 1; + + /// + /// + /// + public const byte RealDataSyncFun = 2; + + + + public const byte AysncReturn = byte.MaxValue; + + + /// + /// 获取启动时间 + /// + public const byte GetStartTimeFun = 0; + + /// + /// 切换到从机 + /// + public const byte ChangeToStandbyFun = 1; + + /// + /// 切换同主机 + /// + public const byte ChangeToPrimaryFun = 2; + + /// + /// 获取工作状态 + /// + public const byte GetStateFun = 3; + + + private ManualResetEvent mWorkStateEvent = new ManualResetEvent(false); + + private IByteBuffer mWorkStateData; + + private ManualResetEvent mRealDataSyncEvent = new ManualResetEvent(false); + + private IByteBuffer mRealDataSyncData; + + #endregion ...Variables... + + #region ... Events ... + + #endregion ...Events... + + #region ... Constructor... + + #endregion ...Constructor... + + #region ... Properties ... + + #endregion ...Properties... + + #region ... Methods ... + + /// + /// + /// + /// + /// + protected override void ProcessData(byte fun, IByteBuffer datas) + { + datas.Retain(); + //收到异步请求回调数据 + if (datas.ReadableBytes == 1) + { + if (datas.ReadByte() == byte.MaxValue) + return; + else + { + Debug.Print("DbClient ProcessData Invailed data"); + } + } + else + { + switch (fun) + { + case WorkStateFun: + mWorkStateData = datas; + mWorkStateEvent.Set(); + break; + case RealDataSyncFun: + mRealDataSyncData = datas; + this.mRealDataSyncEvent.Set(); + break; + } + + } + + base.ProcessData(fun, datas); + } + + /// + /// + /// + /// + /// + public IByteBuffer SyncRealData(int timeout=5000) + { + var mb = GetBuffer(RealDataSyncFun, 0); + mRealDataSyncEvent.Reset(); + Send(mb); + try + { + if (mRealDataSyncEvent.WaitOne(timeout)) + { + return mRealDataSyncData; + } + } + finally + { + + } + return null; + } + + /// + /// + /// + /// + /// + public DateTime? GetStartTime(int timeout = 5000) + { + var mb = GetBuffer(WorkStateFun,1); + mb.WriteByte(GetStartTimeFun); + mWorkStateEvent.Reset(); + Send(mb); + try + { + if (mWorkStateEvent.WaitOne(timeout)) + { + return DateTime.FromBinary(mWorkStateData.ReadLong()); + } + } + finally + { + + } + return null; + } + + /// + /// + /// + /// + /// + public WorkState? GetWorkState(int timeout = 5000) + { + var mb = GetBuffer(WorkStateFun, 1); + mb.WriteByte(GetStateFun); + mWorkStateEvent.Reset(); + Send(mb); + try + { + if (mWorkStateEvent.WaitOne(timeout)) + { + return (WorkState)mWorkStateData.ReadByte(); + } + } + finally + { + + } + return null; + } + + /// + /// + /// + /// + /// + public bool? SwitchToPrimary(int timeout = 5000) + { + var mb = GetBuffer(WorkStateFun, 1); + mb.WriteByte(ChangeToPrimaryFun); + mWorkStateEvent.Reset(); + Send(mb); + try + { + if (mWorkStateEvent.WaitOne(timeout)) + { + return mWorkStateData.ReadByte()>0; + } + } + finally + { + + } + return null; + } + + + /// + /// + /// + /// + /// + public bool? SwitchToStandby(int timeout = 5000) + { + var mb = GetBuffer(WorkStateFun, 1); + mb.WriteByte(ChangeToStandbyFun); + mWorkStateEvent.Reset(); + Send(mb); + try + { + if (mWorkStateEvent.WaitOne(timeout)) + { + return mWorkStateData.ReadByte() > 0; + } + } + finally + { + + } + return null; + } + + #endregion ...Methods... + + #region ... Interfaces ... + + #endregion ...Interfaces... + } +} diff --git a/RunTime/DBRuntime/RDDC/RDDCDataService.cs b/RunTime/DBRuntime/RDDC/RDDCDataService.cs new file mode 100644 index 0000000000000000000000000000000000000000..7c56fe25860d866add9624311210a52eec1ff424 --- /dev/null +++ b/RunTime/DBRuntime/RDDC/RDDCDataService.cs @@ -0,0 +1,232 @@ +//============================================================== +// Copyright (C) 2020 Inc. All rights reserved. +// +//============================================================== +// Create by 种道洋 at 2020/5/14 10:22:00. +// Version 1.0 +// 种道洋 +//============================================================== + +using Cdy.Tag; +using DotNetty.Buffers; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DBRuntime.RDDC +{ + public class ApiFunConst + { + + /// + /// + /// + public const byte WorkStateFun = 1; + + /// + /// + /// + public const byte RealDataSyncFun = 2; + + + + public const byte AysncReturn = byte.MaxValue; + } + + /// + /// + /// + public class RDDCDataService: SocketServer + { + + #region ... Variables ... + + private IByteBuffer mAsyncCalldata; + + private Dictionary mProcess = new Dictionary(); + + private WorStateServerProcess mWorkStateProcess; + private RealDataSyncServerProcess mRealDataSyncProcess; + + /// + /// + /// + public static RDDCDataService Service = new RDDCDataService(); + + /// + /// + /// + public override string Name => "RDDCDataService"; + + #endregion ...Variables... + + #region ... Events ... + + #endregion ...Events... + + #region ... Constructor... + /// + /// + /// + public RDDCDataService() + { + RegistorInit(); + } + #endregion ...Constructor... + + #region ... Properties ... + + #endregion ...Properties... + + #region ... Methods ... + + + /// + /// + /// + /// + protected override void StartInner(int port) + { + mWorkStateProcess = new WorStateServerProcess() { Parent = this }; + mRealDataSyncProcess = new RealDataSyncServerProcess() { Parent = this }; + mWorkStateProcess.Start(); + mRealDataSyncProcess.Start(); + base.StartInner(port); + } + + /// + /// + /// + public override void Stop() + { + base.Stop(); + if (mWorkStateProcess != null) + { + mWorkStateProcess.Stop(); + mWorkStateProcess.Dispose(); + mWorkStateProcess = null; + } + if (mRealDataSyncProcess != null) + { + mRealDataSyncProcess.Stop(); + mRealDataSyncProcess.Dispose(); + mRealDataSyncProcess = null; + } + } + + /// + /// + /// + /// + private IByteBuffer GetAsyncData() + { + mAsyncCalldata = BufferManager.Manager.Allocate(ApiFunConst.AysncReturn, 4); + mAsyncCalldata.WriteInt(0); + return mAsyncCalldata; + } + + /// + /// + /// + private void RegistorInit() + { + this.RegistorFunCallBack(ApiFunConst.WorkStateFun, WorkStateProcess); + this.RegistorFunCallBack(ApiFunConst.RealDataSyncFun, RealDataSyncProcess); + } + + /// + /// + /// + public void PushRealDatatoClient(string clientId,byte[] value) + { + this.SendData(clientId, Api.ApiFunConst.RealDataPushFun, value,value.Length); + } + + /// + /// + /// + /// + /// + public void PushRealDatatoClient(string clientId, IByteBuffer value) + { + this.SendData(clientId, value); + } + + /// + /// + /// + /// + /// + /// + public void AsyncCallback(string clientId,byte fun, byte[] value,int len) + { + this.SendData(clientId, fun, value, len); + + } + + /// + /// + /// + /// + /// + public void AsyncCallback(string clientId, IByteBuffer data) + { + this.SendData(clientId, data); + } + + /// + /// + /// + /// + /// + /// + /// + public void AsyncCallback(string clientId, byte fun, IntPtr value, int len) + { + this.SendData(clientId, fun, value, len); + } + + + /// + /// + /// + /// + /// + /// + private IByteBuffer WorkStateProcess(string clientId, IByteBuffer memory) + { + this.mWorkStateProcess.ProcessData(clientId, memory); + return GetAsyncData(); + } + + /// + /// + /// + /// + /// + /// + private IByteBuffer RealDataSyncProcess(string clientId, IByteBuffer memory) + { + this.mRealDataSyncProcess.ProcessData(clientId, memory); + return GetAsyncData(); + } + + /// + /// + /// + /// + protected override void OnClientDisConnected(string id) + { + mRealDataSyncProcess.OnClientDisconnected(id); + this.mWorkStateProcess.OnClientDisconnected(id); + ServiceLocator.Locator.Resolve().LogoutByClientId(id); + base.OnClientDisConnected(id); + } + + #endregion ...Methods... + + #region ... Interfaces ... + + #endregion ...Interfaces... + } +} diff --git a/RunTime/DBRuntime/RDDC/RDDCManager.cs b/RunTime/DBRuntime/RDDC/RDDCManager.cs new file mode 100644 index 0000000000000000000000000000000000000000..47e2997c325e200cb1d88f3f0fcc68c07320387d --- /dev/null +++ b/RunTime/DBRuntime/RDDC/RDDCManager.cs @@ -0,0 +1,211 @@ +//============================================================== +// Copyright (C) 2020 Inc. All rights reserved. +// +//============================================================== +// Create by 种道洋 at 2020/8/17 16:34:14. +// Version 1.0 +// 种道洋 +//============================================================== + +using Cdy.Tag; +using DBRuntime.RDDC; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace DBRuntime +{ + public class RDDCManager + { + + #region ... Variables ... + /// + /// + /// + public static RDDCManager Manager = new RDDCManager(); + + private RDDCDataService mServer; + + private RDDCClient mClient; + + + private bool mIsInited = false; + + private object mLockObj = new object(); + + #endregion ...Variables... + + #region ... Events ... + + #endregion ...Events... + + #region ... Constructor... + + public RDDCManager() + { + + } + + #endregion ...Constructor... + + #region ... Properties ... + + /// + /// 当前状态 + /// + public WorkState CurrentState { get; set; } = WorkState.Unknow; + + /// + /// + /// + public DateTime StartTime { get; set; } + + /// + /// 服务端口 + /// + public int Port { get; set; } + + /// + /// + /// + public string RemoteIp { get; set; } + + /// + /// + /// + public Func SwitchWorkStateAction { get; set; } + + #endregion ...Properties... + + #region ... Methods ... + + /// + /// + /// + public void Start() + { + mIsInited = false; + mServer = new RDDCDataService(); + mServer.Start(Port); + + mClient = new RDDCClient(); + mClient.Connect(RemoteIp, Port); + mClient.PropertyChanged += MClient_PropertyChanged; + CheckWorkState(); + mIsInited = true; + } + + /// + /// + /// + /// + /// + private void MClient_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) + { + if(mIsInited) + { + Task.Run(ProcessClientConnectChanged); + } + } + + + /// + /// + /// + public void Stop() + { + mServer.Stop(); + mClient.Close(); + } + + private void ProcessClientConnectChanged() + { + if (!mClient.IsConnected) + { + if(CurrentState != WorkState.Primary) + SwitchTo(WorkState.Primary); + } + else + { + var state = mClient.GetWorkState(); + if ((state == WorkState.Primary && this.CurrentState == WorkState.Primary) || (state == WorkState.Standby && this.CurrentState == WorkState.Standby)) + { + var time = mClient.GetStartTime(); + var ss = time > this.StartTime ? WorkState.Primary : WorkState.Standby; + SwitchTo(ss); + } + } + } + + /// + /// + /// + private void CheckWorkState() + { + int count = 0; + while(!mClient.IsConnected) + { + Thread.Sleep(100); + count++; + if (count > 30) break; + } + + if(!mClient.IsConnected) + { + CurrentState = WorkState.Primary; + } + else + { + var time = mClient.GetStartTime(); + if(time!=null) + { + CurrentState = time > this.StartTime ? WorkState.Primary : WorkState.Standby; + } + else + { + CurrentState = WorkState.Standby; + } + } + } + + + + + /// + /// + /// + /// + /// + public bool SwitchTo(WorkState state) + { + lock (mLockObj) + { + var olds = CurrentState; + CurrentState = WorkState.Switching; + if (SwitchWorkStateAction != null) + { + if (SwitchWorkStateAction(state)) + { + CurrentState = state; + return true; + } + else + { + CurrentState = olds; + return false; + } + } + CurrentState = state; + return true; + } + } + + #endregion ...Methods... + + #region ... Interfaces ... + + #endregion ...Interfaces... + } +} diff --git a/RunTime/DBRuntime/RDDC/RDDCServerProcessBase.cs b/RunTime/DBRuntime/RDDC/RDDCServerProcessBase.cs new file mode 100644 index 0000000000000000000000000000000000000000..abd076a3c98b58b17768662854f50911e8d8474d --- /dev/null +++ b/RunTime/DBRuntime/RDDC/RDDCServerProcessBase.cs @@ -0,0 +1,187 @@ +//============================================================== +// Copyright (C) 2020 Inc. All rights reserved. +// +//============================================================== +// Create by 种道洋 at 2020/5/14 11:01:03. +// Version 1.0 +// 种道洋 +//============================================================== + +using Cdy.Tag; +using DotNetty.Buffers; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; + +namespace DBRuntime.RDDC +{ + public abstract class RDDCServerProcessBase : IDisposable + { + + #region ... Variables ... + /// + /// + /// + private Dictionary> mDatasCach = new Dictionary>(); + + private Thread mProcessThread; + + private ManualResetEvent resetEvent; + + private bool mIsClosed = false; + + #endregion ...Variables... + + #region ... Events ... + + #endregion ...Events... + + #region ... Constructor... + + #endregion ...Constructor... + + #region ... Properties ... + /// + /// + /// + public abstract byte FunId { get; } + + /// + /// + /// + public RDDCDataService Parent { get; set; } + + + + #endregion ...Properties... + + #region ... Methods ... + + + /// + /// + /// + /// + /// + protected IByteBuffer ToByteBuffer(byte id, string value) + { + var re = BufferManager.Manager.Allocate(id, value.Length*2); + re.WriteString(value); + return re; + } + + /// + /// + /// + /// + /// + /// + protected IByteBuffer ToByteBuffer(byte id, byte value) + { + var re = BufferManager.Manager.Allocate(id, 1); + re.WriteByte(value); + return re; + } + + protected IByteBuffer ToByteBuffer(byte id, long value) + { + var re = BufferManager.Manager.Allocate(id, 1); + re.WriteLong(value); + return re; + } + + /// + /// + /// + /// + public virtual void ProcessData(string client, IByteBuffer data) + { + data.Retain(); + if (mDatasCach.ContainsKey(client)) + { + mDatasCach[client].Enqueue(data); + } + else + { + var vq = new Queue(); + vq.Enqueue(data); + mDatasCach.Add(client, vq); + } + resetEvent.Set(); + } + + /// + /// + /// + private void DataProcess() + { + while (!mIsClosed) + { + resetEvent.WaitOne(); + if (mIsClosed) return; + resetEvent.Reset(); + foreach (var vv in mDatasCach) + { + while(vv.Value.Count>0) + { + var dd = vv.Value.Dequeue(); + ProcessSingleData(vv.Key, dd); + } + } + } + } + + /// + /// + /// + /// + /// + protected virtual void ProcessSingleData(string client, IByteBuffer data) + { + data.ReleaseBuffer(); + } + + + public virtual void Start() + { + resetEvent = new ManualResetEvent(false); + mProcessThread = new Thread(DataProcess); + mProcessThread.IsBackground = true; + mProcessThread.Start(); + } + + /// + /// + /// + public virtual void Stop() + { + mIsClosed = true; + resetEvent.Set(); + resetEvent.Close(); + } + + /// + /// + /// + public virtual void Dispose() + { + Parent = null; + } + + /// + /// + /// + /// + public virtual void OnClientDisconnected(string id) + { + + } + + #endregion ...Methods... + + #region ... Interfaces ... + + #endregion ...Interfaces... + } +} diff --git a/RunTime/DBRuntime/RDDC/RealDataSyncServerProcess.cs b/RunTime/DBRuntime/RDDC/RealDataSyncServerProcess.cs new file mode 100644 index 0000000000000000000000000000000000000000..a94089d41402b6fecb04e0397f286813b7de08d9 --- /dev/null +++ b/RunTime/DBRuntime/RDDC/RealDataSyncServerProcess.cs @@ -0,0 +1,80 @@ +//============================================================== +// Copyright (C) 2020 Inc. All rights reserved. +// +//============================================================== +// Create by 种道洋 at 2020/8/17 15:52:53. +// Version 1.0 +// 种道洋 +//============================================================== + +using Cdy.Tag; +using DBRuntime.Api; +using DotNetty.Buffers; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DBRuntime.RDDC +{ + public class RealDataSyncServerProcess : RDDCServerProcessBase + { + + #region ... Variables ... + + #endregion ...Variables... + + #region ... Events ... + + #endregion ...Events... + + #region ... Constructor... + + #endregion ...Constructor... + + #region ... Properties ... + + /// + /// + /// + public override byte FunId => 2; + + + #endregion ...Properties... + + #region ... Methods ... + + /// + /// + /// + /// + /// + protected override void ProcessSingleData(string client, IByteBuffer data) + { + ProcessRealDataSync(client); + base.ProcessSingleData(client, data); + } + + + /// + /// + /// + /// + private void ProcessRealDataSync(string clientId) + { + var service = ServiceLocator.Locator.Resolve(); + var real = (service as RealEnginer); + var re = BufferManager.Manager.Allocate(ApiFunConst.RealDataSyncFun,4); + re.WriteInt(real.Memory.Length); + re = Unpooled.CompositeBuffer().AddComponents(true, re, Unpooled.WrappedBuffer(real.Memory, 0, real.Memory.Length)); + Parent.AsyncCallback(clientId, re); + } + + + #endregion ...Methods... + + #region ... Interfaces ... + + #endregion ...Interfaces... + + } +} diff --git a/RunTime/DBRuntime/RDDC/WorStateServerProcess.cs b/RunTime/DBRuntime/RDDC/WorStateServerProcess.cs new file mode 100644 index 0000000000000000000000000000000000000000..e1e3aea6f57da20b3f423b997c7245ee611dc29c --- /dev/null +++ b/RunTime/DBRuntime/RDDC/WorStateServerProcess.cs @@ -0,0 +1,125 @@ +//============================================================== +// Copyright (C) 2020 Inc. All rights reserved. +// +//============================================================== +// Create by 种道洋 at 2020/8/17 15:50:59. +// Version 1.0 +// 种道洋 +//============================================================== + +using DBRuntime.Api; +using DotNetty.Buffers; +using System; +using System.Collections.Generic; +using System.Text; + +namespace DBRuntime.RDDC +{ + public class WorStateServerProcess : RDDCServerProcessBase + { + + #region ... Variables ... + /// + /// 获取启动时间 + /// + public const byte GetStartTime = 0; + + /// + /// 切换到从机 + /// + public const byte ChangeToStandby = 1; + + /// + /// 切换同主机 + /// + public const byte ChangeToPrimary = 2; + + /// + /// 获取工作状态 + /// + public const byte GetState = 3; + + #endregion ...Variables... + + #region ... Events ... + + #endregion ...Events... + + #region ... Constructor... + + #endregion ...Constructor... + + #region ... Properties ... + /// + /// + /// + public override byte FunId => 1; + + #endregion ...Properties... + + #region ... Methods ... + + /// + /// + /// + /// + /// + protected override void ProcessSingleData(string client, IByteBuffer data) + { + byte cmd = data.ReadByte(); + switch (cmd) + { + case GetStartTime: + ProcessGetStartTime(client); + break; + case ChangeToPrimary: + var re = ProcessSwichToPrimary(); + Parent.AsyncCallback(client, ToByteBuffer(GetStartTime, re ? 1 : 0)); + break; + case ChangeToStandby: + re = ProcessSwichToStandby(); + Parent.AsyncCallback(client, ToByteBuffer(GetStartTime, re ? 1 : 0)); + break; + case GetState: + var state = (byte)RDDCManager.Manager.CurrentState; + Parent.AsyncCallback(client, ToByteBuffer(GetStartTime, state)); + break; + } + + base.ProcessSingleData(client, data); + } + + /// + /// + /// + private void ProcessGetStartTime(string client) + { + Parent.AsyncCallback(client, ToByteBuffer(GetStartTime, RDDCManager.Manager.StartTime.ToBinary())); + } + + /// + /// + /// + /// + private bool ProcessSwichToPrimary() + { + return RDDCManager.Manager.SwitchTo(Cdy.Tag.WorkState.Primary); + } + + /// + /// + /// + /// + private bool ProcessSwichToStandby() + { + return RDDCManager.Manager.SwitchTo(Cdy.Tag.WorkState.Standby); + } + + #endregion ...Methods... + + #region ... Interfaces ... + + #endregion ...Interfaces... + + } +} diff --git a/RunTime/DBRuntime/Runner.cs b/RunTime/DBRuntime/Runner.cs index a9b2c8fa4a6d7b77fec964fcabd34d42227df175..d2daaf9720793887e9b0c992acdb7048547b0034 100644 --- a/RunTime/DBRuntime/Runner.cs +++ b/RunTime/DBRuntime/Runner.cs @@ -7,6 +7,7 @@ // 种道洋 //============================================================== using Cdy.Tag.Driver; +using DBRuntime; using System; using System.Collections.Generic; using System.Diagnostics; @@ -75,6 +76,8 @@ namespace Cdy.Tag /// static Runner() { + RDDCManager.Manager.StartTime = DateTime.Now; + //注册日志 ServiceLocator.Locator.Registor(new ConsoleLogger()); @@ -86,6 +89,18 @@ namespace Cdy.Tag #region ... Properties ... + /// + /// + /// + public WorkState State + { + get + { + return RDDCManager.Manager.CurrentState; + } + } + + /// /// 数据库存访路径 /// @@ -317,17 +332,22 @@ namespace Cdy.Tag 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); - seriseEnginer.Start(); - compressEnginer.Start(); - hisEnginer.Start(); - //mSecurityRunner.Start(); - DriverManager.Manager.Start(); + + if (RDDCManager.Manager.CurrentState == WorkState.Primary) + { + seriseEnginer.Start(); + compressEnginer.Start(); + hisEnginer.Start(); + DriverManager.Manager.Start(); + } mIsStarted = true; LoggerService.Service.Info("Runner", " 数据库 " + database + " 启动完成");