Example #1
0
        public async Task StreamDelayed()
        {
            var seed = Encoding.ASCII.GetBytes(@"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce elementum nisi vel magna rhoncus, in aliquam ipsum accumsan. Phasellus efficitur lectus quis malesuada aliquet. Proin mattis sagittis magna vitae blandit. Cras vel diam sagittis, fringilla nunc vitae, vehicula mi. Nullam et auctor mi. Proin vel pharetra tortor. Donec posuere elementum risus, et aliquet magna pharetra non. Curabitur volutpat maximus sem at euismod. Fusce porta, lacus vel varius varius, lacus felis faucibus ante, fermentum sollicitudin elit neque rhoncus tortor. Aenean eget turpis consequat, luctus lorem vehicula, ullamcorper erat.");

            await using var prod = StreamProducer.FromStream(new MemoryStream(seed, false));
            var buffer = new MemoryStream();

            await using var cons = StreamConsumer.Delay(_ => new ValueTask <IStreamConsumer>(StreamConsumer.Create((stream, ctoken) =>
            {
                return(OptimisticCopyToAsync(stream, buffer, 8192, ctoken));
            })));
            await prod.ConsumeAsync(cons);

            Assert.True(seed.SequenceEqual(buffer.ToArray()));
        }
Example #2
0
 public IStreamConsumer CreateConsumer(ContentInfo contentInfo)
 => StreamConsumer.Delay((cancellationToken) => new ValueTask <IStreamConsumer>(CreateUploadConsumerAsync(Uri, contentInfo.Type, cancellationToken)));
        protected virtual async Task InvokeResizeAsync(
            IImageSource source,
            IImageDestination destination,
            string queryString,
            string endpoint,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();
            using var scope = Logger.BeginScope(Guid.NewGuid());
            Logger.LogDebug("Resize operation starting.");
            var uri = new UriBuilder(endpoint)
            {
                Query = queryString
            }.Uri;
            var context = await GetOperationContextAsync(source, destination, endpoint, cancellationToken).ConfigureAwait(false);

            Logger.LogDebug("Computed context for resize operation ({0}).", context.ContentType);
            try
            {
                IStreamConsumer consumer;
                if (context.Destination is null)
                {
                    // both source and destination are serializable
                    consumer = StreamConsumer.Create(async(input, cancellationToken) =>
                    {
                        using var request = new HttpRequestMessage(HttpMethod.Post, uri)
                              {
                                  Content = new JsonStreamContent(input)
                              };
                        using var client   = CreateHttpClient();
                        using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken);
                        await CheckAsync(response, cancellationToken);
                    });
                }
                else
                {
                    // destination is not serializable, source does either support serialization or not..
                    var outputMime    = "application/octet-stream";
                    var finalConsumer = StreamConsumer.Delay(_ =>
                    {
                        Logger.LogDebug("Creating consumer for resize operation");
                        return(new ValueTask <IStreamConsumer>(context.Destination.CreateConsumer(new ContentInfo(outputMime))));
                    });
                    consumer = finalConsumer.Chain(StreamTransformation.Create(async(input, output, cancellationToken) =>
                    {
                        Logger.LogDebug("Sending resize request.");
                        using var request = new HttpRequestMessage(HttpMethod.Post, uri)
                              {
                                  Content = new TypedStreamContent(input, context.ContentType)
                              };
                        using var client   = CreateHttpClient();
                        using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
                        Logger.LogDebug("Received response of the resize request.");
                        await CheckAsync(response, cancellationToken).ConfigureAwait(false);
                        outputMime       = response.Content.Headers.ContentType.MediaType ?? "application/octet-stream";
                        using var stream = await response.Content.ReadAsStreamAsync().ConfigureAwait(false);
                        await stream.CopyToAsync(output, 16 * 1024, cancellationToken).ConfigureAwait(false);
                        Logger.LogDebug("Done processing response of the resize request.");
                    }));
                }
                Logger.LogDebug("Initializing resize operation.");
                await context.Producer.ConsumeAsync(consumer, cancellationToken).ConfigureAwait(false);

                Logger.LogDebug("Resize operation completed.");
            }
            catch (Exception exn) when(!(exn is ImageException))
            {
                if (IsSocketRelated(exn, out var socketExn))
                {
                    if (IsBrokenPipe(socketExn) && source.Reusable)
                    {
                        Logger.LogWarning(exn, "Failed to perform operation due to connection error, retrying...");
                        await InvokeResizeAsync(source, destination, queryString, endpoint, cancellationToken).ConfigureAwait(false);

                        return;
                    }
                    throw new RemoteImageConnectivityException(endpoint, socketExn.SocketErrorCode, "Network related error has occured while performing operation.", exn);
                }
                throw new RemoteImageException(endpoint, ErrorCodes.GenericError, "Error has occurred while performing operation.", exn);
            }
        }