static async Task PollyTest() { var atr = new CRL.Core.Remoting.PollyAttribute(); //atr.TimeOutTime = TimeSpan.FromMilliseconds(100); atr.CircuitBreakerCount = 2; atr.RetryCount = 1; var pollyCtx = new Polly.Context(); var response = await PollyExtension.InvokeAsync <string>(atr, async() => { //await Task.Delay(200); throw new Exception("has error"); return(await Task.FromResult(new CRL.Core.Remoting.PollyExtension.PollyData <string>() { Data = "ok" })); }, ""); if (pollyCtx.ContainsKey("msg")) { Console.WriteLine(pollyCtx["msg"]); } //var str = PollyExtension.Invoke(atr, () => // { // throw new Exception("has error"); // //System.Threading.Thread.Sleep(200); // return new PollyExtension.PollyData<string>() { Error = "ok" }; // }, "test"); Console.WriteLine(response.ToJson()); }
protected virtual CallInvocationDetails <TRequest, TResponse> CreateCall <TRequest, TResponse>(Method <TRequest, TResponse> method, string host, CallOptions options) where TRequest : class where TResponse : class { var methodName = $"{method.ServiceName}.{method.Name}"; var key = methodName.Substring(methodName.IndexOf(".") + 1).ToLower(); var a = _options.MethodPolicies.TryGetValue(key, out PollyAttribute methodPollyAttr); if (!a) { _options.MethodPolicies.TryGetValue("", out methodPollyAttr); } CallOptions options2; //重写header if (options.Headers != null) { options2 = options; } else { options2 = new CallOptions(_grpcConnect.GetMetadata(), options.Deadline, options.CancellationToken); } var pollyData = PollyExtension.Invoke(methodPollyAttr, () => { var callRes = new CallInvocationDetails <TRequest, TResponse>(_grpcConnect.GetChannel(), method, host, options2); return(new PollyExtension.PollyData <CallInvocationDetails <TRequest, TResponse> >() { Data = callRes }); }, $"{methodName}"); var response = pollyData.Data; if (!string.IsNullOrEmpty(pollyData.Error)) { throw new Exception(pollyData.Error); } return(response); //return new CallInvocationDetails<TRequest, TResponse>(Channel.Invoke(), method, host, options2); }
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { try { if (channel == null || !channel.Open) { channel = Core.AsyncInvoke.RunSync(() => bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(HostAddress.address), HostAddress.port))); //channel = bootstrap.ConnectAsync(new IPEndPoint(IPAddress.Parse(HostAddress.address), HostAddress.port)).Result; } } catch (Exception ero) { ThrowError("连接服务端失败:" + ero, "500"); } var id = Guid.NewGuid().ToString(); var method = ServiceType.GetMethod(binder.Name); allWaits.Add(id); var request = new RequestMessage { MsgId = id, Service = ServiceName, Method = binder.Name, //Token = clientConnect.Token.Token }; var dic = new List <byte[]>(); var allArgs = method.GetParameters(); for (int i = 0; i < allArgs.Length; i++) { var p = allArgs[i]; dic.Add(Core.BinaryFormat.FieldFormat.Pack(p.ParameterType, args[i])); } request.Args = dic; var token = request.Token; request.Token = CreateAccessToken(allArgs, args.ToList(), clientConnect.TokenInfo); var pollyAttr = serviceInfo.GetAttribute <PollyAttribute>(); ResponseMessage response = null; var pollyData = PollyExtension.Invoke(pollyAttr, () => { channel.WriteAndFlushAsync(request.ToBuffer()); //等待返回 var res = allWaits.Wait(id).Response; return(new PollyExtension.PollyData <ResponseMessage>() { Data = res }); }, $"{ServiceName}.{method.Name}"); response = pollyData.Data; if (!string.IsNullOrEmpty(pollyData.Error)) { ThrowError(pollyData.Error, "500"); } if (response == null) { ThrowError("请求超时未响应", "500"); } if (!response.Success) { ThrowError($"服务端处理错误:{response.Msg}", response.GetData(typeof(string)) + ""); } var returnType = method.ReturnType; if (response.Outs != null && response.Outs.Count > 0) { foreach (var kv in response.Outs) { var index = kv.Key; var type = allArgs[index]; //args[(int)find] = kv.Value; int offSet = 0; args[index] = Core.BinaryFormat.FieldFormat.UnPack(type.ParameterType, kv.Value, ref offSet); } } if (!string.IsNullOrEmpty(response.Token)) { clientConnect.TokenInfo.Token = response.Token; } if (returnType == typeof(void)) { result = null; return(true); } var generType = returnType; bool isTask = false; if (returnType.Name.StartsWith("Task`1")) { generType = returnType.GenericTypeArguments[0]; isTask = true; } result = response.GetData(generType); if (isTask) { //返回Task类型 var method2 = typeof(Task).GetMethod("FromResult", BindingFlags.Public | BindingFlags.Static); var result2 = method2.MakeGenericMethod(new Type[] { generType }).Invoke(null, new object[] { result }); result = result2; } return(true); }