/// <summary> /// Attempt to read the page, with optional retry capabilities. /// </summary> /// <param name="offset"></param> /// <param name="take"></param> /// <returns></returns> public virtual IObservable <PageReadResult <TItem> > ReadPage(int offset, int take) { var request = new PageReadRequest() { Offset = offset, Take = Math.Min(take, MaxPageSize) }; return(this.ReadPage(request).RetryX((retryCount, ex) => OnErrorObservable(request, ex))); }
/// <summary> /// Enqueue a read /// </summary> /// <param name="pageReadRequest"></param> /// <param name="replaceExisting"></param> /// <returns></returns> protected IObservable <PageReadResult <TItem> > EnqueueReadObservable(PageReadRequest pageReadRequest, bool replaceExisting = false) { return(Enqueue(() => { var alignedStart = 0; var alignedEnd = 0; if (GetReadRange(pageReadRequest, replaceExisting, ref alignedStart, ref alignedEnd)) { return _pageReader.ReadRangeObservable(alignedStart, alignedEnd). ObserveOn(_updateScheduler). Do(l => Total = l.Total). Do(l => AddUpdate(l.Offset, l.Items, replaceExisting)); } // no need to remotely read anything, just get on with it return Observable.Return(new PageReadResult <TItem>(pageReadRequest.Offset, this.Total, null)); } )); }
/// <summary> /// Default exception factory, just fail. /// </summary> /// <param name="request"></param> /// <param name="exception"></param> /// <returns></returns> protected static IObservable <bool> DefaultErrorObservable(PageReadRequest request, Exception exception) { return(Observable.Return(false)); }
/// <summary> /// Upon an exception, invoke the appropriate exeception factory. /// </summary> /// <param name="request"></param> /// <param name="exception"></param> /// <returns></returns> protected virtual IObservable <bool> OnErrorObservable(PageReadRequest request, Exception exception) { return(DefaultErrorObservable(request, exception)); }
/// <summary> /// Method that will be overridden for reading page page requests. /// </summary> /// <param name="pageReadRequest"></param> /// <returns></returns> protected abstract IObservable <PageReadResult <TItem> > ReadPage(PageReadRequest pageReadRequest);
protected override IObservable <PageReadResult <TItem> > ReadPage(PageReadRequest pageReadRequest) { return(_readChunkObservable(pageReadRequest)); }
/// <summary> /// Upon an exception, invoke the appropriate exeception factory. /// </summary> /// <param name="request"></param> /// <param name="exception"></param> /// <returns></returns> protected override IObservable <bool> OnErrorObservable(PageReadRequest request, Exception exception) { return(_exceptionObservable != null?_exceptionObservable(request, exception) : DefaultErrorObservable(request, exception)); }
/// <summary> /// Calculate the read range given a specified count of a 'notional' list of existing read information. /// </summary> /// <typeparam name="TSource"></typeparam> /// <param name="provider"></param> /// <param name="pageReadRequest"></param> /// <param name="currentCount"></param> /// <param name="alignedStart"></param> /// <param name="alignedEnd"></param> /// <returns></returns> public static bool CalcReadRange <TSource>(this BaseChangeSetProvider <TSource> provider, PageReadRequest pageReadRequest, int currentCount, ref int alignedStart, ref int alignedEnd) { var offset = pageReadRequest.Offset; var take = pageReadRequest.Take; var extremum = offset + take; /* * var anythingToRead = true; * * if (provider.Total.HasValue) * { * anythingToRead = (offset >= currentCount) || (offset + take > currentCount) && offset < provider.Total.Value; * } * * if (anythingToRead) * { * // start from top * alignedStart = provider.PageAlignedOffset(currentCount); * * // calculate the end * alignedEnd = Math.Max(alignedStart + take, extremum); * * anythingToRead = alignedStart != alignedEnd; * } */ var topEnd = int.MaxValue; if (provider.Total.HasValue) { topEnd = provider.Total.Value; } var isAnythingToRead = offset + take <= topEnd && currentCount < offset + take; if (isAnythingToRead) { alignedStart = currentCount; var adjustedExtremum = Math.Min(extremum, topEnd); alignedEnd = adjustedExtremum; isAnythingToRead = alignedStart != alignedEnd; } return(isAnythingToRead); //return anythingToRead; }
/// <summary> /// Read the data /// </summary> /// <param name="pageReadRequest"></param> /// <returns></returns> public IObservable <PageReadResult <TItem> > ReadPageObservable(PageReadRequest pageReadRequest) { Guard.NotNull(pageReadRequest); return(EnqueueReadObservable(pageReadRequest)); }
/// <summary> /// Overloaded method used to calculate the range of reads required. /// </summary> /// <param name="pageReadRequest">Ther read request</param> /// <param name="forceReload">Should the data be always read?</param> /// <param name="alignedStart">output start of where data should be read from</param> /// <param name="alignedEnd">out put end of where data should be read up to</param> /// <returns>True if any data should infact be read.</returns> protected abstract bool GetReadRange(PageReadRequest pageReadRequest, bool forceReload, ref int alignedStart, ref int alignedEnd);