public void Init(IDbContextBase context, IQueryable query, CacheInfo cacheInfo)
        {
            CacheInfo = cacheInfo;
            using (var trace = new Trace.TraceDto())
            {
                trace.TraceKey          = "CacheSqlDependency";
                trace.Data["CacheName"] = cacheInfo.Name;
                trace.Data["DateTime"]  = DateTime.Now.ToString();
                trace.Message           = $"CacheSql Dependency {cacheInfo.Name} before init at {DateTime.Now.ToString()} ...";
                trace.Data["State"]     = "initialize";
                Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
            }

            Init(context, query, 500, cacheInfo);

            using (var trace = new Trace.TraceDto())
            {
                trace.TraceKey          = "CacheSqlDependency";
                trace.Data["CacheName"] = cacheInfo.Name;
                trace.Data["DateTime"]  = DateTime.Now.ToString();
                trace.Message           = $"CacheSql Dependency {cacheInfo.Name} was initilized at {DateTime.Now.ToString()} ...";
                trace.Data["State"]     = "initialize";
                Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
            }
        }
        private void DependencyOnChange(object sender, SqlNotificationEventArgs e)
        {
            // Move the original SqlDependency event handler.
            if (e.Type == SqlNotificationType.Subscribe || e.Info == SqlNotificationInfo.Error)
            {
                using (var trace = new Trace.TraceDto())
                {
                    trace.TraceKey          = "CacheSqlDependency";
                    trace.Data["CacheName"] = CacheInfo.Name;
                    trace.Data["DateTime"]  = DateTime.Now.ToString();
                    trace.Message           = $"CacheSql Dependency {CacheInfo.Name} has faced with an Error at {DateTime.Now.ToString()} ...";
                    trace.Data["State"]     = "Error";
                    trace.Data["Type"]      = e.Type.ToString();
                    trace.Data["Info"]      = e.Info.ToString();
                    Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                }

                Core.Cmn.AppBase.LogService.Write($"Some thing is wrong on SqlDependency Change, the query is {iquery} and SqlNotificationInfo is {e.Info} and Source is {e.Source}...");
            }

            dependency.OnChange -= DependencyOnChange;

            if (OnChanged != null)
            {
                try
                {
                    OnChanged(this, e);
                }
                catch (Exception ex)
                {
                    using (var trace = new Trace.TraceDto())
                    {
                        trace.TraceKey          = "CacheSqlDependency";
                        trace.Data["CacheName"] = CacheInfo.Name;
                        trace.Data["DateTime"]  = DateTime.Now.ToString();
                        trace.Message           = $"CacheSql Dependency {CacheInfo.Name} has faced with an exception at {DateTime.Now.ToString()} ...";
                        trace.Data["State"]     = "Error";
                        trace.Data["Exception"] = ex.ToString();
                        trace.Data["Type"]      = e.Type.ToString();
                        trace.Data["Info"]      = e.Info.ToString();
                        Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                    }

                    Core.Cmn.AppBase.LogService.Handle(ex, $"Exception on executing cache on SqlDependency Change, the query is {iquery}...");
                }
            }

            // We re-register the SqlDependency.
            //  RegisterSqlDependency();
        }
예제 #3
0
파일: CacheConfig.cs 프로젝트: Zedfa/Core
        private static void ExcecuteQueryForRefreshingSqlDependencyCache(CacheInfo currentCacheInfo, Type returnCacheType, object queryableCacheExecution, int delay)
        {
            try
            {
                using (var trace = new Trace.TraceDto())
                {
                    trace.TraceKey          = "CacheSqlDependency";
                    trace.Data["CacheName"] = currentCacheInfo.Name;
                    trace.Data["DateTime"]  = DateTime.Now.ToString();
                    trace.Data["State"]     = "ExcecuteQuery";
                    trace.Message           = $"CacheSql Dependency {currentCacheInfo.Name} before ExcecuteQuery at {DateTime.Now.ToString()} ...";
                    Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                }

                (typeof(CacheBase)).GetMethod("RefreshCache").MakeGenericMethod(returnCacheType).Invoke(null, new object[] { queryableCacheExecution, currentCacheInfo });

                using (var trace = new Trace.TraceDto())
                {
                    trace.TraceKey          = "CacheSqlDependency";
                    trace.Data["CacheName"] = currentCacheInfo.Name;
                    trace.Data["DateTime"]  = DateTime.Now.ToString();
                    trace.Data["State"]     = "ExcecuteQuery";
                    trace.Message           = $"CacheSql Dependency {currentCacheInfo.Name} after ExcecuteQuery at {DateTime.Now.ToString()} ...";
                    Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                }
            }
            catch (Exception ex)
            {
                using (var trace = new Trace.TraceDto())
                {
                    trace.TraceKey          = "CacheSqlDependency";
                    trace.Data["CacheName"] = currentCacheInfo.Name;
                    trace.Data["DateTime"]  = DateTime.Now.ToString();
                    trace.Data["State"]     = "ExcecuteQuery";
                    trace.Message           = $"CacheSql Dependency {currentCacheInfo.Name} on ExcecuteQuery has faced with an exception at {DateTime.Now.ToString()} ...";
                    Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                }

                Task.Delay(delay).Wait();
                ((IQueryableCacheDataProvider)queryableCacheExecution).DbContext = AppBase.DependencyInjectionFactory.CreateContextInstance();
                try
                {
                    AppBase.LogService.Handle(ex, $"Exception on excecuting Query for refreshing a DependencySql Cache on {currentCacheInfo.Name}");
                }
                catch
                { }
                ExcecuteQueryForRefreshingSqlDependencyCache(currentCacheInfo, returnCacheType, queryableCacheExecution, delay + 1000);
            }
        }
        private void Init(IDbContextBase context, IQueryable query, int delayForRetryOnError, CacheInfo cacheInfo)
        {
            try
            {
                StartMonitor(context);
                this.iquery = query;

                // Get the ObjectQuery directly or convert the DbQuery to ObjectQuery.
                Core.Cmn.Extensions.QueryableExt.GetSqlCommand <TEntity>(context, query, ref connection, ref command);
                RegisterSqlDependency();
            }
            catch (Exception ex)
            {
                try
                {
                    using (var trace = new Trace.TraceDto())
                    {
                        trace.TraceKey          = "CacheSqlDependency";
                        trace.Data["CacheName"] = cacheInfo.Name;
                        trace.Data["DateTime"]  = DateTime.Now.ToString();
                        trace.Data["Exception"] = ex.ToString();
                        trace.Message           = $"CacheSql Dependency {cacheInfo.Name} has faced with an exception at {DateTime.Now.ToString()} ...";
                        trace.Data["State"]     = "initialize";
                        Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                    }

                    Core.Cmn.AppBase.LogService.Handle(ex, $"Exception on initialize ImmediateNotificationRegister for cache on SqlDependency, the query is {iquery}...");
                }
                catch
                {
                }

                Task.Delay(delayForRetryOnError).Wait();
                Init(context, query, delayForRetryOnError + 1000, cacheInfo);
            }
        }
예제 #5
0
파일: CacheConfig.cs 프로젝트: Zedfa/Core
        private static void BuildCachesInAssembly(Type dBContext, Assembly repAssembly, bool isRepositoryAssembly)
        {
            IEnumerable <MethodInfo> types = null;

            try
            {
                types = repAssembly.GetTypes()
                        .SelectMany(type => type.GetMethods(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic));
            }
            catch
            {
                //This exception is don't care.
                return;
            }

            foreach (var type in types)
            {
                var cacheInfoAtt = type.GetAttributeValue <CacheableAttribute, CacheableAttribute>(cAtt => cAtt);
                if (cacheInfoAtt != null)
                {
                    //if (string.IsNullOrEmpty(cacheInfo.Key))
                    //{
                    //    throw new ArgumentNullException("Cache Key can't be empty.");
                    //}

                    if ((type as MethodInfo).IsStatic)
                    {
                        if (!(type as MethodInfo).IsGenericMethod)
                        {
                            var  methodInfo   = type as MethodInfo;
                            var  parames      = methodInfo.GetParameters();
                            Type funcBaseType = null;
                            if (parames.Count() == 0)
                            {
                                funcBaseType = typeof(Func <>);
                            }
                            if (parames.Count() == 1)
                            {
                                funcBaseType = typeof(Func <,>);
                            }
                            if (parames.Count() == 2)
                            {
                                funcBaseType = typeof(Func <, ,>);
                            }
                            if (parames.Count() == 3)
                            {
                                funcBaseType = typeof(Func <, , ,>);
                            }
                            if (parames.Count() == 4)
                            {
                                funcBaseType = typeof(Func <, , , ,>);
                            }
                            if (parames.Count() == 5)
                            {
                                funcBaseType = typeof(Func <, , , , ,>);
                            }
                            List <Type> tArgs = methodInfo.GetParameters().Select(item => item.ParameterType).ToList();
                            tArgs.Add(methodInfo.ReturnType);
                            var       funcType         = funcBaseType.MakeGenericType(tArgs.ToArray());
                            var       funcInstanc      = methodInfo.CreateDelegate(funcType);
                            var       key              = funcInstanc.Method.GetHashCode().ToString();
                            CacheInfo currentCacheInfo = null;
                            if (!CacheInfoDic.TryGetValue(key, out currentCacheInfo))
                            {
                                // throw new ArgumentException("Duplicate cache key can't be used , please use an unique key for cache.");
                                currentCacheInfo = CreateCacheInfo(cacheInfoAtt, methodInfo, funcInstanc, key);
                            }
                            try
                            {
                                if (typeof(IQueryable).IsAssignableFrom(methodInfo.ReturnType) && parames.Length > 0 && typeof(IQueryable).IsAssignableFrom(parames[0].ParameterType))
                                {
                                    if (!isRepositoryAssembly)
                                    {
                                        throw new NotSupportedException("Queryable Cache just can use in Repository Layer.");
                                    }
                                    var repository = (IRepositoryCache)Activator.CreateInstance(methodInfo.DeclaringType, Activator.CreateInstance(dBContext));
                                    currentCacheInfo.Repository = repository;
                                    if (parames.Length == 1)
                                    {
                                        var    cacheDataProviderType = typeof(QueryableCacheDataProvider <>);
                                        Type[] typeArgs = methodInfo.ReturnType.GenericTypeArguments;
                                        var    cacheDataProviderGenericType = cacheDataProviderType.MakeGenericType(typeArgs);
                                        var    returnCacheType = typeof(List <>).MakeGenericType(methodInfo.ReturnType.GenericTypeArguments[0]);
                                        CacheWCFTypeHelper.typeList.Add(cacheDataProviderGenericType);
                                        CacheWCFTypeHelper.typeList.Add(methodInfo.ReturnType.GenericTypeArguments[0]);
                                        CacheWCFTypeHelper.typeList.Add(returnCacheType);
                                        // if (currentCacheInfo.EnableUseCacheServer)
                                        //      CacheWCFTypeHelper.typeList.Add(methodInfo.ReturnType);
                                        object queryableCacheExecution = Activator.CreateInstance(cacheDataProviderGenericType, new object[] { currentCacheInfo });

                                        if (currentCacheInfo.FrequencyOfBuilding == 0)
                                        {
                                            Stopwatch stopwatch = new Stopwatch();
                                            stopwatch.Start();
                                            if (!cacheInfoAtt.DisableCache)
                                            {
                                                (typeof(CacheBase)).GetMethod("RefreshCache").MakeGenericMethod(returnCacheType).Invoke(null, new object[] { queryableCacheExecution, currentCacheInfo });
                                            }
                                            stopwatch.Stop();
                                            currentCacheInfo.FrequencyOfBuilding += 1;
                                            currentCacheInfo.BuildingTime        += new TimeSpan(stopwatch.ElapsedTicks);
                                        }

                                        if (currentCacheInfo.CacheRefreshingKind == CacheRefreshingKind.Slide)
                                        {
                                            PeriodicTaskFactory p = new PeriodicTaskFactory((pt) =>
                                            {
                                                if (currentCacheInfo.CountOfWaitingThreads < 3)
                                                {
                                                    Stopwatch stopwatch = new Stopwatch();
                                                    stopwatch.Start();
                                                    ((IQueryableCacheDataProvider)queryableCacheExecution).DbContext = AppBase.DependencyInjectionFactory.CreateContextInstance();
                                                    (typeof(CacheBase)).GetMethod("RefreshCache").MakeGenericMethod(returnCacheType).Invoke(null, new object[] { queryableCacheExecution, currentCacheInfo });
                                                    stopwatch.Stop();
                                                    currentCacheInfo.FrequencyOfBuilding += 1;
                                                    currentCacheInfo.BuildingTime        += new TimeSpan(stopwatch.ElapsedTicks);
                                                }
                                            }, new TimeSpan(0, 0, currentCacheInfo.AutoRefreshInterval), new TimeSpan(0, 0, currentCacheInfo.AutoRefreshInterval));

                                            p.Start();
                                        }
                                        else
                                        {
                                            if (currentCacheInfo.CacheRefreshingKind == CacheRefreshingKind.SqlDependency)
                                            {
                                                if (currentCacheInfo.EnableSaveCacheOnHDD && currentCacheInfo.EnableToFetchOnlyChangedDataFromDB)
                                                {
                                                    Stopwatch stopwatch = new Stopwatch();
                                                    stopwatch.Start();
                                                    if (!cacheInfoAtt.DisableCache)
                                                    {
                                                        ((IQueryableCacheDataProvider)queryableCacheExecution).DbContext = AppBase.DependencyInjectionFactory.CreateContextInstance();
                                                        (typeof(CacheBase)).GetMethod("RefreshCache").MakeGenericMethod(returnCacheType).Invoke(null, new object[] { queryableCacheExecution, currentCacheInfo });
                                                    }
                                                    stopwatch.Stop();
                                                    currentCacheInfo.FrequencyOfBuilding += 1;
                                                    currentCacheInfo.BuildingTime        += new TimeSpan(stopwatch.ElapsedTicks);
                                                }

                                                var typeOfSqlNotifier = typeof(IImmediateSqlNotificationRegister <>)
                                                                        .MakeGenericType(currentCacheInfo.Repository.GetDomainModelType());
                                                IImmediateSqlNotificationRegisterBase immediateSqlNotificationRegister = (IImmediateSqlNotificationRegisterBase)
                                                                                                                         AppBase.DependencyInjectionManager.Resolve(typeOfSqlNotifier,
                                                                                                                                                                    new ParameterOverride("context", ((IQueryableCacheDataProvider)queryableCacheExecution).DbContext),
                                                                                                                                                                    new ParameterOverride("query", ((IQueryableCacheDataProvider)queryableCacheExecution).GetQuery()));

                                                using (var trace = new Trace.TraceDto())
                                                {
                                                    trace.TraceKey          = "CacheSqlDependency";
                                                    trace.Data["CacheName"] = currentCacheInfo.Name;
                                                    trace.Data["DateTime"]  = DateTime.Now.ToString();
                                                    trace.Message           = $"CacheSql Dependency {currentCacheInfo.Name} before configouration on startup at {DateTime.Now.ToString()} ...";
                                                    trace.Data["State"]     = "config";
                                                    Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                                                }

                                                immediateSqlNotificationRegister.OnChanged += (object sender, SqlNotificationEventArgs e) =>
                                                {
                                                    if (currentCacheInfo.CountOfWaitingThreads < 3)
                                                    {
                                                        using (var trace = new Trace.TraceDto())
                                                        {
                                                            trace.TraceKey          = "CacheSqlDependency";
                                                            trace.Data["CacheName"] = currentCacheInfo.Name;
                                                            trace.Data["DateTime"]  = DateTime.Now.ToString();
                                                            trace.Message           = $"CacheSql Dependency {currentCacheInfo.Name} before changing at {DateTime.Now.ToString()} ...";
                                                            trace.Data["State"]     = "changing";
                                                            Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                                                        }

                                                        Stopwatch stopwatch = new Stopwatch();
                                                        stopwatch.Start();
                                                        ((IQueryableCacheDataProvider)queryableCacheExecution).DbContext = AppBase.DependencyInjectionFactory.CreateContextInstance();
                                                        immediateSqlNotificationRegister.Init(((IQueryableCacheDataProvider)queryableCacheExecution).DbContext, ((IQueryableCacheDataProvider)queryableCacheExecution).GetQuery(), currentCacheInfo);
                                                        ExcecuteQueryForRefreshingSqlDependencyCache(currentCacheInfo, returnCacheType, queryableCacheExecution, 500);
                                                        stopwatch.Stop();
                                                        currentCacheInfo.FrequencyOfBuilding += 1;
                                                        currentCacheInfo.BuildingTime        += new TimeSpan(stopwatch.ElapsedTicks);
                                                        using (var trace = new Trace.TraceDto())
                                                        {
                                                            trace.TraceKey          = "CacheSqlDependency";
                                                            trace.Data["CacheName"] = currentCacheInfo.Name;
                                                            trace.Data["DateTime"]  = DateTime.Now.ToString();
                                                            trace.Message           = $"CacheSql Dependency {currentCacheInfo.Name} was changed at {DateTime.Now.ToString()} ...";
                                                            trace.Data["State"]     = "changing";
                                                            Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                                                        }
                                                    }
                                                };

                                                using (var trace = new Trace.TraceDto())
                                                {
                                                    trace.TraceKey          = "CacheSqlDependency";
                                                    trace.Data["CacheName"] = currentCacheInfo.Name;
                                                    trace.Data["DateTime"]  = DateTime.Now.ToString();
                                                    trace.Message           = $"CacheSql Dependency {currentCacheInfo.Name} was configured on startup at {DateTime.Now.ToString()} ...";
                                                    trace.Data["State"]     = "config";
                                                    Core.Cmn.AppBase.TraceWriter.SubmitData(trace);
                                                }
                                            }
                                        }
                                    }

                                    if (currentCacheInfo.EnableToFetchOnlyChangedDataFromDB && !currentCacheInfo.DisableToSyncDeletedRecord_JustIfEnableToFetchOnlyChangedDataFromDB)
                                    {
                                        CacheManagementRepository.CreateSqlTriggerForDetectingDeletedRecords(string.Format("{0}.{1}", repository.Schema, repository.TableName), repository.KeyName);
                                    }
                                }
                                else
                                {
                                    if (isRepositoryAssembly)
                                    {
                                        throw new NotSupportedException("Functional Cache just can use in Service Layer.");
                                    }

                                    var Service = (IServiceCache)Activator.CreateInstance(methodInfo.DeclaringType, Activator.CreateInstance(dBContext));
                                    Core.Cmn.AppBase.TraceWriter.SubmitData(new Trace.TraceDto {
                                        Message = $"{currentCacheInfo.Name} BuildCachesInAssembly start..."
                                    });
                                    currentCacheInfo.Service = Service;
                                    Type cacheDataProviderType = null;
                                    if (parames.Length == 0)
                                    {
                                        cacheDataProviderType = typeof(FunctionalCacheDataProvider <>);
                                        var    cacheDataProviderGenericType = AddAndGetCacheDataProviderTypeForSerialization(methodInfo, cacheDataProviderType);
                                        object functionalCacheExecution     = Activator.CreateInstance(cacheDataProviderGenericType, new object[] { currentCacheInfo });
                                        if (currentCacheInfo.FrequencyOfBuilding == 0)
                                        {
                                            Stopwatch stopwatch = new Stopwatch();
                                            stopwatch.Start();
                                            if (!cacheInfoAtt.DisableCache)
                                            {
                                                (typeof(CacheBase)).GetMethod("RefreshCache").MakeGenericMethod(methodInfo.ReturnType).Invoke(null, new object[] { functionalCacheExecution, currentCacheInfo });
                                            }
                                            stopwatch.Stop();
                                            currentCacheInfo.FrequencyOfBuilding += 1;
                                            currentCacheInfo.BuildingTime        += new TimeSpan(stopwatch.ElapsedTicks);
                                        }

                                        if (currentCacheInfo.CacheRefreshingKind == CacheRefreshingKind.Slide)
                                        {
                                            PeriodicTaskFactory p = new PeriodicTaskFactory((pt) =>
                                            {
                                                if (currentCacheInfo.CountOfWaitingThreads < 3)
                                                {
                                                    Stopwatch stopwatch = new Stopwatch();
                                                    stopwatch.Start();
                                                    (typeof(CacheBase)).GetMethod("RefreshCache").MakeGenericMethod(methodInfo.ReturnType).Invoke(null, new object[] { functionalCacheExecution, currentCacheInfo });
                                                    stopwatch.Stop();
                                                    currentCacheInfo.FrequencyOfBuilding += 1;
                                                    currentCacheInfo.BuildingTime        += new TimeSpan(stopwatch.ElapsedTicks);
                                                }
                                            }, new TimeSpan(0, 0, currentCacheInfo.AutoRefreshInterval), new TimeSpan(0, 0, currentCacheInfo.AutoRefreshInterval));

                                            p.Start();
                                        }
                                    }
                                    else
                                    {
                                        if (parames.Length == 1)
                                        {
                                            cacheDataProviderType = typeof(FunctionalCacheDataProvider <,>);
                                        }

                                        if (parames.Length == 2)
                                        {
                                            cacheDataProviderType = typeof(FunctionalCacheDataProvider <, ,>);
                                        }

                                        if (parames.Length == 3)
                                        {
                                            cacheDataProviderType = typeof(FunctionalCacheDataProvider <, , ,>);
                                        }

                                        if (parames.Length == 4)
                                        {
                                            cacheDataProviderType = typeof(FunctionalCacheDataProvider <, , , ,>);
                                        }

                                        if (parames.Length == 5)
                                        {
                                            cacheDataProviderType = typeof(FunctionalCacheDataProvider <, , , , ,>);
                                        }

                                        AddAndGetCacheDataProviderTypeForSerialization(methodInfo, cacheDataProviderType);
                                    }

                                    Core.Cmn.AppBase.TraceWriter.SubmitData(new Trace.TraceDto {
                                        Message = $"{currentCacheInfo.Name} BuildCachesInAssembly done."
                                    });
                                }
                            }
                            catch (Exception exception)
                            {
                                Core.Cmn.AppBase.LogService.Handle(exception, $"{exception.Message}. Cache name: {currentCacheInfo?.Name}");
                                throw;
                            }

                            currentCacheInfo.LastBuildDateTime = DateTime.Now;
                        }
                        else
                        {
                            if (cacheInfoAtt.EnableAutomaticallyAndPeriodicallyRefreshCache)
                            {
                                throw new NotSupportedException($"a generic method can't call automatically for cache.If you want to use generic method set '{nameof(cacheInfoAtt.CacheRefreshingKind)}' = {nameof(CacheRefreshingKind.Slide)} in CacheableAttribute");
                            }
                        }
                    }
                    else
                    {
                        throw new NotSupportedException("Cacheable Attribute can't use on Non static methods, because we can't work on nostatic method for caching.");
                    }
                }
            }
        }