/// <summary> /// Enforces behaviour required for logging unsuccessful cache requests and providing implementation-independent checks, so that the plugin author /// doesn't need to remember to call Request[Succeeded|Failed] or do general checks. Plugin author provides implementation-specific caching in /// the 'DoGetChunk' function. /// </summary> /// <param name="listener"></param> /// <param name="cancellationToken"></param> /// <returns></returns> public virtual T GetChunk(IDataLoadEventListener listener, GracefulCancellationToken cancellationToken) { Request = RequestProvider.GetNext(listener); // If GetNext returns null, there are no further failures to process and we're done if (Request == null) { listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "The RequestProvider has no more requests to provide (RequestProvider.GetNext returned null)")); return(null); } if (Request.CacheProgress == null) { throw new InvalidOperationException("The request has no CacheProgress item (in this case to determine when the lag period begins)"); } // Check if we will stray into the lag period with this fetch and if so signal we are finished var cacheLagPeriod = Request.CacheProgress.GetCacheLagPeriod(); if (cacheLagPeriod != null && cacheLagPeriod.TimeIsWithinPeriod(Request.End)) { listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Information, "The Request is for a time within the Cache Lag Period. This means we are up-to-date and can stop now.")); return(null); } Chunk = DoGetChunk(Request, listener, cancellationToken); if (Chunk != null && Chunk.Request == null && Request != null) { listener.OnNotify(this, new NotifyEventArgs(ProgressEventType.Error, "DoGetChunk completed and set a Chunk Successfully but the Chunk.Request was null. Try respecting the Request property in your class when creating your Chunk.")); } return(Chunk); }