Skip to content

Commit c6efe7c

Browse files
committed
Refines async operations and resource management
* Improves asynchronous programming practices by consistently applying `ConfigureAwait(false)` to prevent potential deadlocks and optimize performance. * Enhances resource management by ensuring `HttpResponseMessage` and content streams are properly disposed using `using var` statements. * Optimizes JSON deserialization by reading directly from network streams where possible, avoiding intermediate string conversions for efficiency. * Updates project metadata, including the Dependabot assignee and repository URL. * Removes verbose logging of serialized vCon data to improve security and reduce log volume.
1 parent 76920ca commit c6efe7c

4 files changed

Lines changed: 33 additions & 35 deletions

File tree

.github/dependabot.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@ updates:
66
directory: '/'
77
schedule:
88
interval: 'weekly'
9-
9+
1010
# Maintain dependencies for .NET
1111
- package-ecosystem: 'nuget'
1212
directory: '/'
1313
schedule:
1414
interval: 'weekly'
1515
open-pull-requests-limit: 10
1616
assignees:
17-
- 'mstonis'
17+
- 'michaelstonis'
1818
commit-message:
1919
prefix: 'deps'
20-
include: 'scope'
20+
include: 'scope'

VConSharp/ApiClient/VConApiClient.cs

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public async Task<IReadOnlyList<string>> GetVConsUuidsAsync(
8383
try
8484
{
8585
_logger.LogDebug("Getting vCons UUIDs with parameters: {Parameters}", queryParams);
86-
var response = await _httpClient.GetFromJsonAsync<List<string>>(requestUri, _jsonOptions, cancellationToken);
86+
var response = await _httpClient.GetFromJsonAsync<List<string>>(requestUri, _jsonOptions, cancellationToken).ConfigureAwait(false);
8787
return response ?? new List<string>();
8888
}
8989
catch (Exception ex)
@@ -100,17 +100,16 @@ public async Task<IReadOnlyList<string>> GetVConsUuidsAsync(
100100
{
101101
_logger.LogDebug("Getting vCon with UUID: {UUID}", vconUuid);
102102
var requestUri = $"vcon/{vconUuid}";
103-
var response = await _httpClient.GetAsync(requestUri, cancellationToken);
103+
using var response = await _httpClient.GetAsync(requestUri, cancellationToken).ConfigureAwait(false);
104104

105105
response.EnsureSuccessStatusCode();
106106

107107
// Read the raw JSON first to inspect it
108-
var rawJson = await response.Content.ReadAsStringAsync(cancellationToken);
109-
_logger.LogInformation("Raw JSON response: {JSON}", rawJson);
108+
using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
110109

111110
try
112111
{
113-
var vconData = JsonSerializer.Deserialize<VCon>(rawJson, _jsonOptions);
112+
var vconData = JsonSerializer.Deserialize<VCon>(stream, _jsonOptions);
114113
return vconData;
115114
}
116115
catch (JsonException jsonEx)
@@ -143,7 +142,7 @@ public async Task<IReadOnlyList<VCon>> GetMultipleVConsAsync(
143142
try
144143
{
145144
_logger.LogDebug("Getting multiple vCons with UUIDs: {UUIDs}", string.Join(", ", uuidList));
146-
var response = await _httpClient.GetFromJsonAsync<List<VCon>>(requestUri, _jsonOptions, cancellationToken);
145+
var response = await _httpClient.GetFromJsonAsync<List<VCon>>(requestUri, _jsonOptions, cancellationToken).ConfigureAwait(false);
147146

148147
return response?.Where(v => v != null).ToList() ?? new List<VCon>();
149148
}
@@ -168,19 +167,18 @@ public async Task<VCon> CreateVConAsync(VCon vcon, IEnumerable<string>? ingressL
168167
try
169168
{
170169
_logger.LogDebug("Creating vCon with UUID: {UUID}", vcon.Uuid);
171-
var vconJson = JsonSerializer.Serialize(vcon, _jsonOptions);
172-
_logger.LogInformation("Sending vCon JSON: {JSON}", vconJson);
173-
var response = await _httpClient.PostAsJsonAsync(requestUri, vcon, _jsonOptions, cancellationToken);
170+
171+
using var response = await _httpClient.PostAsJsonAsync(requestUri, vcon, _jsonOptions, cancellationToken).ConfigureAwait(false);
174172

175173
if (!response.IsSuccessStatusCode)
176174
{
177-
var errorContent = await response.Content.ReadAsStringAsync(cancellationToken);
175+
var errorContent = await response.Content.ReadAsStringAsync(cancellationToken).ConfigureAwait(false);
178176
_logger.LogError("API returned error {StatusCode}: {ErrorContent}", response.StatusCode, errorContent);
179177
}
180178

181179
response.EnsureSuccessStatusCode();
182180

183-
var createdVCon = await response.Content.ReadFromJsonAsync<VCon>(_jsonOptions, cancellationToken);
181+
var createdVCon = await response.Content.ReadFromJsonAsync<VCon>(_jsonOptions, cancellationToken).ConfigureAwait(false);
184182
return createdVCon!;
185183
}
186184
catch (Exception ex)
@@ -198,7 +196,7 @@ public async Task DeleteVConAsync(Guid vconUuid, CancellationToken cancellationT
198196
try
199197
{
200198
_logger.LogDebug("Deleting vCon with UUID: {UUID}", vconUuid);
201-
var response = await _httpClient.DeleteAsync(requestUri, cancellationToken);
199+
using var response = await _httpClient.DeleteAsync(requestUri, cancellationToken).ConfigureAwait(false);
202200
response.EnsureSuccessStatusCode();
203201
}
204202
catch (Exception ex)
@@ -238,7 +236,7 @@ public async Task<IReadOnlyList<Guid>> SearchVConsAsync(
238236
try
239237
{
240238
_logger.LogDebug("Searching vCons with parameters: {Parameters}", queryParams);
241-
var response = await _httpClient.GetFromJsonAsync<List<string>>(requestUri, _jsonOptions, cancellationToken);
239+
var response = await _httpClient.GetFromJsonAsync<List<string>>(requestUri, _jsonOptions, cancellationToken).ConfigureAwait(false);
242240

243241
return response?.Select(Guid.Parse).ToList() ?? new List<Guid>();
244242
}
@@ -258,7 +256,7 @@ public async Task AddToIngressListAsync(string ingressList, IEnumerable<Guid> vc
258256
try
259257
{
260258
_logger.LogDebug("Adding vCons to ingress list {IngressList}: {UUIDs}", ingressList, string.Join(", ", uuids));
261-
var response = await _httpClient.PostAsJsonAsync(requestUri, uuids, _jsonOptions, cancellationToken);
259+
using var response = await _httpClient.PostAsJsonAsync(requestUri, uuids, _jsonOptions, cancellationToken).ConfigureAwait(false);
262260
response.EnsureSuccessStatusCode();
263261
}
264262
catch (Exception ex)
@@ -284,7 +282,7 @@ public async Task<IReadOnlyList<string>> GetFromEgressListAsync(string egressLis
284282
try
285283
{
286284
_logger.LogDebug("Getting vCons from egress list {EgressList} with limit {Limit}", egressList, limit);
287-
var response = await _httpClient.GetAsync(requestUri, cancellationToken);
285+
using var response = await _httpClient.GetAsync(requestUri, cancellationToken).ConfigureAwait(false);
288286

289287
if (response.StatusCode == System.Net.HttpStatusCode.NoContent)
290288
{
@@ -293,8 +291,8 @@ public async Task<IReadOnlyList<string>> GetFromEgressListAsync(string egressLis
293291

294292
response.EnsureSuccessStatusCode();
295293

296-
var content = await response.Content.ReadAsStringAsync(cancellationToken);
297-
var results = JsonSerializer.Deserialize<List<string>>(content, _jsonOptions);
294+
using var stream = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
295+
var results = JsonSerializer.Deserialize<List<string>>(stream, _jsonOptions);
298296
return results ?? new List<string>();
299297
}
300298
catch (Exception ex)
@@ -312,10 +310,10 @@ public async Task<int> CountEgressListAsync(string egressList, CancellationToken
312310
try
313311
{
314312
_logger.LogDebug("Counting vCons in egress list {EgressList}", egressList);
315-
var response = await _httpClient.GetAsync(requestUri, cancellationToken);
313+
using var response = await _httpClient.GetAsync(requestUri, cancellationToken).ConfigureAwait(false);
316314
response.EnsureSuccessStatusCode();
317315

318-
var content = await response.Content.ReadAsStringAsync(cancellationToken);
316+
using var content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
319317
var result = JsonSerializer.Deserialize<Dictionary<string, int>>(content, _jsonOptions);
320318

321319
return result?.FirstOrDefault().Value ?? 0;
@@ -333,10 +331,10 @@ public async Task<Dictionary<string, object>> GetConfigAsync(CancellationToken c
333331
try
334332
{
335333
_logger.LogDebug("Getting system configuration");
336-
var response = await _httpClient.GetAsync("config", cancellationToken);
334+
using var response = await _httpClient.GetAsync("config", cancellationToken).ConfigureAwait(false);
337335
response.EnsureSuccessStatusCode();
338336

339-
var content = await response.Content.ReadAsStringAsync(cancellationToken);
337+
using var content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
340338
var result = JsonSerializer.Deserialize<Dictionary<string, object>>(content, _jsonOptions);
341339
return result ?? new Dictionary<string, object>();
342340
}
@@ -353,7 +351,7 @@ public async Task UpdateConfigAsync(Dictionary<string, object> config, Cancellat
353351
try
354352
{
355353
_logger.LogDebug("Updating system configuration");
356-
var response = await _httpClient.PostAsJsonAsync("config", config, _jsonOptions, cancellationToken);
354+
using var response = await _httpClient.PostAsJsonAsync("config", config, _jsonOptions, cancellationToken).ConfigureAwait(false);
357355
response.EnsureSuccessStatusCode();
358356
}
359357
catch (Exception ex)
@@ -371,10 +369,10 @@ public async Task<Dictionary<string, object>> GetDeadLetterQueueAsync(string ing
371369
try
372370
{
373371
_logger.LogDebug("Getting DLQ contents for ingress list {IngressList}", ingressList);
374-
var response = await _httpClient.GetAsync(requestUri, cancellationToken);
372+
using var response = await _httpClient.GetAsync(requestUri, cancellationToken).ConfigureAwait(false);
375373
response.EnsureSuccessStatusCode();
376374

377-
var content = await response.Content.ReadAsStringAsync(cancellationToken);
375+
using var content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
378376
var result = JsonSerializer.Deserialize<Dictionary<string, object>>(content, _jsonOptions);
379377
return result ?? new Dictionary<string, object>();
380378
}
@@ -393,10 +391,10 @@ public async Task<Dictionary<string, object>> ReprocessDeadLetterQueueAsync(stri
393391
try
394392
{
395393
_logger.LogDebug("Reprocessing DLQ for ingress list {IngressList}", ingressList);
396-
var response = await _httpClient.PostAsync(requestUri, null, cancellationToken);
394+
using var response = await _httpClient.PostAsync(requestUri, null, cancellationToken).ConfigureAwait(false);
397395
response.EnsureSuccessStatusCode();
398396

399-
var content = await response.Content.ReadAsStringAsync(cancellationToken);
397+
using var content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
400398
var result = JsonSerializer.Deserialize<Dictionary<string, object>>(content, _jsonOptions);
401399
return result ?? new Dictionary<string, object>();
402400
}
@@ -413,10 +411,10 @@ public async Task<Dictionary<string, object>> RebuildSearchIndexAsync(Cancellati
413411
try
414412
{
415413
_logger.LogDebug("Rebuilding search index");
416-
var response = await _httpClient.GetAsync("index_vcons", cancellationToken);
414+
using var response = await _httpClient.GetAsync("index_vcons", cancellationToken).ConfigureAwait(false);
417415
response.EnsureSuccessStatusCode();
418416

419-
var content = await response.Content.ReadAsStringAsync(cancellationToken);
417+
using var content = await response.Content.ReadAsStreamAsync(cancellationToken).ConfigureAwait(false);
420418
var result = JsonSerializer.Deserialize<Dictionary<string, object>>(content, _jsonOptions);
421419
return result ?? new Dictionary<string, object>();
422420
}

VConSharp/ApiClient/VConApiModel.cs

Whitespace-only changes.

VConSharp/VConSharp.csproj

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44
<TargetFramework>net9.0</TargetFramework>
55
<ImplicitUsings>enable</ImplicitUsings>
66
<Nullable>enable</Nullable>
7-
7+
88
<!-- NuGet Package Metadata -->
99
<PackageId>VConSharp</PackageId>
1010
<Authors>VConSharp Contributors</Authors>
1111
<Company>VConSharp</Company>
1212
<Description>A .NET library for creating and managing Virtual Conversations (vCons)</Description>
1313
<PackageTags>vcon;conversation;virtual-conversation;communication</PackageTags>
14-
<RepositoryUrl>https://github.com/mstonis/VConSharp</RepositoryUrl>
14+
<RepositoryUrl>https://github.com/theeightbot/VConSharp</RepositoryUrl>
1515
<RepositoryType>git</RepositoryType>
1616
<PackageLicenseExpression>MIT</PackageLicenseExpression>
1717
<PackageReadmeFile>README.md</PackageReadmeFile>
18-
18+
1919
<!-- XML Documentation -->
2020
<GenerateDocumentationFile>true</GenerateDocumentationFile>
2121
<NoWarn>$(NoWarn);1591</NoWarn>
@@ -31,5 +31,5 @@
3131
<PackageReference Include="Microsoft.Extensions.Http" Version="9.0.6" />
3232
<PackageReference Include="System.Text.Json" Version="9.0.6" />
3333
</ItemGroup>
34-
34+
3535
</Project>

0 commit comments

Comments
 (0)