/// <summary> /// Adds and configures the consistence services for the consistency. /// </summary> /// <param name="services">The services available in the application.</param> /// <param name="setupAction">An action to configure the <see cref="CapOptions" />.</param> /// <returns>An <see cref="CapBuilder" /> for application services.</returns> public static InitQBuilder AddInitQ(this IServiceCollection services, Action <InitQOptions> setupAction) { if (setupAction == null) { throw new ArgumentNullException(nameof(setupAction)); } var options = new InitQOptions(); setupAction(options); services.Configure(setupAction); services.AddSingleton(typeof(ICacheService), new RedisCacheService(options.ConnectionString)); services.AddHostedService <HostedService>(); foreach (var item in options.ListSubscribe) { services.TryAddSingleton(item); } return(new InitQBuilder(services)); }
public async Task FindInterfaceTypes(IServiceProvider provider, InitQOptions options) { var executorDescriptorList = new List <ConsumerExecutorDescriptor>(); using (var scoped = provider.CreateScope()) { var scopedProvider = scoped.ServiceProvider; var list_service = scopedProvider.GetService <Func <Type, IRedisSubscribe> >(); foreach (var item in options.ListSubscribe) { var consumerServices = list_service(item); var typeInfo = consumerServices.GetType().GetTypeInfo(); if (!typeof(IRedisSubscribe).GetTypeInfo().IsAssignableFrom(typeInfo)) { continue; } executorDescriptorList.AddRange(GetTopicAttributesDescription(typeInfo)); } List <Task> tasks = new List <Task>(); //普通队列任务 tasks.Add(Send(executorDescriptorList.Where(m => m.Attribute.GetType().Name == "SubscribeAttribute"), provider, options)); //延迟队列任务 tasks.Add(SendDelay(executorDescriptorList.Where(m => m.Attribute.GetType().Name == "SubscribeDelayAttribute"), provider, options)); await Task.WhenAll(tasks); } }
/// <summary> /// Adds and configures the consistence services for the consistency. /// </summary> /// <param name="services">The services available in the application.</param> /// <param name="setupAction">An action to configure the <see cref="CapOptions" />.</param> /// <returns>An <see cref="CapBuilder" /> for application services.</returns> public static InitQBuilder AddInitQ(this IServiceCollection services, Action <InitQOptions> setupAction) { if (setupAction == null) { throw new ArgumentNullException(nameof(setupAction)); } var options = new InitQOptions(); setupAction(options); services.Configure(setupAction); // 依赖注入中提取ConnectionMultiplexerd对象,避免再次初始化 var provider = services.BuildServiceProvider(); var redisConn = provider.GetService <ConnectionMultiplexer>(); if (redisConn != null) { services.AddSingleton(typeof(ICacheService), new RedisCacheService(redisConn)); } else { services.AddSingleton(typeof(ICacheService), new RedisCacheService(options.ConnectionString)); } services.AddHostedService <HostedService>(); if (options.ListSubscribe != null) { foreach (var item in options.ListSubscribe) { services.TryAddSingleton(item); } services.AddSingleton(serviceProvider => { Func <Type, IRedisSubscribe> accesor = key => { foreach (var item in options.ListSubscribe) { if (key == item) { return(serviceProvider.GetService(item) as IRedisSubscribe); } } throw new ArgumentException($"不支持的DI Key: {key}"); }; return(accesor); }); } return(new InitQBuilder(services)); }
public void FindInterfaceTypes(IServiceProvider provider, InitQOptions options) { var executorDescriptorList = new List <ConsumerExecutorDescriptor>(); using (var scoped = provider.CreateScope()) { var scopedProvider = scoped.ServiceProvider; var consumerServices = scopedProvider.GetServices <IRedisSubscribe>(); foreach (var service in consumerServices) { var typeInfo = service.GetType().GetTypeInfo(); if (!typeof(IRedisSubscribe).GetTypeInfo().IsAssignableFrom(typeInfo)) { continue; } executorDescriptorList.AddRange(GetTopicAttributesDescription(typeInfo)); } Send(executorDescriptorList, provider, options); } }
private void Send(IEnumerable <ConsumerExecutorDescriptor> ExecutorDescriptorList, IServiceProvider serviceProvider, InitQOptions options) { foreach (var ConsumerExecutorDescriptor in ExecutorDescriptorList) { //线程 Task.Run(() => { using (var scope = serviceProvider.GetRequiredService <IServiceScopeFactory>().CreateScope()) { var publish = ConsumerExecutorDescriptor.Attribute.Name; var provider = scope.ServiceProvider; var obj = ActivatorUtilities.GetServiceOrCreateInstance(provider, ConsumerExecutorDescriptor.ImplTypeInfo); ParameterInfo[] parameterInfos = ConsumerExecutorDescriptor.MethodInfo.GetParameters(); //redis对象 var _redis = scope.ServiceProvider.GetService <ICacheService>(); while (true) { if (options.ShowLog) { Console.WriteLine($"执行方法:{obj.ToString()},key:{publish},执行时间{DateTime.Now}"); } var count = _redis.ListLength(publish); if (count > 0) { //从MQ里获取一条消息 var res = _redis.ListRightPop(publish); //堵塞 Thread.Sleep(options.IntervalTime); Task.Run(() => { if (parameterInfos.Length == 0) { ConsumerExecutorDescriptor.MethodInfo.Invoke(obj, null); } else { object[] parameters = new object[] { res }; ConsumerExecutorDescriptor.MethodInfo.Invoke(obj, parameters); } }); } else { //线程挂起1s Thread.Sleep(options.SuspendTime); } } } }); } }
private async Task Send(IEnumerable <ConsumerExecutorDescriptor> ExecutorDescriptorList, IServiceProvider serviceProvider, InitQOptions options) { foreach (var ConsumerExecutorDescriptor in ExecutorDescriptorList) { //线程 await Task.Run(async() => { using (var scope = serviceProvider.GetRequiredService <IServiceScopeFactory>().CreateScope()) { var publish = ConsumerExecutorDescriptor.Attribute.Name; var provider = scope.ServiceProvider; var obj = ActivatorUtilities.GetServiceOrCreateInstance(provider, ConsumerExecutorDescriptor.ImplTypeInfo); ParameterInfo[] parameterInfos = ConsumerExecutorDescriptor.MethodInfo.GetParameters(); //redis对象 var _redis = scope.ServiceProvider.GetService <ICacheService>(); while (true) { try { if (options.ShowLog) { Console.WriteLine($"执行方法:{obj.ToString()},key:{publish},执行时间{DateTime.Now}"); } var count = await _redis.ListLengthAsync(publish); if (count > 0) { //从MQ里获取一条消息 var res = await _redis.ListRightPopAsync(publish); if (string.IsNullOrEmpty(res)) { continue; } //堵塞 await Task.Delay(options.IntervalTime); try { await Task.Run(async() => { if (parameterInfos.Length == 0) { ConsumerExecutorDescriptor.MethodInfo.Invoke(obj, null); } else { object[] parameters = new object[] { res }; ConsumerExecutorDescriptor.MethodInfo.Invoke(obj, parameters); } }); } catch (Exception ex) { Console.WriteLine(ex.Message); } } else { //线程挂起1s await Task.Delay(options.SuspendTime); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } } }); } }
private async Task SendDelay(IEnumerable <ConsumerExecutorDescriptor> ExecutorDescriptorList, IServiceProvider serviceProvider, InitQOptions options) { List <Task> tasks = new List <Task>(); foreach (var ConsumerExecutorDescriptor in ExecutorDescriptorList) { //线程 tasks.Add(Task.Run(async() => { using (var scope = serviceProvider.GetRequiredService <IServiceScopeFactory>().CreateScope()) { var publish = $"queue:{ConsumerExecutorDescriptor.Attribute.Name}"; var provider = scope.ServiceProvider; var obj = ActivatorUtilities.GetServiceOrCreateInstance(provider, ConsumerExecutorDescriptor.ImplTypeInfo); ParameterInfo[] parameterInfos = ConsumerExecutorDescriptor.MethodInfo.GetParameters(); //redis对象 var _redis = scope.ServiceProvider.GetService <ICacheService>(); //从zset添加到队列(锁) tasks.Add(Task.Run(async() => { while (true) { var keyInfo = "lockZSetTibos"; //锁名称 var token = Guid.NewGuid().ToString("N"); //锁持有者 var coon = await _redis.GetDatabase().LockTakeAsync(keyInfo, token, TimeSpan.FromSeconds(5), CommandFlags.None); if (coon) { try { var dt = DateTime.Now; var arry = await _redis.SortedSetRangeByScoreAsync(ConsumerExecutorDescriptor.Attribute.Name, null, dt); if (arry != null && arry.Length > 0) { foreach (var item in arry) { await _redis.ListLeftPushAsync(publish, item); } //移除zset数据 await _redis.SortedSetRemoveRangeByScoreAsync(ConsumerExecutorDescriptor.Attribute.Name, null, dt); } else { //线程挂起1s await Task.Delay(1000); } } catch (Exception ex) { Console.WriteLine($"执行延迟队列报错:{ex.Message}"); } finally { //释放锁 _redis.GetDatabase().LockRelease(keyInfo, token); } } } })); //消费队列 tasks.Add(Task.Run(async() => { while (true) { try { if (options.ShowLog) { Console.WriteLine($"执行方法:{obj.ToString()},key:{publish},执行时间{DateTime.Now}"); } var count = await _redis.ListLengthAsync(publish); if (count > 0) { //从MQ里获取一条消息 var res = await _redis.ListRightPopAsync(publish); if (string.IsNullOrEmpty(res)) { continue; } //堵塞 await Task.Delay(options.IntervalTime); try { await Task.Run(async() => { if (parameterInfos.Length == 0) { ConsumerExecutorDescriptor.MethodInfo.Invoke(obj, null); } else { object[] parameters = new object[] { res }; ConsumerExecutorDescriptor.MethodInfo.Invoke(obj, parameters); } }); } catch (Exception ex) { Console.WriteLine(ex.Message); } } else { //线程挂起1s await Task.Delay(options.SuspendTime); } } catch (Exception ex) { Console.WriteLine(ex.Message); } } })); } })); } await Task.WhenAll(tasks); }