private void ApiCall(ref ZSocket socket, ApiCallItem item) { using (IocScope.CreateScope()) { Interlocked.Increment(ref CallCount); try { if (LogRecorder.LogMonitor) { ApiCallByMonitor(ref socket, item); } else { ApiCallNoMonitor(ref socket, item); } } catch (Exception ex) { ZeroTrace.WriteException(StationName, ex, "ApiCall", item.ApiName); item.Result = ApiResult.InnerErrorJson; SendResult(ref socket, item, ZeroOperatorStateType.Error); } finally { Interlocked.Decrement(ref waitCount); } } }
void IApiHandler.End(ApiStation station, ApiCallItem item) { count.End = DateTime.Now.Ticks; count.Status = item.Status; //count.FromId = item.CallerGlobalId; ApiCounter.Instance.Count(count); }
/// <summary> /// 发送返回值 /// </summary> /// <param name="socket"></param> /// <param name="item"></param> /// <param name="state"></param> /// <returns></returns> private bool SendResult(ref ZSocket socket, ApiCallItem item, ZeroOperatorStateType state) { if (!CanLoop) { ZeroTrace.WriteError("SendResult", "is closed", StationName); return(false); } if (item.Result == null) { return(SendResult(ref socket, new ZMessage { new ZFrame(item.Caller), new ZFrame(new byte[] { 2, (byte)state, ZeroFrameType.Requester, ZeroFrameType.GlobalId }), new ZFrame(item.Requester.ToZeroBytes()), new ZFrame((item.GlobalId).ToZeroBytes()) })); } return(SendResult(ref socket, new ZMessage { new ZFrame(item.Caller), new ZFrame(new byte[] { 3, (byte)state, ZeroFrameType.JsonValue, ZeroFrameType.Requester, ZeroFrameType.GlobalId }), new ZFrame((item.Result).ToZeroBytes()), new ZFrame(item.Requester.ToZeroBytes()), new ZFrame((item.GlobalId).ToZeroBytes()) })); }
private void ApiCallNoMonitor(ref ZSocket socket, ApiCallItem item) { ZeroOperatorStateType state = RestoryContext(item); if (state == ZeroOperatorStateType.Ok) { Prepare(item); state = ExecCommand(item); if (state != ZeroOperatorStateType.Ok) { Interlocked.Increment(ref ErrorCount); } else { Interlocked.Increment(ref SuccessCount); } } else { Interlocked.Increment(ref ErrorCount); } if (!SendResult(ref socket, item, state)) { Interlocked.Increment(ref SendError); } End(item); }
private void ApiCallByMonitor(ref ZSocket socket, ApiCallItem item) { using (MonitorScope.CreateScope(item.ApiName)) { LogRecorder.MonitorTrace($"Caller:{item.Caller}"); LogRecorder.MonitorTrace($"GlobalId:{item.GlobalId}"); LogRecorder.MonitorTrace(JsonConvert.SerializeObject(item)); ZeroOperatorStateType state; Prepare(item); using (MonitorScope.CreateScope("Do")) { state = ExecCommand(item); } if (state != ZeroOperatorStateType.Ok) { Interlocked.Increment(ref ErrorCount); } else { Interlocked.Increment(ref SuccessCount); } LogRecorder.MonitorTrace(item.Result); if (!SendResult(ref socket, item, state)) { ZeroTrace.WriteError(item.ApiName, "SendResult"); } End(item); } }
void IApiHandler.Prepare(ApiStation station, ApiCallItem item) { count = new CountData { IsInner = true, Start = DateTime.Now.Ticks, Requester = item.Requester, HostName = station.StationName, ApiName = item.ApiName }; }
private void ApiCall(ref ZSocket socket, ApiCallItem item) { ApiContext.SetRequestContext(item.GlobalId, item.Requester, item.RequestId ?? item.GlobalId); item.Handlers = CreateHandlers(); Interlocked.Increment(ref CallCount); if (LogRecorder.LogMonitor) { ApiCallByMonitor(ref socket, item); } else { ApiCallNoMonitor(ref socket, item); } Interlocked.Decrement(ref waitCount); }
void End(ApiCallItem item) { if (item.Handlers == null) { return; } foreach (var p in item.Handlers) { try { p.End(this, item); } catch (Exception e) { ZeroTrace.WriteException(StationName, e, "EndActions", item.ApiName); } } }
private void ApiCallNoMonitor(ref ZSocket socket, ApiCallItem item) { Prepare(item); var state = ExecCommand(item); if (state != ZeroOperatorStateType.Ok) { Interlocked.Increment(ref ErrorCount); } else { Interlocked.Increment(ref SuccessCount); } LogRecorder.MonitorTrace(item.Result); if (!SendResult(ref socket, item, state)) { Interlocked.Increment(ref SendError); ZeroTrace.WriteError(item.ApiName, "SendResult"); } End(item); }
void Prepare(ApiCallItem item) { if (item.RequestId == null) { item.RequestId = item.GlobalId; } if (item.Handlers == null) { return; } foreach (var p in item.Handlers) { try { p.Prepare(this, item); } catch (Exception e) { ZeroTrace.WriteException(StationName, e, "PreActions", item.ApiName); } } }
/// <summary> /// 还原调用上下文 /// </summary> /// <param name="item"></param> /// <returns></returns> private ZeroOperatorStateType RestoryContext(ApiCallItem item) { try { if (!string.IsNullOrWhiteSpace(item.ContextJson)) { GlobalContext.SetContext(JsonConvert.DeserializeObject <ApiContext>(item.ContextJson)); } if (!string.IsNullOrWhiteSpace(item.Content)) { GlobalContext.Current.DependencyObjects.Annex(JsonConvert.DeserializeObject <Dictionary <string, string> >(item.Content)); } GlobalContext.Current.Request.SetValue(item.GlobalId, item.Requester, item.RequestId); return(ZeroOperatorStateType.Ok); } catch (Exception e) { ZeroTrace.WriteException(StationName, e, item.ApiName, "restory context", item.ContextJson); item.Result = ApiResult.ArgumentErrorJson; item.Status = ZeroOperatorStatus.FormalError; return(ZeroOperatorStateType.LocalException); } }
//void ProcessTask(object obj) //{ // Interlocked.Increment(ref ptocessTaskCount); // var socket = ZSocket.CreateClientSocket(Config.WorkerResultAddress, ZSocketType.DEALER); // var pool = ZmqPool.CreateZmqPool(); // pool.Prepare(new[] { ZSocket.CreateClientSocket($"inproc://{StationName}_api.route", ZSocketType.PAIR) }, ZPollEvent.In); // var token = (CancellationToken)obj; // while (!token.IsCancellationRequested && CanRun) // { // //if (!Quote.StartProcess(out var item)) // //{ // // continue; // //} // //ApiCall(ref socket, item); // //Quote.EndProcess(); // if (!pool.Poll() || !pool.CheckIn(0, out var message)) // { // continue; // } // using (message) // { // if (!Unpack(message, out var item)) // { // SendLayoutErrorResult(ref socket, item.Caller, item.Requester); // continue; // } // ApiCall(ref socket, item); // } // } // socket.TryClose(); // if (Interlocked.Decrement(ref ptocessTaskCount) == 0) // _processSemaphore.Release(); //} #endregion #region IO /// <summary> /// 解析数据 /// </summary> /// <param name="messages"></param> /// <param name="item"></param> /// <returns></returns> private bool Unpack(ZMessage messages, out ApiCallItem item) { item = new ApiCallItem { Caller = messages[0].Read() }; try { var description = messages[1].Read(); if (description.Length < 2) { ZeroTrace.WriteError("Receive", "LaoutError", Config.WorkerResultAddress, description.LinkToString(p => p.ToString("X2"), "")); item = null; return(false); } int end = description[0] + 2; if (end != messages.Count) { ZeroTrace.WriteError("Receive", "LaoutError", Config.WorkerResultAddress, $"FrameSize{messages.Count}", description.LinkToString(p => p.ToString("X2"), "")); item = null; return(false); } for (int idx = 2; idx < end; idx++) { var bytes = messages[idx].Read(); if (bytes.Length == 0) { continue; } var val = Encoding.UTF8.GetString(bytes).TrimEnd('\0'); switch (description[idx]) { case ZeroFrameType.GlobalId: item.GlobalId = val; break; case ZeroFrameType.RequestId: item.RequestId = val; break; case ZeroFrameType.Requester: item.Requester = val; break; case ZeroFrameType.Context: item.ContextJson = val; break; case ZeroFrameType.Command: item.ApiName = val; break; case ZeroFrameType.Argument: item.Argument = val; break; case ZeroFrameType.Content: item.Content = val; break; } } return(item.ApiName != null && item.GlobalId != null); } catch (Exception e) { ZeroTrace.WriteException("Receive", e, Config.WorkerResultAddress, $"FrameSize{messages.Count}"); return(false); } finally { messages.Dispose(); } }
/// <summary> /// 执行命令 /// </summary> /// <param name="item"></param> /// <returns></returns> private ZeroOperatorStateType ExecCommand(ApiCallItem item) { //1 查找调用方法 if (!_apiActions.TryGetValue(item.ApiName.Trim(), out var action)) { item.Result = ApiResult.NoFindJson; item.Status = ZeroOperatorStatus.NotFind; return(ZeroOperatorStateType.NotFind); } //2 确定调用方法及对应权限 if (action.NeedLogin && (GlobalContext.Customer == null || GlobalContext.Customer.UserId <= 0)) { item.Result = ApiResult.DenyAccessJson; item.Status = ZeroOperatorStatus.DenyAccess; return(ZeroOperatorStateType.DenyAccess); } //3 参数校验 try { if (!action.RestoreArgument(item.Argument ?? "{}")) { item.Result = ApiResult.ArgumentErrorJson; item.Status = ZeroOperatorStatus.FormalError; return(ZeroOperatorStateType.ArgumentInvalid); } } catch (Exception e) { ZeroTrace.WriteException(StationName, e, item.ApiName, "restory argument", item.Argument); item.Result = ApiResult.LocalExceptionJson; item.Status = ZeroOperatorStatus.FormalError; return(ZeroOperatorStateType.LocalException); } try { if (!action.Validate(out var message)) { item.Result = JsonConvert.SerializeObject(ApiResult.Error(ErrorCode.LogicalError, message)); item.Status = ZeroOperatorStatus.LogicalError; return(ZeroOperatorStateType.ArgumentInvalid); } } catch (Exception e) { ZeroTrace.WriteException(StationName, e, item.ApiName, "invalidate argument", item.Argument); item.Result = ApiResult.LocalExceptionJson; item.Status = ZeroOperatorStatus.LocalException; return(ZeroOperatorStateType.LocalException); } //4 方法执行 try { var result = action.Execute(); if (result != null) { if (result.Status == null) { result.Status = new ApiStatusResult { InnerMessage = item.GlobalId } } ; else { result.Status.InnerMessage = item.GlobalId; } } item.Result = result == null ? ApiResult.SucceesJson : JsonConvert.SerializeObject(result); item.Status = result == null || result.Success ? ZeroOperatorStatus.Success : ZeroOperatorStatus.LogicalError; return(result == null || result.Success ? ZeroOperatorStateType.Ok : ZeroOperatorStateType.Failed); } catch (Exception e) { ZeroTrace.WriteException(StationName, e, item.ApiName, "execute", JsonConvert.SerializeObject(item)); item.Result = ApiResult.LocalExceptionJson; item.Status = ZeroOperatorStatus.LocalException; return(ZeroOperatorStateType.LocalException); } }