protected bool AddCacheEntryIfAbsent(string cacheKey, out HystrixCachedTask <RequestResponseType> entry) { var newEntry = new HystrixCachedTask <RequestResponseType>(); if (Properties.RequestCacheEnabled && cacheKey != null) { entry = _requestCache.PutIfAbsent(cacheKey, newEntry); if (entry != null) { return(true); } } entry = newEntry; return(false); }
public Task <RequestResponseType> ToTask() { RequestCollapser <BatchReturnType, RequestResponseType, RequestArgumentType> requestCollapser = collapserFactory.GetRequestCollapser(this); CollapsedRequest <RequestResponseType, RequestArgumentType> request = null; HystrixCachedTask <RequestResponseType> entry = null; if (AddCacheEntryIfAbsent(CacheKey, out entry)) { metrics.MarkResponseFromCache(); var origTask = entry.CachedTask; request = entry.CachedTask.AsyncState as CollapsedRequest <RequestResponseType, RequestArgumentType>; request.AddLinkedToken(_token); var continued = origTask.ContinueWith <RequestResponseType>( (parent) => { CollapsedRequest <RequestResponseType, RequestArgumentType> req = parent.AsyncState as CollapsedRequest <RequestResponseType, RequestArgumentType>; if (req != null) { if (req.Exception != null) { throw req.Exception; } return(req.Response); } else { throw new InvalidOperationException("Missing AsyncState from parent task"); } }, _token, TaskContinuationOptions.ExecuteSynchronously, TaskScheduler.Current); return(continued); } try { request = requestCollapser.SubmitRequest(RequestArgument, _token); entry.CachedTask = request.CompletionSource.Task; return(entry.CachedTask); } catch (Exception ex) { return(Task.FromException <RequestResponseType>(ex)); } }