/// <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));
        }
Beispiel #2
0
        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));
        }
Beispiel #4
0
        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);
            }
        }
Beispiel #5
0
 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);
                     }
                 }
             }
         });
     }
 }
Beispiel #6
0
 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);
                     }
                 }
             }
         });
     }
 }
Beispiel #7
0
        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);
        }