/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults(IConsumer <T> consumer, IProducerContext producerContext) { IProducerListener producerListener = producerContext.Listener; producerListener.OnProducerStart(producerContext.Id, PRODUCER_NAME); bool delayRequest; lock (_gate) { if (_numCurrentRequests >= _maxSimultaneousRequests) { _pendingRequests.Enqueue( new Tuple <IConsumer <T>, IProducerContext>(consumer, producerContext)); delayRequest = true; } else { _numCurrentRequests++; delayRequest = false; } } if (!delayRequest) { ProduceResultsInternal(consumer, producerContext); } }
/// <summary> /// Performs the decode synchronously. /// </summary> private async Task DoDecode(EncodedImage encodedImage, bool isLast) { if (IsFinished() || !EncodedImage.IsValid(encodedImage)) { return; } try { long queueTime = _jobScheduler.GetQueuedTime(); int length = isLast ? encodedImage.Size : GetIntermediateImageEndOffset(encodedImage); if (length == 0) { return; } IQualityInfo quality = isLast ? ImmutableQualityInfo.FULL_QUALITY : GetQualityInfo(); _producerListener.OnProducerStart(_producerContext.Id, PRODUCER_NAME); CloseableImage image = null; try { image = await _parent._imageDecoder .DecodeImageAsync(encodedImage, length, quality, _imageDecodeOptions) .ConfigureAwait(false); } catch (Exception e) { _producerListener.OnProducerFinishWithFailure( _producerContext.Id, PRODUCER_NAME, e, GetExtraMap(image, queueTime, quality, isLast)); HandleError(e); return; } _producerListener.OnProducerFinishWithSuccess( _producerContext.Id, PRODUCER_NAME, GetExtraMap(image, queueTime, quality, isLast)); HandleResult(image, isLast); } finally { EncodedImage.CloseSafely(encodedImage); } }
/// <summary> /// Instantiates the <see cref="StatefulProducerRunnable{T}"/>. /// </summary> public StatefulProducerRunnable( IConsumer <T> consumer, IProducerListener producerListener, string producerName, string requestId) { _consumer = consumer; _producerListener = producerListener; _producerName = producerName; _requestId = requestId; _producerListener.OnProducerStart(_requestId, _producerName); }
private void DoPostprocessing( CloseableReference <CloseableImage> sourceImageRef, bool isLast) { Preconditions.CheckArgument(CloseableReference <CloseableImage> .IsValid(sourceImageRef)); if (!ShouldPostprocess(sourceImageRef.Get())) { MaybeNotifyOnNewResult(sourceImageRef, isLast); return; } _listener.OnProducerStart(_requestId, NAME); CloseableReference <CloseableImage> destImageRef = null; try { try { destImageRef = PostprocessInternal(sourceImageRef.Get()); } catch (Exception e) { _listener.OnProducerFinishWithFailure( _requestId, NAME, e, GetExtraMap(_listener, _requestId, _postprocessor)); MaybeNotifyOnFailure(e); return; } _listener.OnProducerFinishWithSuccess( _requestId, NAME, GetExtraMap(_listener, _requestId, _postprocessor)); MaybeNotifyOnNewResult(destImageRef, isLast); } finally { CloseableReference <CloseableImage> .CloseSafely(destImageRef); } }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; listener.OnProducerStart(requestId, ProducerName); ImageRequest imageRequest = producerContext.ImageRequest; object callerContext = producerContext.CallerContext; ICacheKey cacheKey = _cacheKeyFactory.GetBitmapCacheKey(imageRequest, callerContext); IDictionary <string, string> extraMap = default(IDictionary <string, string>); CloseableReference <CloseableImage> cachedReference = _memoryCache.Get(cacheKey); if (cachedReference != null) { bool isFinal = cachedReference.Get().QualityInfo.IsOfFullQuality; if (isFinal) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1f); } consumer.OnNewResult(cachedReference, isFinal); cachedReference.Dispose(); if (isFinal) { return; } } if (producerContext.LowestPermittedRequestLevel >= RequestLevel.BITMAP_MEMORY_CACHE) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnNewResult(null, true); return; } extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; IConsumer <CloseableReference <CloseableImage> > wrappedConsumer = WrapConsumer(consumer, cacheKey); listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(wrappedConsumer, producerContext); }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <CloseableReference <CloseableImage> > consumer, IProducerContext producerContext) { IProducerListener listener = producerContext.Listener; string requestId = producerContext.Id; ImageRequest imageRequest = producerContext.ImageRequest; object callerContext = producerContext.CallerContext; // If there's no postprocessor or the postprocessor doesn't // require caching, forward results. IPostprocessor postprocessor = imageRequest.Postprocessor; if (postprocessor == null || postprocessor.PostprocessorCacheKey == null) { _inputProducer.ProduceResults(consumer, producerContext); return; } listener.OnProducerStart(requestId, ProducerName); ICacheKey cacheKey = _cacheKeyFactory.GetPostprocessedBitmapCacheKey( imageRequest, callerContext); CloseableReference <CloseableImage> cachedReference = _memoryCache.Get(cacheKey); var extraMap = default(Dictionary <string, string>); if (cachedReference != null) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1.0f); consumer.OnNewResult(cachedReference, true); cachedReference.Dispose(); } else { bool isRepeatedProcessor = postprocessor.GetType() == typeof(IRepeatedPostprocessor); IConsumer <CloseableReference <CloseableImage> > cachedConsumer = new CachedPostprocessorConsumer( consumer, cacheKey, isRepeatedProcessor, _memoryCache); extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, ProducerName, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(cachedConsumer, producerContext); } }
/// <summary> /// Start producing results for given context. /// Provided consumer is notified whenever progress is made /// (new value is ready or error occurs). /// </summary> public void ProduceResults( IConsumer <EncodedImage> consumer, IProducerContext producerContext) { string requestId = producerContext.Id; IProducerListener listener = producerContext.Listener; listener.OnProducerStart(requestId, PRODUCER_NAME); ImageRequest imageRequest = producerContext.ImageRequest; ICacheKey cacheKey = _cacheKeyFactory.GetEncodedCacheKey( imageRequest, producerContext.CallerContext); CloseableReference <IPooledByteBuffer> cachedReference = _memoryCache.Get(cacheKey); IDictionary <string, string> extraMap = default(IDictionary <string, string>); try { if (cachedReference != null) { EncodedImage cachedEncodedImage = new EncodedImage(cachedReference); try { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "true" } }; listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnProgressUpdate(1f); consumer.OnNewResult(cachedEncodedImage, true); return; } finally { EncodedImage.CloseSafely(cachedEncodedImage); } } if (producerContext.LowestPermittedRequestLevel >= RequestLevel.ENCODED_MEMORY_CACHE) { extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); consumer.OnNewResult(null, true); return; } IConsumer <EncodedImage> consumerOfInputProducer = new EncodedMemoryCacheConsumer(_memoryCache, consumer, cacheKey); extraMap = new Dictionary <string, string>() { { VALUE_FOUND, "false" } }; listener.OnProducerFinishWithSuccess( requestId, PRODUCER_NAME, listener.RequiresExtraMap(requestId) ? new ReadOnlyDictionary <string, string>(extraMap) : null); _inputProducer.ProduceResults(consumerOfInputProducer, producerContext); } finally { CloseableReference <IPooledByteBuffer> .CloseSafely(cachedReference); } }