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 + " 启动完成");