From 4035c838c1508af0aa7e767a97431a692958ce1c Mon Sep 17 00:00:00 2001 From: vnugent Date: Sun, 12 May 2024 16:55:32 -0400 Subject: perf: Utils + http perf mods --- lib/Net.Rest.Client/src/Construction/Extensions.cs | 98 +++++++++++++++++++--- 1 file changed, 85 insertions(+), 13 deletions(-) (limited to 'lib/Net.Rest.Client') diff --git a/lib/Net.Rest.Client/src/Construction/Extensions.cs b/lib/Net.Rest.Client/src/Construction/Extensions.cs index ca0873b..93a1365 100644 --- a/lib/Net.Rest.Client/src/Construction/Extensions.cs +++ b/lib/Net.Rest.Client/src/Construction/Extensions.cs @@ -1,5 +1,5 @@ /* -* Copyright (c) 2023 Vaughn Nugent +* Copyright (c) 2024 Vaughn Nugent * * Library: VNLib * Package: VNLib.Net.Rest.Client @@ -23,6 +23,7 @@ */ using System; +using System.IO; using System.Text.Json; using System.Threading; using System.Threading.Tasks; @@ -46,8 +47,11 @@ namespace VNLib.Net.Rest.Client.Construction /// The request entity model to send to the server /// A token to cancel the operation /// A task that resolves the response message + /// public static async Task ExecuteAsync(this IRestSiteAdapter site, TModel entity, CancellationToken cancellation = default) { + ArgumentNullException.ThrowIfNull(site); + //Get the adapter for the model IRestEndpointAdapter adapter = site.GetAdapter(); @@ -75,6 +79,44 @@ namespace VNLib.Net.Rest.Client.Construction return response; } + /// + /// Begins a stream download of the desired resource by sending the request model parameter. + /// An must be defined to handle requests of the given model type. + /// + /// WARNING: This function will not invoke the OnResponse handler functions after the stream + /// has been returned, there is no way to inspect the response when excuting a stream download + /// + /// + /// + /// + /// The request entity model to send to the server + /// A token to cancel the operation + /// A task that resolves the response data stream + public static async Task DownloadStreamAsync(this IRestSiteAdapter site, TModel entity, CancellationToken cancellation = default) + { + ArgumentNullException.ThrowIfNull(site); + + //Get the adapter for the model + IRestEndpointAdapter adapter = site.GetAdapter(); + + //Get new request on adapter + RestRequest request = adapter.GetRequest(entity); + + //Wait to exec operations if needed + await site.WaitAsync(cancellation); + + Stream? response; + + //Get rest client + using (ClientContract contract = site.GetClient()) + { + //Exec response + response = await contract.Resource.DownloadStreamAsync(request, cancellation); + } + + return response; + } + /// /// Executes a request against the site by sending the request model parameter. An must be /// defined to handle requests of the given model type. @@ -87,6 +129,8 @@ namespace VNLib.Net.Rest.Client.Construction /// A task that resolves the response message with json resonse support public static async Task> ExecuteAsync(this IRestSiteAdapter site, TModel entity, CancellationToken cancellation = default) { + ArgumentNullException.ThrowIfNull(site); + //Get the adapter for the model IRestEndpointAdapter adapter = site.GetAdapter(); @@ -124,6 +168,8 @@ namespace VNLib.Net.Rest.Client.Construction /// When completed, gets the public static async Task ExecuteSingleAsync(this IRestSiteAdapter site, TModel model, CancellationToken cancellation = default) where TModel : IRestSingleEndpoint { + ArgumentNullException.ThrowIfNull(site); + //Init new request RestRequest request = new(model.Url, model.Method); model.OnRequest(request); @@ -149,6 +195,7 @@ namespace VNLib.Net.Rest.Client.Construction return response; } + /// /// Sets the request method of a new request /// @@ -358,22 +405,47 @@ namespace VNLib.Net.Rest.Client.Construction /// The json response entity type /// The response task /// A task that resolves the deserialized entity type - public static async Task AsJson(this Task response) + public static Task AsJson(this Task response) + => As(response, static r => JsonSerializer.Deserialize(r.RawBytes)); + + /// + /// Converts a task that resolves a to a task that deserializes + /// the response data as json. + /// + /// The response task + /// A task that resolves the deserialized entity type + public static Task AsBytes(this Task response) => As(response, static p => p.RawBytes); + + /// + /// Converts a task that resolves a to a task that uses your + /// transformation function to create the result + /// + /// The response task + /// Your custom callback function used to transform the data + /// A task that resolves the deserialized entity type + public static async Task As(this Task response, Func> callback) { + ArgumentNullException.ThrowIfNull(response); + ArgumentNullException.ThrowIfNull(callback); + RestResponse r = await response.ConfigureAwait(false); - return JsonSerializer.Deserialize(r.RawBytes); + return await callback(r).ConfigureAwait(false); } /// - /// Converts a task that resolves a to a task that deserializes - /// the response data as json. + /// Converts a task that resolves a to a task that uses your + /// transformation function to create the result /// /// The response task + /// Your custom callback function used to transform the data /// A task that resolves the deserialized entity type - public static async Task AsBytes(this Task response) + public static async Task As(this Task response, Func callback) { + ArgumentNullException.ThrowIfNull(response); + ArgumentNullException.ThrowIfNull(callback); + RestResponse r = await response.ConfigureAwait(false); - return r.RawBytes; + return callback(r); } private record class EndpointAdapterBuilder(IRestSiteEndpointStore Site) : IRestEndpointBuilder @@ -396,8 +468,8 @@ namespace VNLib.Net.Rest.Client.Construction /// public IRestRequestBuilder WithModifier(Action requestBuilder) { - _ = requestBuilder ?? throw new ArgumentNullException(nameof(requestBuilder)); - //Add handler to handler chain + ArgumentNullException.ThrowIfNull(requestBuilder); + Adapter.RequestChain.AddLast(requestBuilder); return this; } @@ -405,8 +477,8 @@ namespace VNLib.Net.Rest.Client.Construction /// public IRestRequestBuilder WithUrl(Func uriBuilder) { - _ = uriBuilder ?? throw new ArgumentNullException(nameof(uriBuilder)); - //Add get url handler + ArgumentNullException.ThrowIfNull(uriBuilder); + Adapter.GetUrl = uriBuilder; return this; } @@ -414,8 +486,8 @@ namespace VNLib.Net.Rest.Client.Construction /// public IRestRequestBuilder OnResponse(Action onResponseBuilder) { - _ = onResponseBuilder ?? throw new ArgumentNullException(nameof(onResponseBuilder)); - //Add a response handler + ArgumentNullException.ThrowIfNull(onResponseBuilder); + Adapter.ResponseChain.AddLast(onResponseBuilder); return this; } -- cgit