private static IList <T> Find <T>(this ISearchContext context, By by, bool nocache) where T : WebElement, new() { var filterPredicate = CacheHolder.GetFilterPredicate <T>(); if (filterPredicate == null) { throw new InvalidOperationException("Unable to look for elements of type " + typeof(T)); } Func <IWebElement, T> create = WebElement.Create <T>; IEnumerable <IWebElement> elements; if (by != null) { elements = context.FindElements(by).Where(filterPredicate); } else { var webElement = context as WebElement; by = By.XPath("//*"); if (webElement != null) { by = By.XPath(webElement.GetElementXPath() + "//*"); } elements = context.FindElements(by).Where(filterPredicate); } return(elements.Select(create).ToList()); }
public TValue Set <TValue>(string key, TValue newvalue) { var cacheHolder = new CacheHolder(newvalue, DateTimeOffset.Now.Add(_defaultCacheTime)); _objectCache.AddOrUpdate(key, s => cacheHolder, (s, holder) => cacheHolder); return(newvalue); }
private void UpdateImage(Texture2D t, byte[] data) { Initialize(); Texture ot = null; if (m_ri) { ot = m_ri.texture; m_ri.texture = t; m_ri.enabled = t; if (m_useNativeSize && t) { m_ri.SetNativeSize(); } } else if (m_i) { ot = m_i.sprite ? m_i.sprite.texture : null; var ss = t ? t.ToSprite() : null; m_i.sprite = ss; m_i.enabled = ss; if (m_useNativeSize && ss) { m_i.SetNativeSize(); } } if (ot != t) { if (m_refCache) { m_refCache.refCount--; if (!m_refCache) { m_cached.Remove(m_refCache); } } m_refCache = null; if (m_isWeb && t) { var l = m_image.ToLower(); var cache = m_cached.Find(c => c.url == l); if (cache == null) { cache = CacheHolder.Create(l, t, data); m_cached.Add(cache); } else { cache.refCount++; } m_refCache = cache; } } }
private void OnDestroy() { if (m_refCache) { m_refCache.refCount--; if (!m_refCache) { m_cached.Remove(m_refCache); } } m_i = null; m_ri = null; m_refCache = null; m_onLoaded = null; }
private bool AddToCache(string key, CacheHolder ch) { lock (safe) { if (ReuseControllers) { if (ctrlCache == null) { ctrlCache = new Dictionary <string, CacheHolder>(); } if (!ctrlCache.ContainsKey(key)) { ctrlCache.Add(key, ch); return(true); } } } return(false); }
private void Release(CacheHolder holder, GlobalTableKey gkey) { CacheState cs = global.GetOrAdd(gkey, (tabkeKeyNotUsed) => new CacheState()); lock (cs) { if (cs.Modify == holder) { cs.Modify = null; } cs.Share.Remove(holder); // always try remove if (cs.Modify == null && cs.Share.Count == 0 && cs.AcquireStatePending == StateInvalid) { // 安全的从global中删除,没有并发问题。 cs.AcquireStatePending = StateRemoved; global.TryRemove(gkey, out var _); } holder.Acquired.TryRemove(gkey, out var _); } }
public override void Render(Graphics g, IMapViewPort map) { try { _shapeFile.Open(); var ds = new FeatureDataSet(); _shapeFile.ExecuteIntersectionQuery(map.Envelope, ds); var dt = ds.Tables[0]; foreach (FeatureDataRow fdr in dt.Rows) { if (fdr.Geometry.EnvelopeInternal.Intersects(map.Envelope)) { var file = fdr[_fieldName] as string; if (!Path.IsPathRooted(file)) { file = Path.Combine(Path.GetDirectoryName(_fileName), file); } if (file == null) { continue; } if (_logger.IsDebugEnabled) { _logger.Debug("Drawing " + file); } if (!_openDatasets.ContainsKey(file)) { OpenDataset(file); _openDatasets.Add(file, new CacheHolder() { Bands = Bands, Dataset = _gdalDataset, Envelope = _envelope, HistoBounds = HistoBounds, ImageSize = _imageSize, Projection = Projection }); } else { CacheHolder hld = _openDatasets[file]; Bands = hld.Bands; _gdalDataset = hld.Dataset; _envelope = hld.Envelope; HistoBounds = hld.HistoBounds; _imageSize = hld.ImageSize; Projection = hld.Projection; } base.Render(g, map); _envelope = null; _gdalDataset = null; } } } catch (Exception) { _shapeFile.Close(); } }
private int AcquireModify(Acquire rpc) { CacheHolder sender = (CacheHolder)rpc.Sender.UserState; rpc.Result = rpc.Argument; while (true) { CacheState cs = global.GetOrAdd(rpc.Argument.GlobalTableKey, (tabkeKeyNotUsed) => new CacheState()); lock (cs) { if (cs.AcquireStatePending == StateRemoved) { continue; } while (cs.AcquireStatePending != StateInvalid) { switch (cs.AcquireStatePending) { case StateShare: if (cs.Modify == sender) { logger.Debug("1 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateInvalid; rpc.SendResultCode(AcquireModifyDeadLockFound); return(0); } break; case StateModify: if (cs.Modify == sender || cs.Share.Contains(sender)) { logger.Debug("2 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateInvalid; rpc.SendResultCode(AcquireModifyDeadLockFound); return(0); } break; } logger.Debug("3 {0} {1} {2}", sender, rpc.Argument.State, cs); Monitor.Wait(cs); } cs.AcquireStatePending = StateModify; if (cs.Modify != null) { if (cs.Modify == sender) { logger.Debug("4 {0} {1} {2}", sender, rpc.Argument.State, cs); // 已经是Modify又申请,可能是sender异常关闭,又重启连上。 // 更新一下。应该是不需要的。 sender.Acquired[rpc.Argument.GlobalTableKey] = StateModify; rpc.SendResultCode(AcquireModifyAlreadyIsModify); cs.AcquireStatePending = StateInvalid; return(0); } int stateReduceResult = StateReduceException; Zeze.Util.Task.Run( () => { stateReduceResult = cs.Modify.Reduce(rpc.Argument.GlobalTableKey, StateInvalid); lock (cs) { Monitor.PulseAll(cs); } }, "GlobalCacheManager.AcquireModify.Reduce"); logger.Debug("5 {0} {1} {2}", sender, rpc.Argument.State, cs); Monitor.Wait(cs); switch (stateReduceResult) { case StateInvalid: cs.Modify.Acquired.TryRemove(rpc.Argument.GlobalTableKey, out var _); break; // reduce success default: // case StateReduceRpcTimeout: // case StateReduceException: // case StateReduceNetError: cs.AcquireStatePending = StateInvalid; Monitor.Pulse(cs); logger.Error("XXX 9 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateInvalid; rpc.SendResultCode(AcquireModifyFaild); return(0); } cs.Modify = sender; sender.Acquired[rpc.Argument.GlobalTableKey] = StateModify; cs.AcquireStatePending = StateInvalid; Monitor.Pulse(cs); logger.Debug("6 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.SendResult(); return(0); } List <Util.KV <CacheHolder, Reduce> > reducePending = new List <Util.KV <CacheHolder, Reduce> >(); HashSet <CacheHolder> reduceSuccessed = new HashSet <CacheHolder>(); bool senderIsShare = false; // 先把降级请求全部发送给出去。 foreach (CacheHolder c in cs.Share) { if (c == sender) { senderIsShare = true; reduceSuccessed.Add(sender); continue; } Reduce reduce = c.ReduceWaitLater(rpc.Argument.GlobalTableKey, StateInvalid); if (null != reduce) { reducePending.Add(Util.KV.Create(c, reduce)); } else { // 网络错误不再认为成功。整个降级失败,要中断降级。 // 已经发出去的降级请求要等待并处理结果。后面处理。 break; } } Zeze.Util.Task.Run( () => { // 一个个等待是否成功。WaitAll 碰到错误不知道怎么处理的, // 应该也会等待所有任务结束(包括错误)。 foreach (var reduce in reducePending) { try { reduce.Value.Future.Task.Wait(); if (reduce.Value.Result.State == StateInvalid) { // 后面还有个成功的处理循环,但是那里可能包含sender, // 在这里更新吧。 reduce.Key.Acquired.TryRemove(rpc.Argument.GlobalTableKey, out var _); reduceSuccessed.Add(reduce.Key); } else { reduce.Key.SetError(); } } catch (Exception ex) { reduce.Key.SetError(); // 等待失败不再看作成功。 logger.Error(ex, "Reduce {0} {1} {2} {3}", sender, rpc.Argument.State, cs, reduce.Value.Argument); } } lock (cs) { // 需要唤醒等待任务结束的,但没法指定,只能全部唤醒。 Monitor.PulseAll(cs); } }, "GlobalCacheManager.AcquireModify.WaitReduce"); logger.Debug("7 {0} {1} {2}", sender, rpc.Argument.State, cs); Monitor.Wait(cs); // 移除成功的。 foreach (CacheHolder successed in reduceSuccessed) { cs.Share.Remove(successed); } // 如果前面降级发生中断(break),这里就不会为0。 if (cs.Share.Count == 0) { cs.Modify = sender; sender.Acquired[rpc.Argument.GlobalTableKey] = StateModify; cs.AcquireStatePending = StateInvalid; Monitor.Pulse(cs); // Pending 结束,唤醒一个进来就可以了。 logger.Debug("8 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.SendResult(); } else { // senderIsShare 在失败的时候,Acquired 没有变化,不需要更新。 // 失败了,要把原来是share的sender恢复。先这样吧。 if (senderIsShare) { cs.Share.Add(sender); } cs.AcquireStatePending = StateInvalid; Monitor.Pulse(cs); // Pending 结束,唤醒一个进来就可以了。 logger.Error("XXX 10 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateInvalid; rpc.SendResultCode(AcquireModifyFaild); } // 很好,网络失败不再看成成功,发现除了加break, // 其他处理已经能包容这个改动,都不用动。 return(0); } } }
private int AcquireShare(Acquire rpc) { CacheHolder sender = (CacheHolder)rpc.Sender.UserState; rpc.Result = rpc.Argument; while (true) { CacheState cs = global.GetOrAdd(rpc.Argument.GlobalTableKey, (tabkeKeyNotUsed) => new CacheState()); lock (cs) { if (cs.AcquireStatePending == StateRemoved) { continue; } while (cs.AcquireStatePending != StateInvalid) { switch (cs.AcquireStatePending) { case StateShare: if (cs.Modify == sender) { logger.Debug("1 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateInvalid; rpc.SendResultCode(AcquireShareDeadLockFound); return(0); } break; case StateModify: if (cs.Modify == sender || cs.Share.Contains(sender)) { logger.Debug("2 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateInvalid; rpc.SendResultCode(AcquireShareDeadLockFound); return(0); } break; } logger.Debug("3 {0} {1} {2}", sender, rpc.Argument.State, cs); Monitor.Wait(cs); } cs.AcquireStatePending = StateShare; if (cs.Modify != null) { if (cs.Modify == sender) { cs.AcquireStatePending = StateInvalid; logger.Debug("4 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateModify; // 已经是Modify又申请,可能是sender异常关闭, // 又重启连上。更新一下。应该是不需要的。 sender.Acquired[rpc.Argument.GlobalTableKey] = StateModify; rpc.SendResultCode(AcquireShareAlreadyIsModify); return(0); } int stateReduceResult = StateReduceException; Zeze.Util.Task.Run( () => { stateReduceResult = cs.Modify.Reduce(rpc.Argument.GlobalTableKey, StateShare); lock (cs) { Monitor.PulseAll(cs); } }, "GlobalCacheManager.AcquireShare.Reduce"); logger.Debug("5 {0} {1} {2}", sender, rpc.Argument.State, cs); Monitor.Wait(cs); switch (stateReduceResult) { case StateShare: cs.Modify.Acquired[rpc.Argument.GlobalTableKey] = StateShare; cs.Share.Add(cs.Modify); // 降级成功,有可能降到 Invalid,此时就不需要加入 Share 了。 break; default: // 包含协议返回错误的值的情况。 // case StateReduceRpcTimeout: // case StateReduceException: // case StateReduceNetError: cs.AcquireStatePending = StateInvalid; Monitor.Pulse(cs); logger.Error("XXX 8 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.Result.State = StateInvalid; rpc.SendResultCode(AcquireShareFaild); return(0); } cs.Modify = null; sender.Acquired[rpc.Argument.GlobalTableKey] = StateShare; cs.Share.Add(sender); cs.AcquireStatePending = StateInvalid; Monitor.Pulse(cs); logger.Debug("6 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.SendResult(); return(0); } sender.Acquired[rpc.Argument.GlobalTableKey] = StateShare; cs.Share.Add(sender); cs.AcquireStatePending = StateInvalid; logger.Debug("7 {0} {1} {2}", sender, rpc.Argument.State, cs); rpc.SendResult(); return(0); } } }
private bool InvokeActionInternal(HttpContext ctx, string controller, string action, object[] parameters, string[] prefix) { string[] pref = prefix; if (pref == null) { string[] segments = GetSegments(ctx.Request); if (segments == null) { pref = new string[0]; } else { int n = segments.Length - 2; // Number of prefix segments; pref = new string[n]; Array.Copy(segments, pref, n); } } Namespace nsOverride = null; if (!OnValidatePrefix(pref, ref nsOverride)) { return(false); // Prefix segment validation failed; } Type t = FindControllerType(controller, nsOverride); // Locating the controller's Type; if (t == null) { return(false); // Controller's Type not found; } MethodInfo info = t.GetMethod(action, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.InvokeMethod); if (info == null) { return(false); // Action not found; } object[] prm = parameters; if (prm == null) { prm = PrepareActionParameters(info.GetParameters(), ctx.Request.QueryString); if (prm == null) { return(false); } } string signature = t.Module.Name + "/" + t.FullName; // Unique signature of assembly+namespace+controller; CacheHolder ch = GetFromCache(signature); if (ch == null) { ch = new CacheHolder(); } if (ch.instance == null) { ch.instance = Activator.CreateInstance(t); } ch.lastUse = DateTime.Now; BindingFlags flags = BindingFlags.SetProperty | BindingFlags.NonPublic | BindingFlags.Instance; t.InvokeMember("ctx", flags, null, ch.instance, new[] { ctx }); t.InvokeMember("prefix", flags, null, ch.instance, new[] { pref }); try { info.Invoke(ch.instance, prm); } catch (Exception ex) { if (OnActionException != null) { string a = info.ReflectedType.FullName + "." + info.Name; OnActionException(ctx, a, ex); } } AddToCache(signature, ch); return(true); }
private static PageDescriptionAttribute TryGetPageDescriptionAttribute <T>() { return(CacheHolder.TryGetPageDescriptionAttribute(typeof(T))); }
private static PageDescriptionAttribute TryGetPageDescriptionAttribute(Type t) { return(CacheHolder.TryGetPageDescriptionAttribute(t)); }
private static PageDescriptionAttribute TryGetPageDescriptionAttribute(Assembly containingAssembly, string pageTitle) { return(CacheHolder.TryGetPageDescriptionAttribute(containingAssembly, pageTitle)); }
/// <summary> /// Core implementation of locating and invoking an action. /// </summary> /// <param name="ctx">current HTTP request object</param> /// <param name="controller">controller name</param> /// <param name="action">action name</param> /// <param name="parameters">action parameters</param> /// <param name="prefix">prefix segments</param> /// <returns>true, if action was located and invoked</returns> private bool InvokeActionInternal(HttpContext ctx, string controller, string action, object[] parameters, string[] prefix) { string[] pref = prefix; if (pref == null) { string[] segments = GetSegments(ctx.Request); if (segments == null) { pref = new string[0]; } else { int n = segments.Length - 2; // Number of prefix segments; pref = new string[n]; Array.Copy(segments, pref, n); } } Namespace nsOverride = null; if (!OnValidatePrefix(pref, ref nsOverride)) { return(false); // Prefix segment validation failed; } Type t = FindControllerType(controller, nsOverride); // Locating the controller's Type; if (t == null) { return(false); // Controller's Type not found; } // Locating the action method (only public, non-static methods within the class itself, ignoring the name case) MethodInfo info = t.GetMethod(action, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.InvokeMethod); if (info == null) { return(false); // Action not found; } // Preparing collection of parameters for the action... object[] prm = parameters; if (prm == null) { prm = PrepareActionParameters(info.GetParameters(), ctx.Request.QueryString); if (prm == null) { return(false); // Failed to get the expected parameters; } } string signature = t.Module.Name + "/" + t.FullName; // Unique signature of assembly+namespace+controller; CacheHolder ch = GetFromCache(signature); // Try getting details from cache; if (ch == null) { ch = new CacheHolder(); } if (ch.instance == null) { ch.instance = Activator.CreateInstance(t); // Creating new instance of the controller class; } ch.lastUse = DateTime.Now; // last use of the controller; // Updating protected properties in BaseController indirectly... BindingFlags flags = BindingFlags.SetProperty | BindingFlags.NonPublic | BindingFlags.Instance; t.InvokeMember("ctx", flags, null, ch.instance, new[] { ctx }); t.InvokeMember("prefix", flags, null, ch.instance, new[] { pref }); try { info.Invoke(ch.instance, prm); // Invoking the target action; } catch (Exception ex) { if (OnActionException != null) { string a = info.ReflectedType.FullName + "." + info.Name; // Fully-qualified name of the action method; OnActionException(ctx, a, ex); // Trigger event; } } AddToCache(signature, ch); // Adding details to the cache; return(true); // Action was located and invoked; }