/// <summary> /// Fetches an existing item from cache or null. IsAbsent is true when data was read from cache as an AbsentValue /// </summary> /// <typeparam name="TKey">Type of key</typeparam> /// <typeparam name="TResult">Type of the returned result value</typeparam> /// <param name="cache">Cache instance to operate on</param> /// <param name="key">Key to read</param> /// <param name="tblCache">Name of a cache table within a cache</param> /// <param name="caching">Caching options, or null for defaults</param> /// <param name="isAbsent">Returns true when value was found, but it is an AbsentValue instance</param> /// <returns>Cached reference type value, or null if not found or absent</returns> public static TResult FetchFrom <TKey, TResult>(this ICache cache, TKey key, string tblCache, ICacheParams caching, out bool isAbsent) where TResult : class { cache.NonNull(nameof(cache)); if (caching == null) { caching = CacheParams.DefaultCache; } TResult result = null; isAbsent = false; if (caching.ReadCacheMaxAgeSec >= 0) { ICacheTable <TKey> tbl = cache.GetOrCreateTable <TKey>(tblCache); var cached = tbl.Get(key, caching.ReadCacheMaxAgeSec); isAbsent = cached is AbsentValue; if (!isAbsent) { result = cached as TResult; } } return(result); }
/// <summary> /// Saves an item through cache: call the `fSave` functor synchronously then saves the result into cache table /// </summary> /// <typeparam name="TKey">Type of key</typeparam> /// <typeparam name="TData">Type of reference type value to save</typeparam> /// <typeparam name="TSaveResult">Type of save result</typeparam> /// <param name="cache">Cache to operate on</param> /// <param name="key">Key value</param> /// <param name="data">Reference type value to save. May not be null or AbsentValue</param> /// <param name="tblCache">The name of a cache table</param> /// <param name="caching">Caching options, or null for default</param> /// <param name="fSave">Synchronous functor that performs backend save</param> /// <returns>A result of the call to `fSave` functor</returns> public static TSaveResult SaveThrough <TKey, TData, TSaveResult>(this ICache cache, TKey key, TData data, string tblCache, ICacheParams caching, Func <TKey, TData, TSaveResult> fSave) where TData : class { cache.NonNull(nameof(cache)); if (data == null || data is AbsentValue) { throw new DataAccessException(StringConsts.ARGUMENT_ERROR + "{0}(data ==null || is AbsentValue)".Args(nameof(SaveThrough))); } if (caching == null) { caching = CacheParams.DefaultCache; } var result = fSave.NonNull(nameof(fSave))(key, data); var wAge = caching.WriteCacheMaxAgeSec; if (wAge >= 0) { var tbl = cache.GetOrCreateTable <TKey>(tblCache); tbl.Put(key, data, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); } return(result); }
/// <summary> /// Assigns caching parameters to this query from anotherICacheParams /// </summary> public void AssignCaching(ICacheParams cache) { if (cache == null) { return; } ReadCacheMaxAgeSec = cache.ReadCacheMaxAgeSec; WriteCacheMaxAgeSec = cache.WriteCacheMaxAgeSec; WriteCachePriority = cache.WriteCachePriority; CacheAbsentData = cache.CacheAbsentData; }
protected virtual GraphNode DoGetNode(GDID gNode, ICacheParams cacheParams = null) { var row = Cache.FetchThrough(gNode, SocialConsts.GS_NODE_TBL, cacheParams, gdid => loadNodeRow(gNode)); if (row == null) { return(new GraphNode()); } return(new GraphNode(row.Node_Type, row.GDID, row.G_OriginShard, row.G_Origin, row.Origin_Name, row.Origin_Data, row.Create_Date.Value, GSFriendVisibility.ToFriendVisibility(row.Friend_Visibility))); }
/// <inheritdoc/> public async Task <IEnumerable <TreeNodeHeader> > GetChildNodeListAsync(EntityId idParent, DateTime?asOfUtc = null, ICacheParams cache = null) { //permission checks are performed in the child traverse loop down below var gop = GdidOrPath.OfGNodeOrPath(idParent); var asof = DefaultAndAlignOnPolicyBoundary(asOfUtc, idParent); if (cache == null) { cache = CacheParams.DefaultCache; } IEnumerable <TreeNodeHeader> result; if (gop.PathAddress != null) { result = await getChildNodeListByTreePath(gop.Tree, gop.PathAddress, asof, cache).ConfigureAwait(false); } else { result = await getChildNodeListByGdid(gop.Tree, gop.GdidAddress, asof, cache).ConfigureAwait(false); } return(result); }
IEnumerable <string> GetFileNames(ICacheParams caching = null) { return(null); }
public static bool DeleteThrough <TKey>(this ICache cache, TKey key, string tblCache, ICacheParams caching, Func <TKey, bool> fDelete) { if (caching == null) { caching = CacheParams.DefaultCache; } var wAge = caching.WriteCacheMaxAgeSec; var tbl = cache.GetOrCreateTable <TKey>(tblCache); if (caching.CacheAbsentData && wAge >= 0) { tbl.Put(key, AbsentValue.Instance, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); } else { tbl.Remove(key); } return(fDelete(key)); }
public static int SaveThrough <TKey, TData>(this ICache cache, TKey key, TData data, string tblCache, ICacheParams caching, Func <TKey, TData, int> fSave) where TData : class { if (data == null) { return(0); } if (caching == null) { caching = CacheParams.DefaultCache; } var result = fSave(key, data); var wAge = caching.WriteCacheMaxAgeSec; if (wAge >= 0) { var tbl = cache.GetOrCreateTable <TKey>(tblCache); tbl.Put(key, data, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); } return(result); }
/// <summary> /// Asynchronously fetches an item through cache - if the item exists and satisfies the `ICacheParams` (and optional `fFilter` functor) then it is /// immediately (synchronously) returned to the caller. Otherwise, calls the `fFetch` async functor to perform the actual fetch of a value by key, /// and then puts the result in cache according to `ICacheParams` /// </summary> /// <typeparam name="TKey">Type of key</typeparam> /// <typeparam name="TResult">Type of the result value</typeparam> /// <param name="cache">Non-null ICache instance to operate on</param> /// <param name="key">Key value</param> /// <param name="tblCache">Name of cache table</param> /// <param name="caching">Caching options, or null for defaults</param> /// <param name="fFetch">Required async functor that performs actual fetch when the value is NOT found in cache</param> /// <param name="fFilter">Optional functor - additional filter applied to existing values</param> /// <returns>Cached reference type value, or null if not found or absent</returns> public static async Task <TResult> FetchThroughAsync <TKey, TResult>(this ICache cache, TKey key, string tblCache, ICacheParams caching, Func <TKey, Task <TResult> > fFetch, Func <TKey, TResult, TResult> fFilter = null) where TResult : class { cache.NonNull(nameof(cache)); ICacheTable <TKey> tbl = null; if (caching == null) { caching = CacheParams.DefaultCache; } if (caching.ReadCacheMaxAgeSec >= 0 || caching.WriteCacheMaxAgeSec >= 0) { tbl = cache.GetOrCreateTable <TKey>(tblCache); } TResult result = null; if (caching.ReadCacheMaxAgeSec >= 0) { var cached = tbl.Get(key, caching.ReadCacheMaxAgeSec); if (cached is AbsentValue) { return(null); } else { result = cached as TResult; } if (fFilter != null) { result = fFilter(key, result); } } if (result != null) { return(result); } result = await fFetch.NonNull(nameof(fFetch))(key);//<-- only fFetch is IO-bound hence asynchronous if (result == null && !caching.CacheAbsentData) { return(null); } var wAge = caching.WriteCacheMaxAgeSec; if (wAge >= 0) { tbl.Put(key, (object)result ?? AbsentValue.Instance, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); } return(result); }
/// <summary> /// Implements <see cref="ICmsSource.FetchContentAsync(ContentId, string, DateTime, ICacheParams)"/> /// </summary> public async Task <Content> FetchContentAsync(ContentId id, string isoLang, DateTime utcNow, ICacheParams caching) { ensureOperationalState(); var appliedIsoLang = ComponentDirector.DefaultGlobalLanguage.ISO; //in future this can be moved to property per portal if (isoLang.IsNullOrWhiteSpace()) { isoLang = appliedIsoLang; } var dirPath = m_FS.CombinePaths(m_FSRootPath, id.Portal, id.Namespace); using (var session = m_FS.StartSession(m_FSConnectParams)) { var dir = await session.GetItemAsync(dirPath) as FileSystemDirectory; if (dir == null) { return(null); //directory not found } //1st try to get language-specific file var(fname, fext) = getFileNameWithLangIso(id.Block, isoLang); var actualIsoLang = isoLang; var file = await dir.GetFileAsync(fname); //2nd try to get language-agnostic file if (file == null) { fname = id.Block;//without the language file = await dir.GetFileAsync(fname); } else { appliedIsoLang = isoLang; } if (file == null) { return(null); //file not found } var ctp = App.GetContentTypeMappings().MapFileExtension(fext); byte[] binContent = null; string txtContent = null; if (ctp.IsBinary) { using (var ms = new MemoryStream()) using (var stream = file.FileStream) { await stream.CopyToAsync(ms); binContent = ms.ToArray(); } } else { txtContent = await file.ReadAllTextAsync(); } var createUser = m_FS.InstanceCapabilities.SupportsCreationUserNames ? file.CreationUser.Name : null; var modifyUser = m_FS.InstanceCapabilities.SupportsModificationUserNames ? file.ModificationUser.Name : null; var createDate = m_FS.InstanceCapabilities.SupportsCreationTimestamps ? file.CreationTimestamp : null; var modifyDate = m_FS.InstanceCapabilities.SupportsModificationTimestamps ? file.ModificationTimestamp : null; var result = new Content(id, ctp.Name, txtContent, binContent, ctp.ContentType, new LangInfo(appliedIsoLang, appliedIsoLang), attachmentFileName: id.Block, createUser: createUser, modifyUser: modifyUser, createDate: createDate, modifyDate: modifyDate); return(result); } }
/// <summary> /// Implements <see cref="ICmsFacade.GetContentAsync(ContentId, Atom?, ICacheParams)"/> /// </summary> public async Task <Content> GetContentAsync(ContentId id, Atom?isoLang = null, ICacheParams caching = null) { if (!id.IsAssigned) { throw new CmsException($"{StringConsts.ARGUMENT_ERROR} {nameof(CmsFacade)}.{nameof(GetContentAsync)}(!id.IsAssigned)"); } if (!isoLang.HasValue || isoLang.Value.IsZero) { isoLang = this.DefaultGlobalLanguage.ISO; } if (caching == null) { caching = getEffectiveCaching(); } if (InstrumentationEnabled) { m_stat_RequestCount.IncrementLong(Datum.UNSPECIFIED_SOURCE); m_stat_RequestCount.IncrementLong($"{id.Portal}:${isoLang}"); } var now = App.TimeSource.UTCNow; var existing = tryLookupExisting(id, isoLang.Value, now, caching); if (existing != null) { if (InstrumentationEnabled) { Interlocked.Increment(ref m_stat_CacheHitCount); m_stat_ResponseCount.IncrementLong(Datum.UNSPECIFIED_SOURCE); m_stat_ResponseCount.IncrementLong($"{id.Portal}:${isoLang}"); } return(existing); } if (InstrumentationEnabled) { Interlocked.Increment(ref m_stat_CacheMissCount); } var fetched = await fetchAndCacheContent(id, isoLang.Value, now, caching).ConfigureAwait(false); if (InstrumentationEnabled && fetched != null) { m_stat_ResponseCount.IncrementLong(Datum.UNSPECIFIED_SOURCE); m_stat_ResponseCount.IncrementLong($"{id.Portal}:${isoLang}"); } return(fetched); }
/// <summary> /// If NoCache is true then returns `CacheParams.NoCache` otherwise returns default (null by dflt) /// </summary> public static ICacheParams NoOrDefaultCache(this bool noCache, ICacheParams dflt = null) => noCache ? CacheParams.NoCache : dflt;
/// <summary> /// Deletes an item from cache and underlying store by calling the supplied asynchronous functor /// </summary> /// <typeparam name="TKey">Type of key</typeparam> /// <param name="cache">Non-null cache instance to delete from</param> /// <param name="key">Key value</param> /// <param name="tblCache">The name of a cache table</param> /// <param name="caching">Caching options, or null for defaults</param> /// <param name="fDelete">Asynchronous functor that performs backend deletion</param> /// <returns>True when value was deleted from the backing store</returns> public static async Task <bool> DeleteThroughAsync <TKey>(this ICache cache, TKey key, string tblCache, ICacheParams caching, Func <TKey, Task <bool> > fDelete) { cache.NonNull(nameof(cache)); if (caching == null) { caching = CacheParams.DefaultCache; } var wAge = caching.WriteCacheMaxAgeSec; var tbl = cache.GetOrCreateTable <TKey>(tblCache); if (caching.CacheAbsentData && wAge >= 0) { tbl.Put(key, AbsentValue.Instance, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); } else { tbl.Remove(key); } return(await fDelete.NonNull(nameof(fDelete))(key).ConfigureAwait(false)); }
/// <summary> /// Returns Config by name or null /// </summary> public FileResource GetFile(string name, ICacheParams caching = null) { return(null); }
/// <summary> /// Returns Config by name or null /// </summary> public ConfigResource GetConfig(string name, ICacheParams caching = null) { return(null); }
/// <summary> /// Saves an item through cache: call the `fSave` functor asynchronously then synchronously saves the result into cache table /// </summary> /// <typeparam name="TKey">Type of key</typeparam> /// <typeparam name="TData">Type of reference type value to save</typeparam> /// <typeparam name="TSaveResult">Type of save result</typeparam> /// <param name="cache">Cache to operate on</param> /// <param name="key">Key value</param> /// <param name="data">Reference type value to save. May not be null or AbsentValue</param> /// <param name="tblCache">The name of a cache table</param> /// <param name="caching">Caching options, or null for default</param> /// <param name="fSave">Synchronous functor that performs backend save</param> /// <param name="extraPut">Optional functor (cache, TKey, TData, ICacheParams) which can be used to add the piled value to other cache tables (indexes) </param> /// <returns>A result of the call to `fSave` functor</returns> public static async Task <TSaveResult> SaveThroughAsync <TKey, TData, TSaveResult>(this ICache cache, TKey key, TData data, string tblCache, ICacheParams caching, Func <TKey, TData, Task <TSaveResult> > fSave, Action <ICache, TKey, TData, ICacheParams> extraPut = null ) where TData : class { cache.NonNull(nameof(cache)); if (data == null || data is AbsentValue) { throw new DataAccessException(StringConsts.ARGUMENT_ERROR + "{0}(data ==null || is AbsentValue)".Args(nameof(SaveThrough))); } if (caching == null) { caching = CacheParams.DefaultCache; } var result = await fSave.NonNull(nameof(fSave))(key, data); var wAge = caching.WriteCacheMaxAgeSec; if (wAge >= 0) { var tbl = cache.GetOrCreateTable <TKey>(tblCache); var pr = tbl.Put(key, data, out var ptr, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); if (pr != PutResult.Collision && ptr.Valid) { extraPut?.Invoke(cache, key, data, caching); } } return(result); }
/// <summary> /// Fetches an item through cache - if the item exists and satisfies the `ICacheParams` (and optional `fFilter` functor) then it is immediately returned /// to the caller. Otherwise, calls the `fFetch` functor to perform the actual fetch of a value by key, and then puts the result in cache /// according to `ICacheParams` /// </summary> /// <typeparam name="TKey">Type of key</typeparam> /// <typeparam name="TResult">Type of the result value</typeparam> /// <param name="cache">Non-null ICache instance to operate on</param> /// <param name="key">Key value</param> /// <param name="tblCache">Name of cache table</param> /// <param name="caching">Caching options, or null for defaults</param> /// <param name="fFetch">Required functor that performs actual fetch when the value is NOT found in cache</param> /// <param name="fFilter">Optional functor - additional filter applied to existing values</param> /// <param name="extraPut">Optional functor (cache, TKey, TResult, ICacheParams) which can be used to add the piled value to other cache tables (indexes) </param> /// <returns>Cached reference type value, or null if not found or absent</returns> public static TResult FetchThrough <TKey, TResult>(this ICache cache, TKey key, string tblCache, ICacheParams caching, Func <TKey, TResult> fFetch, Func <TKey, TResult, TResult> fFilter = null, Action <ICache, TKey, TResult, ICacheParams> extraPut = null ) where TResult : class { cache.NonNull(nameof(cache)); ICacheTable <TKey> tbl = null; if (caching == null) { caching = CacheParams.DefaultCache; } if (caching.ReadCacheMaxAgeSec >= 0 || caching.WriteCacheMaxAgeSec >= 0) { tbl = cache.GetOrCreateTable <TKey>(tblCache); } TResult result = null; if (caching.ReadCacheMaxAgeSec >= 0) { var cached = tbl.Get(key, caching.ReadCacheMaxAgeSec); if (cached is AbsentValue) { return(null); } else { result = cached as TResult; } if (fFilter != null) { result = fFilter(key, result); } } if (result != null) { return(result); } result = fFetch.NonNull(nameof(fFetch))(key); if (result == null && !caching.CacheAbsentData) { return(null); } var wAge = caching.WriteCacheMaxAgeSec; if (wAge >= 0) { var pr = tbl.Put(key, (object)result ?? AbsentValue.Instance, out var ptr, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); if (pr != PutResult.Collision && ptr.Valid) { extraPut?.Invoke(cache, key, result, caching); } } return(result); }
/// <inheritdoc/> public async Task <TreeNodeInfo> GetNodeInfoAsync(EntityId id, DateTime?asOfUtc = null, ICacheParams cache = null) { //permission checks are performed in the child traverse loop down below if (cache == null) { cache = CacheParams.DefaultCache; } var asof = DefaultAndAlignOnPolicyBoundary(asOfUtc, id); var gop = GdidOrPath.OfGNodeOrPath(id); TreeNodeInfo result; if (gop.PathAddress != null) { result = await getNodeByTreePath(gop.Tree, gop.PathAddress, asof, cache).ConfigureAwait(false); } else { var graph = new HashSet <GDID>(); result = await getNodeByGdid(graph, gop.Tree, gop.GdidAddress, asof, cache).ConfigureAwait(false); } return(result); }
/// <summary> /// This is an async version of FetchFrom. This cache operation is only nominally asynchronous as it is performed in-memory and hence CPU-bound. /// Fetches an existing item from cache or null. IsAbsent is true when data was read from cache as an AbsentValue. /// </summary> /// <typeparam name="TKey">Type of key</typeparam> /// <typeparam name="TResult">Type of the returned result value</typeparam> /// <param name="cache">Cache instance to operate on</param> /// <param name="key">Key to read</param> /// <param name="tblCache">Name of a cache table within a cache</param> /// <param name="caching">Caching options, or null for defaults</param> /// <param name="isAbsent">Returns true when value was found, but it is an AbsentValue instance</param> /// <returns>Cached reference type value, or null if not found or absent</returns> public static Task <TResult> FetchFromAsync <TKey, TResult>(this ICache cache, TKey key, string tblCache, ICacheParams caching, out bool isAbsent) where TResult : class => Task.FromResult(cache.FetchFrom <TKey, TResult>(key, tblCache, caching, out isAbsent));
private async Task <TreeNodeInfo> getNodeByTreePath(TreePtr tree, TreePath path, DateTime asOfUtc, ICacheParams caching) { var tblCache = s_CacheTableName[tree]; var keyCache = nameof(getNodeByTreePath) + path + asOfUtc.Ticks; var result = await m_Data.Cache.FetchThroughAsync( keyCache, tblCache, caching, async key => { TreeNodeInfo nodeParent = null; TreeNodeInfo node = null; for (var i = -1; i < path.Count; i++) //going from LEFT to RIGHT { var segment = i < 0 ? Constraints.VERY_ROOT_PATH_SEGMENT : path[i]; node = await getNodeByPathSegment(tree, nodeParent == null ? GDID.ZERO : nodeParent.Gdid, segment, asOfUtc, caching).ConfigureAwait(false); if (node == null) { return(null); // deleted } //Config chain inheritance pattern if (nodeParent == null) { node.EffectiveConfig = new ConfigVector(node.LevelConfig.Content);//Copy node.FullPath = Constraints.VERY_ROOT_PATH_SEGMENT; } else { var confHere = node.LevelConfig.Node.NonEmpty(nameof(node.LevelConfig)); var confParent = nodeParent.EffectiveConfig.Node.NonEmpty(nameof(nodeParent.EffectiveConfig)); var confResult = new MemoryConfiguration() { Application = this.App }; confResult.CreateFromNode(confParent); //inherit confResult.Root.OverrideBy(confHere); //override node.EffectiveConfig = new ConfigVector(confResult.Root); node.FullPath = TreePath.Join(nodeParent.FullPath, node.PathSegment); } nodeParent = node; App.Authorize(new TreePermission(TreeAccessLevel.Read, node.FullPathId)); } return(node); }).ConfigureAwait(false); return(result); }
private async Task <TreeNodeInfo> getNodeByPathSegment(TreePtr tree, GDID gParent, string pathSegment, DateTime asOfUtc, ICacheParams caching) { if (gParent.IsZero) { gParent = Constraints.G_VERY_ROOT_NODE; } var tblCache = s_CacheTableName[tree]; var keyCache = nameof(getNodeByPathSegment) + gParent.ToHexString() + (pathSegment ?? string.Empty) + asOfUtc.Ticks; var node = await m_Data.Cache.FetchThroughAsync( keyCache, tblCache, caching, async key => { var qry = new Query <TreeNodeInfo>("Tree.GetNodeInfo") { new Query.Param("tree", tree), new Query.Param("gparent", gParent), new Query.Param("psegment", pathSegment), new Query.Param("asof", asOfUtc) }; return(await m_Data.TreeLoadDocAsync(tree, qry)); } ).ConfigureAwait(false); return(node); }
private async Task <TreeNodeInfo> getNodeByGdid(HashSet <GDID> graph, TreePtr tree, GDID gNode, DateTime asOfUtc, ICacheParams caching) { var tblCache = s_CacheTableName[tree]; var keyCache = nameof(getNodeByGdid) + gNode.ToHexString() + asOfUtc.Ticks; var result = await m_Data.Cache.FetchThroughAsync( keyCache, tblCache, caching, async key => { if (!graph.Add(gNode)) { //circular reference var err = new ConfigException("Circular reference in config tree = `{0}`, gnode = `{1}`, asof = `{2}`".Args(tree, gNode, asOfUtc)); WriteLogFromHere(Log.MessageType.CatastrophicError, err.Message, err, pars: new { tree = tree.ToString(), gnode = gNode, asof = asOfUtc }.ToJson()); throw err; } //1 - fetch THIS level - rightmost part of the tree var qry = new Query <TreeNodeInfo>("Tree.GetNodeInfoByGdid") { new Query.Param("tree", tree), new Query.Param("gdid", gNode), new Query.Param("asof", asOfUtc) }; var node = await m_Data.TreeLoadDocAsync(tree, qry); if (node == null) { return(null); } //2 - if IAM ROOT, there is no parent for root node.EffectiveConfig = new ConfigVector(node.LevelConfig.Content);//Copy node.FullPath = Constraints.VERY_ROOT_PATH_SEGMENT; if (node.Gdid == Constraints.G_VERY_ROOT_NODE) { return(node); } //3 - Fetch parent of THIS TreeNodeInfo nodeParent = await getNodeByGdid(graph, tree, node.G_Parent, asOfUtc, caching).ConfigureAwait(false); if (nodeParent == null) { return(null); } //4 - calculate effective config var cfgNode = node.LevelConfig.Node.NonEmpty(nameof(node.LevelConfig)); var cfgParent = nodeParent.EffectiveConfig.Node.NonEmpty(nameof(nodeParent.EffectiveConfig)); var confResult = new MemoryConfiguration() { Application = this.App }; confResult.CreateFromNode(cfgParent); //inherit confResult.Root.OverrideBy(cfgNode); //override node.EffectiveConfig.Node = confResult.Root; node.FullPath = TreePath.Join(nodeParent.FullPath, node.PathSegment); //the security check is done post factum AFTER tree node full path is known return(node); } ).ConfigureAwait(false); if (result == null) { return(null); } App.Authorize(new TreePermission(TreeAccessLevel.Read, result.FullPathId)); return(result); }
/// <summary> /// Fetches an item through cache /// </summary> public static TResult FetchThrough <TKey, TResult>(this ICache cache, TKey key, string tblCache, ICacheParams caching, Func <TKey, TResult> fFetch, Func <TKey, TResult, TResult> fFilter = null) where TResult : class { ICacheTable <TKey> tbl = null; if (caching == null) { caching = CacheParams.DefaultCache; } if (caching.ReadCacheMaxAgeSec >= 0 || caching.WriteCacheMaxAgeSec >= 0) { tbl = cache.GetOrCreateTable <TKey>(tblCache); } TResult result = null; if (caching.ReadCacheMaxAgeSec >= 0) { var cached = tbl.Get(key, caching.ReadCacheMaxAgeSec); if (cached is AbsentValue) { return(null); } else { result = cached as TResult; } if (fFilter != null) { result = fFilter(key, result); } } if (result != null) { return(result); } result = fFetch(key); if (result == null && !caching.CacheAbsentData) { return(null); } var wAge = caching.WriteCacheMaxAgeSec; if (wAge >= 0) { tbl.Put(key, (object)result ?? AbsentValue.Instance, wAge > 0 ? wAge : (int?)null, caching.WriteCachePriority); } return(result); }
private async Task <IEnumerable <TreeNodeHeader> > getChildNodeListByTreePath(TreePtr tree, TreePath pathAddress, DateTime asOfUtc, ICacheParams caching) { var nodeParent = await getNodeByTreePath(tree, pathAddress, asOfUtc, caching).ConfigureAwait(false); if (nodeParent == null) { return(null); } var result = await getChildNodeListByGdid(tree, nodeParent.Gdid, asOfUtc, caching); return(result); }
public static TResource Navigate <TResource>(this ICMSContext ctx, string path, ICacheParams caching = null) where TResource : Resource { var result = ctx.TryNavigate(path, caching) as TResource; if (result == null) { throw new CMSException(StringConsts.CMS_NAVIGATE_T_ERROR.Args(ctx.Portal, typeof(TResource), path)); } return(result); }
private async Task <IEnumerable <TreeNodeHeader> > getChildNodeListByGdid(TreePtr tree, GDID gdidAddress, DateTime asOfUtc, ICacheParams caching) { var tblCache = s_CacheTableName[tree]; var keyCache = nameof(getChildNodeListByGdid) + gdidAddress.ToHexString() + asOfUtc.Ticks; var nodes = await m_Data.Cache.FetchThroughAsync( keyCache, tblCache, caching, async key => { var qry = new Query <TreeNodeHeader>("Tree.GetChildNodeList") { new Query.Param("tree", tree), new Query.Param("gparent", gdidAddress), new Query.Param("asof", asOfUtc) }; return(await m_Data.TreeLoadEnumerableAsync(tree, qry)); } ).ConfigureAwait(false); return(nodes); }
public async Task <Content> FetchContentAsync(ContentId id, Atom isoLang, DateTime utcNow, ICacheParams caching) { id.HasRequiredValue(nameof(id)); var(svc, adr) = ensureOperationalState(); var uri = new UriQueryBuilder("feed") .Add("portal", id.Portal) .Add("ns", id.Namespace) .Add("block", id.Block) .Add("isolang", isoLang.ToString()) .Add("nocache", caching == null || caching.ReadCacheMaxAgeSec < 0) .Add("buffered", false) .ToString(); var result = await svc.Call(adr, nameof(ICmsSource), new ShardKey(id.Block), async (http, ct) => { Content content = null; using (var httpResponse = await http.Client.GetAsync(uri).ConfigureAwait(false)) { httpResponse.EnsureSuccessStatusCode(); var compress = httpResponse.Content.Headers.ContentType.MediaType.EqualsOrdIgnoreCase(Controllers.CmsSourceFeeder.CTP_COMPRESSED); using (var stream = await httpResponse.Content.ReadAsStreamAsync().ConfigureAwait(false)) { var rstream = stream; if (compress) { rstream = new GZipStream(stream, CompressionMode.Decompress, true); } content = new Content(stream); if (compress) { rstream.Dispose(); } } } return(content); }).ConfigureAwait(false); return(result); }
protected virtual IEnumerable <FriendConnection> DoGetFriendConnections(FriendQuery query, ICacheParams cacheParams = null) { var rows = ForNode(query.G_Node).LoadEnumerable(Queries.FindFriends <FriendRow>(query)); foreach (var row in rows) { var friendNode = DoGetNode(row.G_Friend, cacheParams); foreach (var graphNode in GraphHost.FilterByOriginQuery(new[] { friendNode }, query.OriginQuery)) { yield return(new FriendConnection(graphNode, row.Request_Date, FriendStatus.Approved.Equals(GSFriendStatus.ToFriendStatus(row.Status)) ? (DateTime?)row.Status_Date : null, GSFriendshipRequestDirection.ToFriendshipRequestDirection(row.Direction), GSFriendVisibility.ToFriendVisibility(row.Visibility), row.Lists)); } } }