private async Task LoadLocallyAsync(string key, Stream sink, ICacheControl cacheControl, CancellationToken ct) { async Task func(string cachekey, Stream factorySink, ICacheControl factoryCacheControl) { try { Stats.TraceLocalLoads(_groupName); await _getter.GetAsync(cachekey, factorySink, factoryCacheControl, ct).ConfigureAwait(false); } catch (Exception ex) { Logger.Error(ex, String.Format("Call to LoadLocally for Cache {0} key: {1} failed ", _groupName, key)); throw; } } Stats.TraceCacheHits(_groupName); var cacheEntry = await _localCache.GetOrAddAsync(key, func, cacheControl, ct).ConfigureAwait(false); try { Stream cacheEntryStream = cacheEntry.Value(); await cacheEntryStream.CopyToAsync(sink).ConfigureAwait(false); } finally { await cacheEntry.DisposeAsync().ConfigureAwait(false); } }
public async Task GetAsync(string key, Stream sink, ICacheControl cacheControl, CancellationToken ct) { Interlocked.Increment(ref callCount); try { long number = long.Parse(key); long result; if (number == 0) { result = 0; } else if (number == 1) { result = 1; } else { // Make to call to n-1 and n-2 in parallel using (var firstStream = new MemoryStream()) using (var secondStream = new MemoryStream()) { await getter.GetAsync((number - 1).ToString(), firstStream, new CacheControl(), CancellationToken.None).ConfigureAwait(false); await getter.GetAsync((number - 2).ToString(), secondStream, new CacheControl(), CancellationToken.None).ConfigureAwait(false); var firstStr = firstStream.StreamToString(); var secondStr = secondStream.StreamToString(); // return the sum var firstLong = long.Parse(firstStr); var secondLong = long.Parse(secondStr); result = firstLong + secondLong; } } var resultStream = result.ToString().StringToStream(); resultStream.Position = 0; await resultStream.CopyToAsync(sink); } catch (Exception ex) { Console.WriteLine(ex.ToString()); throw; } }