|
@@ -1,12 +1,10 @@
|
|
|
using System;
|
|
|
-using System.Collections.Concurrent;
|
|
|
using System.Collections.Generic;
|
|
|
using System.Threading;
|
|
|
using Vit.Extensions;
|
|
|
using Vit.Core.Module.Log;
|
|
|
using Sers.Core.Module.Rpc;
|
|
|
using Vit.Core.Util.ConfigurationManager;
|
|
|
-using Vit.Core.Util.Threading;
|
|
|
using Sers.Core.CL.CommunicationManage;
|
|
|
using Sers.Core.CL.MessageOrganize;
|
|
|
using Sers.Core.Module.Message;
|
|
@@ -14,6 +12,7 @@ using Vit.Core.Util.ComponentModel.SsError;
|
|
|
using Sers.Core.Module.Api.LocalApi.Event;
|
|
|
using Sers.Core.Util.Consumer;
|
|
|
using System.Runtime.CompilerServices;
|
|
|
+using Newtonsoft.Json.Linq;
|
|
|
|
|
|
namespace Sers.Core.Module.Api.LocalApi
|
|
|
{
|
|
@@ -23,11 +22,16 @@ namespace Sers.Core.Module.Api.LocalApi
|
|
|
/// <summary>
|
|
|
/// 后台服务的线程个数(单位个,默认0,代表不开启服务)(appsettings.json :: Sers.LocalApiService.workThreadCount)
|
|
|
/// </summary>
|
|
|
- public int workThreadCount { get; set; }
|
|
|
+ public int workThreadCount { get => workThread.workThreadCount; set => workThread.workThreadCount = value; }
|
|
|
|
|
|
public LocalApiService()
|
|
|
{
|
|
|
- workThreadCount = ConfigurationManager.Instance.GetByPath<int?>("Sers.LocalApiService.workThreadCount") ?? 0;
|
|
|
+ workThread = ConsumerFactory.CreateConsumer<RequestInfo>(ConfigurationManager.Instance.GetByPath<JObject>("Sers.LocalApiService.workThread"));
|
|
|
+
|
|
|
+ workThread.name = "LocalApiService";
|
|
|
+ workThread.processor = Consumer_Processor;
|
|
|
+ workThread.OnFinish = Consumer_OnFinish;
|
|
|
+ workThread.OnTimeout = Consumer_OnTimeout;
|
|
|
}
|
|
|
|
|
|
public void Init()
|
|
@@ -43,8 +47,10 @@ namespace Sers.Core.Module.Api.LocalApi
|
|
|
public IEnumerable<IApiNode> apiNodes => apiNodeMng.apiNodes;
|
|
|
|
|
|
|
|
|
- public ApiNodeMng ApiNodeMng => apiNodeMng;
|
|
|
+ public ApiNodeMng ApiNodeMng => apiNodeMng;
|
|
|
+
|
|
|
|
|
|
+ static readonly ApiMessage const_ApiReply_Err_Timeout = new ApiMessage().InitAsApiReplyMessageByError(SsError.Err_HandleTimeout);
|
|
|
|
|
|
|
|
|
|
|
@@ -104,7 +110,21 @@ namespace Sers.Core.Module.Api.LocalApi
|
|
|
#endregion
|
|
|
|
|
|
|
|
|
- static readonly ApiMessage const_ApiReply_Err_Timeout = new ApiMessage().InitAsApiReplyMessageByError(SsError.Err_HandleTimeout);
|
|
|
+
|
|
|
+ #region Start Stop
|
|
|
+ public bool Start()
|
|
|
+ {
|
|
|
+ Stop();
|
|
|
+ return Consumer_Start();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void Stop()
|
|
|
+ {
|
|
|
+ Consumer_Stop();
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
#region 后台服务
|
|
@@ -112,6 +132,7 @@ namespace Sers.Core.Module.Api.LocalApi
|
|
|
{
|
|
|
public IOrganizeConnection conn;
|
|
|
public ApiMessage apiRequest;
|
|
|
+ public ApiMessage apiReply;
|
|
|
public Object sender;
|
|
|
public Action<object, ApiMessage> callback;
|
|
|
}
|
|
@@ -128,275 +149,105 @@ namespace Sers.Core.Module.Api.LocalApi
|
|
|
requestInfo.apiRequest = apiRequest;
|
|
|
requestInfo.callback = callback;
|
|
|
|
|
|
- worker.Publish(requestInfo);
|
|
|
+ Consumer_Publish(requestInfo);
|
|
|
}
|
|
|
+ #endregion
|
|
|
|
|
|
|
|
|
|
|
|
- #region Start Stop
|
|
|
-
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// 后台调用Api的线程
|
|
|
- /// </summary>
|
|
|
- IWorker worker = null;
|
|
|
-
|
|
|
- public bool Start()
|
|
|
- {
|
|
|
- Stop();
|
|
|
-
|
|
|
- int timeout_ms = ConfigurationManager.Instance.GetByPath<int?>("Sers.LocalApiService.timeout_ms") ?? 0;
|
|
|
+ #region Consumer
|
|
|
+
|
|
|
|
|
|
- if (timeout_ms > 0)
|
|
|
- {
|
|
|
- worker = new Worker_TimeLimit() { timeout_ms = timeout_ms };
|
|
|
-
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- worker = new Worker();
|
|
|
- }
|
|
|
+ readonly IConsumer<RequestInfo> workThread;
|
|
|
|
|
|
-
|
|
|
- return worker.Start(workThreadCount, CallLocalApi);
|
|
|
- }
|
|
|
|
|
|
- public void Stop()
|
|
|
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
+ void Consumer_Publish(RequestInfo requestInfo)
|
|
|
{
|
|
|
- worker?.Stop();
|
|
|
- worker = null;
|
|
|
+ workThread.Publish(requestInfo);
|
|
|
}
|
|
|
- #endregion
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- #endregion
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- #region class Worker
|
|
|
- interface IWorker { bool Start(int workThreadCount, Func<ApiMessage, ApiMessage> callLocalApi);void Stop(); void Publish(RequestInfo requestInfo); }
|
|
|
|
|
|
- #region Worker
|
|
|
|
|
|
-
|
|
|
- class Worker : IWorker
|
|
|
+ bool Consumer_Start()
|
|
|
{
|
|
|
-
|
|
|
- IConsumer<RequestInfo> taskToCallApi = ConsumerFactory.CreateConsumer<RequestInfo>();
|
|
|
-
|
|
|
-
|
|
|
- Func<ApiMessage, ApiMessage> callLocalApi;
|
|
|
-
|
|
|
-
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- public void Publish(RequestInfo requestInfo)
|
|
|
- {
|
|
|
- taskToCallApi.Publish(requestInfo);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- public bool Start(int workThreadCount, Func<ApiMessage, ApiMessage> callLocalApi)
|
|
|
+ if (workThread.IsRunning) return false;
|
|
|
+ try
|
|
|
{
|
|
|
- if (taskToCallApi.IsRunning) return false;
|
|
|
-
|
|
|
- try
|
|
|
+ if (workThreadCount > 0)
|
|
|
{
|
|
|
- this.callLocalApi = callLocalApi;
|
|
|
-
|
|
|
- taskToCallApi.name = "LocalApiService";
|
|
|
- taskToCallApi.workThreadCount = workThreadCount;
|
|
|
- taskToCallApi.processor = Processor;
|
|
|
+ workThread.Start();
|
|
|
+ Logger.Info("[LocalApiService] Started,workThreadCount:" + workThreadCount);
|
|
|
|
|
|
- if (workThreadCount > 0)
|
|
|
- {
|
|
|
- taskToCallApi.Start();
|
|
|
- Logger.Info("[LocalApiService] Started,workThreadCount:" + workThreadCount);
|
|
|
-
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- Logger.Error(ex);
|
|
|
- Stop();
|
|
|
- return false;
|
|
|
}
|
|
|
+ return true;
|
|
|
}
|
|
|
-
|
|
|
- public void Stop()
|
|
|
+ catch (Exception ex)
|
|
|
{
|
|
|
- if (!taskToCallApi.IsRunning) return;
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- taskToCallApi.Stop();
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- Logger.Error(ex);
|
|
|
- }
|
|
|
- Logger.Info("[LocalApiService] Stoped");
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- #region TaskToCallApi
|
|
|
-
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- void Processor(RequestInfo requestInfo)
|
|
|
- {
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- CommunicationManageServer.CurConn = requestInfo.conn;
|
|
|
-
|
|
|
- //处理请求
|
|
|
- ApiMessage apiReply = callLocalApi(requestInfo.apiRequest);
|
|
|
-
|
|
|
- //调用请求回调
|
|
|
- requestInfo.callback(requestInfo.sender, apiReply);
|
|
|
- }
|
|
|
- catch (Exception ex) when (!(ex.GetBaseException() is ThreadInterruptedException))
|
|
|
- {
|
|
|
- Logger.Error(ex);
|
|
|
- }
|
|
|
+ Logger.Error(ex);
|
|
|
+ Consumer_Stop();
|
|
|
+ return false;
|
|
|
}
|
|
|
-
|
|
|
-
|
|
|
- #endregion
|
|
|
}
|
|
|
- #endregion
|
|
|
|
|
|
-
|
|
|
-
|
|
|
- #region Worker_TimeLimit
|
|
|
- class Worker_TimeLimit : IWorker
|
|
|
+ void Consumer_Stop()
|
|
|
{
|
|
|
+ if (!workThread.IsRunning) return;
|
|
|
|
|
|
- BlockingCollection<RequestInfo> requestQueue = new BlockingCollection<RequestInfo>();
|
|
|
-
|
|
|
-
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- public void Publish(RequestInfo requestInfo)
|
|
|
+ try
|
|
|
{
|
|
|
- requestQueue.Add(requestInfo);
|
|
|
+ workThread.Stop();
|
|
|
}
|
|
|
+ catch (Exception ex)
|
|
|
+ {
|
|
|
+ Logger.Error(ex);
|
|
|
+ }
|
|
|
+ Logger.Info("[LocalApiService] Stoped");
|
|
|
+ }
|
|
|
|
|
|
|
|
|
-
|
|
|
- LongTaskHelp_TimeLimit taskToCallApi = new LongTaskHelp_TimeLimit();
|
|
|
- Func<ApiMessage, ApiMessage> callLocalApi;
|
|
|
+ #region event
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// 超时时间。(主动关闭超过此时间的任务,实际任务强制关闭的时间会在1倍超时时间到2倍超时时间内)。单位:ms。
|
|
|
- /// 脉冲间隔。
|
|
|
- /// </summary>
|
|
|
- public int timeout_ms { set { taskToCallApi.timeout_ms = value; } }
|
|
|
- public bool Start(int workThreadCount, Func<ApiMessage, ApiMessage> callLocalApi)
|
|
|
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
+ void Consumer_Processor(RequestInfo requestInfo)
|
|
|
+ {
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- this.callLocalApi = callLocalApi;
|
|
|
-
|
|
|
- taskToCallApi.threadName = "LocalApiService";
|
|
|
- taskToCallApi.threadCount = workThreadCount;
|
|
|
+ CommunicationManageServer.CurConn = requestInfo.conn;
|
|
|
|
|
|
- if (workThreadCount > 0)
|
|
|
- {
|
|
|
- taskToCallApi.Start(GetWork, DealWork, OnFinish, OnTimeout);
|
|
|
- Logger.Info("[LocalApiService] Started,workThreadCount:" + workThreadCount+ ",timeout_ms:" + taskToCallApi.timeout_ms);
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- Logger.Error(ex);
|
|
|
- Stop();
|
|
|
- return false;
|
|
|
- }
|
|
|
+ //处理请求
|
|
|
+ requestInfo.apiReply = CallLocalApi(requestInfo.apiRequest);
|
|
|
}
|
|
|
-
|
|
|
- public void Stop()
|
|
|
+ catch (Exception ex) when (!(ex.GetBaseException() is ThreadInterruptedException))
|
|
|
{
|
|
|
- if (!taskToCallApi.IsRunning) return;
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- taskToCallApi.Stop();
|
|
|
- }
|
|
|
- catch (Exception ex)
|
|
|
- {
|
|
|
- Logger.Error(ex);
|
|
|
- }
|
|
|
- Logger.Info("[LocalApiService] Stoped");
|
|
|
+ Logger.Error(ex);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
+ void Consumer_OnFinish(RequestInfo requestInfo)
|
|
|
+ {
|
|
|
+ //调用请求回调
|
|
|
+ requestInfo.callback(requestInfo.sender, requestInfo.apiReply);
|
|
|
+ }
|
|
|
|
|
|
- #region TaskToCallApi
|
|
|
-
|
|
|
- /*
|
|
|
- workArg apiRequest
|
|
|
- workArg2 apiReply
|
|
|
- workArg3 sender
|
|
|
- workArg4 callback
|
|
|
-
|
|
|
-
|
|
|
- */
|
|
|
-
|
|
|
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
+ void Consumer_OnTimeout(RequestInfo requestInfo)
|
|
|
+ {
|
|
|
+ ApiMessage apiReply = new ApiMessage();
|
|
|
+ apiReply.rpcContextData_OriData = const_ApiReply_Err_Timeout.rpcContextData_OriData;
|
|
|
+ apiReply.value_OriData = const_ApiReply_Err_Timeout.value_OriData;
|
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- void GetWork(LongTaskHelp_TimeLimit.Worker w)
|
|
|
- {
|
|
|
- //堵塞获取请求
|
|
|
- var requestInfo = requestQueue.Take();
|
|
|
- CommunicationManageServer.CurConn = requestInfo.conn;
|
|
|
+ //调用请求回调
|
|
|
+ requestInfo.callback(requestInfo.sender, apiReply);
|
|
|
+ }
|
|
|
|
|
|
- w.workArg = requestInfo.apiRequest;
|
|
|
- w.workArg3 = requestInfo.sender;
|
|
|
- w.workArg4 = requestInfo.callback;
|
|
|
-
|
|
|
- }
|
|
|
+ #endregion
|
|
|
|
|
|
+ #endregion
|
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- void DealWork(LongTaskHelp_TimeLimit.Worker w)
|
|
|
- {
|
|
|
- ApiMessage apiRequest = (ApiMessage)w.workArg;
|
|
|
|
|
|
- //处理请求
|
|
|
- w.workArg2 = callLocalApi(apiRequest);
|
|
|
- }
|
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- void OnFinish(LongTaskHelp_TimeLimit.Worker w)
|
|
|
- {
|
|
|
- ApiMessage apiReply = (ApiMessage)w.workArg2;
|
|
|
- object sender = w.workArg3;
|
|
|
- Action<object, ApiMessage> callback = (Action<object, ApiMessage>)w.workArg4;
|
|
|
- //调用请求回调
|
|
|
- callback(sender, apiReply);
|
|
|
- }
|
|
|
|
|
|
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
|
|
|
- void OnTimeout(LongTaskHelp_TimeLimit.Worker w)
|
|
|
- {
|
|
|
- ApiMessage apiReply = new ApiMessage();
|
|
|
- apiReply.rpcContextData_OriData = const_ApiReply_Err_Timeout.rpcContextData_OriData;
|
|
|
- apiReply.value_OriData = const_ApiReply_Err_Timeout.value_OriData;
|
|
|
-
|
|
|
- object sender = w.workArg3;
|
|
|
- Action<object, ApiMessage> callback = (Action<object, ApiMessage>)w.workArg4;
|
|
|
-
|
|
|
- //调用请求回调
|
|
|
- callback(sender, apiReply);
|
|
|
- }
|
|
|
-
|
|
|
- #endregion
|
|
|
- }
|
|
|
- #endregion
|
|
|
-
|
|
|
- #endregion
|
|
|
|
|
|
|
|
|
|