public void Create(string route, MethodInfo serverMethodInfo, MethodInfo clientMethodInfo, List <Type> serverInterceptors, List <Type> clientInterceptors) { if (ServiceInvokers.ContainsKey(route)) { throw new DuplicateRouteException(route); } var enableClient = ServiceProvider.GetService <ILoadBalancing>() != null; var serviceDescriptor = new ServiceDescriptor { Route = route, MethodInfo = serverMethodInfo, ArgsType = serverMethodInfo == null ? null : serverMethodInfo.GetParameters().Select(p => p.ParameterType).ToArray(), MethodInvoker = serverMethodInfo == null ? null : new MethodInvoker(serverMethodInfo), ServerInterceptors = serverInterceptors, ClientInterceptors = clientInterceptors }; var nonCircuitBreakerAttr = clientMethodInfo.GetCustomAttribute <NonCircuitBreakerAttribute>(); if (nonCircuitBreakerAttr == null) { var circuitBreakerAttr = clientMethodInfo.GetCustomAttribute <CircuitBreakerAttribute>(); var globalCircuitBreaker = UraganoSettings.CircuitBreakerOptions; if (globalCircuitBreaker != null || circuitBreakerAttr != null) { var breaker = new ServiceCircuitBreakerOptions(); if (globalCircuitBreaker != null) { breaker.Timeout = globalCircuitBreaker.Timeout; breaker.Retry = globalCircuitBreaker.Retry; breaker.ExceptionsAllowedBeforeBreaking = globalCircuitBreaker.ExceptionsAllowedBeforeBreaking; breaker.DurationOfBreak = globalCircuitBreaker.DurationOfBreak; } if (circuitBreakerAttr != null) { if (circuitBreakerAttr.Timeout.HasValue) { breaker.Timeout = circuitBreakerAttr.Timeout.Value; } if (circuitBreakerAttr.Retry.HasValue) { breaker.Retry = circuitBreakerAttr.Retry.Value; } if (circuitBreakerAttr.ExceptionsAllowedBeforeBreaking.HasValue) { breaker.ExceptionsAllowedBeforeBreaking = circuitBreakerAttr.ExceptionsAllowedBeforeBreaking.Value; } if (circuitBreakerAttr.DurationOfBreak.HasValue) { breaker.DurationOfBreak = circuitBreakerAttr.DurationOfBreak.Value; } if (!string.IsNullOrWhiteSpace(circuitBreakerAttr.FallbackExecuteScript)) { breaker.HasInjection = true; if (enableClient) { ScriptInjection.AddScript(route, circuitBreakerAttr.FallbackExecuteScript, circuitBreakerAttr.ScriptUsingNameSpaces); } } } serviceDescriptor.ServiceCircuitBreakerOptions = breaker; } } //Must have a method of returning a value. if (UraganoSettings.CachingOptions != null && clientMethodInfo.ReturnType != typeof(Task)) { if (clientMethodInfo.GetCustomAttribute <NonCachingAttribute>() == null && clientMethodInfo.DeclaringType?.GetCustomAttribute <NonCachingAttribute>() == null) { var attr = clientMethodInfo.GetCustomAttribute <CachingAttribute>(); var keyGenerator = ServiceProvider.GetRequiredService <ICachingKeyGenerator>(); var key = keyGenerator.GenerateKeyPlaceholder(UraganoSettings.CachingOptions.KeyPrefix, UraganoSettings.CachingOptions.ExpireSeconds, route, clientMethodInfo, attr); serviceDescriptor.CachingConfig = new CachingConfig { CustomKey = attr != null && !string.IsNullOrWhiteSpace(attr.Key), KeyPlaceholder = key, ExpireSeconds = string.IsNullOrWhiteSpace(attr?.ExpireSeconds) ? UraganoSettings.CachingOptions.ExpireSeconds : int.Parse(attr.ExpireSeconds) }; } } ServiceInvokers.TryAdd(route, serviceDescriptor); }
public void Create(string route, MethodInfo serverMethodInfo, MethodInfo clientMethodInfo, List <Type> serverInterceptors, List <Type> clientInterceptors) { if (ServiceInvokers.ContainsKey(route)) { throw new DuplicateRouteException(route); } var enableClient = ServiceProvider.GetService <ILoadBalancing>() != null; ServiceCircuitBreakerOptions breaker = null; CachingConfig cachingConfig = null; if (enableClient) { #region Circuit breaker var nonCircuitBreakerAttr = clientMethodInfo.GetCustomAttribute <NonCircuitBreakerAttribute>(); if (nonCircuitBreakerAttr == null) { var circuitBreakerAttr = clientMethodInfo.GetCustomAttribute <CircuitBreakerAttribute>(); var globalCircuitBreaker = UraganoSettings.CircuitBreakerOptions; if (globalCircuitBreaker != null || circuitBreakerAttr != null) { breaker = new ServiceCircuitBreakerOptions(); if (globalCircuitBreaker != null) { breaker.Timeout = globalCircuitBreaker.Timeout; breaker.Retry = globalCircuitBreaker.Retry; breaker.ExceptionsAllowedBeforeBreaking = globalCircuitBreaker.ExceptionsAllowedBeforeBreaking; breaker.DurationOfBreak = globalCircuitBreaker.DurationOfBreak; breaker.MaxParallelization = globalCircuitBreaker.MaxParallelization; breaker.MaxQueuingActions = globalCircuitBreaker.MaxQueuingActions; } if (circuitBreakerAttr != null) { if (circuitBreakerAttr.TimeoutMilliseconds > -1) { breaker.Timeout = TimeSpan.FromMilliseconds(circuitBreakerAttr.TimeoutMilliseconds); } if (circuitBreakerAttr.Retry > -1) { breaker.Retry = circuitBreakerAttr.Retry; } if (circuitBreakerAttr.ExceptionsAllowedBeforeBreaking > -1) { breaker.ExceptionsAllowedBeforeBreaking = circuitBreakerAttr.ExceptionsAllowedBeforeBreaking; } if (circuitBreakerAttr.DurationOfBreakSeconds > -1) { breaker.DurationOfBreak = TimeSpan.FromSeconds(circuitBreakerAttr.DurationOfBreakSeconds); } if (!string.IsNullOrWhiteSpace(circuitBreakerAttr.FallbackExecuteScript)) { breaker.HasInjection = true; ScriptInjection.AddScript(route, circuitBreakerAttr.FallbackExecuteScript, circuitBreakerAttr.ScriptUsingNameSpaces); } if (circuitBreakerAttr.MaxParallelization > -1) { breaker.MaxParallelization = circuitBreakerAttr.MaxParallelization; } if (circuitBreakerAttr.MaxQueuingActions > -1) { breaker.MaxQueuingActions = circuitBreakerAttr.MaxQueuingActions; } } } } #endregion #region Caching //Must have a method of returning a value. if (UraganoSettings.CachingOptions != null && clientMethodInfo.ReturnType != typeof(Task) && clientMethodInfo.GetCustomAttribute <NonCachingAttribute>() == null && clientMethodInfo.DeclaringType?.GetCustomAttribute <NonCachingAttribute>() == null) { var attr = clientMethodInfo.GetCustomAttribute <CachingAttribute>(); var keyGenerator = ServiceProvider.GetRequiredService <ICachingKeyGenerator>(); var key = keyGenerator.GenerateKeyPlaceholder(UraganoSettings.CachingOptions.KeyPrefix, UraganoSettings.CachingOptions.ExpireSeconds, route, clientMethodInfo, attr); cachingConfig = new CachingConfig(key, attr != null && !string.IsNullOrWhiteSpace(attr.Key), attr != null && attr.ExpireSeconds != -1 ? attr.ExpireSeconds : UraganoSettings.CachingOptions.ExpireSeconds); } #endregion } var serviceDescriptor = new ServiceDescriptor(route, serverMethodInfo, clientMethodInfo, serverMethodInfo == null ? null : new MethodInvoker(serverMethodInfo), serverInterceptors, clientInterceptors, breaker, cachingConfig); ServiceInvokers.TryAdd(route, serviceDescriptor); }