Skip to content

Commit

Permalink
Merge branch 'dev' into V6
Browse files Browse the repository at this point in the history
  • Loading branch information
tgstation-server committed Oct 8, 2023
2 parents 23f6092 + 7bc3082 commit 0f7e289
Show file tree
Hide file tree
Showing 231 changed files with 1,836 additions and 1,555 deletions.
10 changes: 5 additions & 5 deletions src/Tgstation.Server.Client/AdministrationClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ public AdministrationClient(IApiClient apiClient)
}

/// <inheritdoc />
public Task<AdministrationResponse> Read(CancellationToken cancellationToken) => ApiClient.Read<AdministrationResponse>(Routes.Administration, cancellationToken);
public ValueTask<AdministrationResponse> Read(CancellationToken cancellationToken) => ApiClient.Read<AdministrationResponse>(Routes.Administration, cancellationToken);

/// <inheritdoc />
public async Task<ServerUpdateResponse> Update(
public async ValueTask<ServerUpdateResponse> Update(
ServerUpdateRequest updateRequest,
Stream? zipFileStream,
CancellationToken cancellationToken)
Expand All @@ -50,14 +50,14 @@ public async Task<ServerUpdateResponse> Update(
}

/// <inheritdoc />
public Task Restart(CancellationToken cancellationToken) => ApiClient.Delete(Routes.Administration, cancellationToken);
public ValueTask Restart(CancellationToken cancellationToken) => ApiClient.Delete(Routes.Administration, cancellationToken);

/// <inheritdoc />
public Task<IReadOnlyList<LogFileResponse>> ListLogs(PaginationSettings? paginationSettings, CancellationToken cancellationToken)
public ValueTask<List<LogFileResponse>> ListLogs(PaginationSettings? paginationSettings, CancellationToken cancellationToken)
=> ReadPaged<LogFileResponse>(paginationSettings, Routes.Logs, null, cancellationToken);

/// <inheritdoc />
public async Task<Tuple<LogFileResponse, Stream>> GetLog(LogFileResponse logFile, CancellationToken cancellationToken)
public async ValueTask<Tuple<LogFileResponse, Stream>> GetLog(LogFileResponse logFile, CancellationToken cancellationToken)
{
var resultFile = await ApiClient.Read<LogFileResponse>(
Routes.Logs + Routes.SanitizeGetPath(
Expand Down
113 changes: 82 additions & 31 deletions src/Tgstation.Server.Client/ApiClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
using Tgstation.Server.Api;
using Tgstation.Server.Api.Models;
using Tgstation.Server.Api.Models.Response;
using Tgstation.Server.Common.Extensions;
using Tgstation.Server.Common.Http;

namespace Tgstation.Server.Client
Expand Down Expand Up @@ -168,84 +169,84 @@ public void Dispose()
}

/// <inheritdoc />
public Task<TResult> Create<TResult>(string route, CancellationToken cancellationToken)
public ValueTask<TResult> Create<TResult>(string route, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpMethod.Put, null, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Read<TResult>(string route, CancellationToken cancellationToken)
public ValueTask<TResult> Read<TResult>(string route, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, null, HttpMethod.Get, null, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Update<TResult>(string route, CancellationToken cancellationToken)
public ValueTask<TResult> Update<TResult>(string route, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpMethod.Post, null, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Update<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
public ValueTask<TResult> Update<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Post, null, false, cancellationToken);

/// <inheritdoc />
public Task Patch(string route, CancellationToken cancellationToken) => RunRequest<object>(route, null, HttpPatch, null, false, cancellationToken);
public ValueTask Patch(string route, CancellationToken cancellationToken) => RunRequest(route, HttpPatch, null, false, cancellationToken);

/// <inheritdoc />
public Task Update<TBody>(string route, TBody body, CancellationToken cancellationToken)
public ValueTask Update<TBody>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, object>(route, body, HttpMethod.Post, null, false, cancellationToken);
=> RunResultlessRequest(route, body, HttpMethod.Post, null, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Create<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
public ValueTask<TResult> Create<TBody, TResult>(string route, TBody body, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Put, null, false, cancellationToken);

/// <inheritdoc />
public Task Delete(string route, CancellationToken cancellationToken)
=> RunRequest<object>(route, null, HttpMethod.Delete, null, false, cancellationToken);
public ValueTask Delete(string route, CancellationToken cancellationToken)
=> RunRequest(route, HttpMethod.Delete, null, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Create<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
public ValueTask<TResult> Create<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Put, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Read<TResult>(string route, long instanceId, CancellationToken cancellationToken)
public ValueTask<TResult> Read<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<TResult>(route, null, HttpMethod.Get, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Update<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
public ValueTask<TResult> Update<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Post, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task Delete(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<object>(route, null, HttpMethod.Delete, instanceId, false, cancellationToken);
public ValueTask Delete(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest(route, HttpMethod.Delete, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task Delete<TBody>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
public ValueTask Delete<TBody>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, object>(route, body, HttpMethod.Delete, instanceId, false, cancellationToken);
=> RunResultlessRequest(route, body, HttpMethod.Delete, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Delete<TResult>(string route, long instanceId, CancellationToken cancellationToken)
public ValueTask<TResult> Delete<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<TResult>(route, null, HttpMethod.Delete, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Delete<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
public ValueTask<TResult> Delete<TBody, TResult>(string route, TBody body, long instanceId, CancellationToken cancellationToken)
where TBody : class
=> RunRequest<TBody, TResult>(route, body, HttpMethod.Delete, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Create<TResult>(string route, long instanceId, CancellationToken cancellationToken)
public ValueTask<TResult> Create<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpMethod.Put, instanceId, false, cancellationToken);

/// <inheritdoc />
public Task<TResult> Patch<TResult>(string route, long instanceId, CancellationToken cancellationToken)
public ValueTask<TResult> Patch<TResult>(string route, long instanceId, CancellationToken cancellationToken)
=> RunRequest<object, TResult>(route, new object(), HttpPatch, instanceId, false, cancellationToken);

/// <inheritdoc />
public void AddRequestLogger(IRequestLogger requestLogger) => requestLoggers.Add(requestLogger ?? throw new ArgumentNullException(nameof(requestLogger)));

/// <inheritdoc />
public Task<Stream> Download(FileTicketResponse ticket, CancellationToken cancellationToken)
public ValueTask<Stream> Download(FileTicketResponse ticket, CancellationToken cancellationToken)
{
if (ticket == null)
throw new ArgumentNullException(nameof(ticket));
Expand All @@ -260,7 +261,7 @@ public Task<Stream> Download(FileTicketResponse ticket, CancellationToken cancel
}

/// <inheritdoc />
public async Task Upload(FileTicketResponse ticket, Stream? uploadStream, CancellationToken cancellationToken)
public async ValueTask Upload(FileTicketResponse ticket, Stream? uploadStream, CancellationToken cancellationToken)
{
if (ticket == null)
throw new ArgumentNullException(nameof(ticket));
Expand Down Expand Up @@ -303,8 +304,8 @@ await RunRequest<object>(
/// <param name="instanceId">The optional instance <see cref="EntityId.Id"/> for the request.</param>
/// <param name="tokenRefresh">If this is a token refresh operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the response on success.</returns>
protected virtual async Task<TResult> RunRequest<TResult>(
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the response on success.</returns>
protected virtual async ValueTask<TResult> RunRequest<TResult>(
string route,
HttpContent? content,
HttpMethod method,
Expand Down Expand Up @@ -339,7 +340,7 @@ protected virtual async Task<TResult> RunRequest<TResult>(
if (fileDownload)
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypeNames.Application.Octet));

await Task.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken))).ConfigureAwait(false);
await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogRequest(request, cancellationToken))).ConfigureAwait(false);

response = await httpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead, cancellationToken).ConfigureAwait(false);
}
Expand All @@ -352,7 +353,7 @@ protected virtual async Task<TResult> RunRequest<TResult>(

try
{
await Task.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken))).ConfigureAwait(false);
await ValueTaskExtensions.WhenAll(requestLoggers.Select(x => x.LogResponse(response, cancellationToken))).ConfigureAwait(false);

// just stream
if (fileDownload && response.IsSuccessStatusCode)
Expand Down Expand Up @@ -396,8 +397,8 @@ protected virtual async Task<TResult> RunRequest<TResult>(
/// Attempt to refresh the bearer token in the <see cref="headers"/>.
/// </summary>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in <see langword="true"/> if the refresh was successful, <see langword="false"/> otherwise.</returns>
async Task<bool> RefreshToken(CancellationToken cancellationToken)
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in <see langword="true"/> if the refresh was successful, <see langword="false"/> otherwise.</returns>
async ValueTask<bool> RefreshToken(CancellationToken cancellationToken)
{
if (tokenRefreshHeaders == null)
return false;
Expand Down Expand Up @@ -435,8 +436,8 @@ async Task<bool> RefreshToken(CancellationToken cancellationToken)
/// <param name="instanceId">The optional instance <see cref="EntityId.Id"/> for the request.</param>
/// <param name="tokenRefresh">If this is a token refresh operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="Task{TResult}"/> resulting in the response on success.</returns>
async Task<TResult> RunRequest<TBody, TResult>(
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the response on success.</returns>
async ValueTask<TResult> RunRequest<TBody, TResult>(
string route,
TBody? body,
HttpMethod method,
Expand All @@ -462,5 +463,55 @@ async Task<TResult> RunRequest<TBody, TResult>(
cancellationToken)
.ConfigureAwait(false);
}

/// <summary>
/// Main request method.
/// </summary>
/// <typeparam name="TBody">The body <see cref="Type"/>.</typeparam>
/// <param name="route">The route to run.</param>
/// <param name="body">The body of the request.</param>
/// <param name="method">The method of the request.</param>
/// <param name="instanceId">The optional instance <see cref="EntityId.Id"/> for the request.</param>
/// <param name="tokenRefresh">If this is a token refresh operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the response on success.</returns>
async ValueTask RunResultlessRequest<TBody>(
string route,
TBody? body,
HttpMethod method,
long? instanceId,
bool tokenRefresh,
CancellationToken cancellationToken)
where TBody : class
=> await RunRequest<TBody, object>(
route,
body,
method,
instanceId,
tokenRefresh,
cancellationToken);

/// <summary>
/// Main request method.
/// </summary>
/// <param name="route">The route to run.</param>
/// <param name="method">The method of the request.</param>
/// <param name="instanceId">The optional instance <see cref="EntityId.Id"/> for the request.</param>
/// <param name="tokenRefresh">If this is a token refresh operation.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/> for the operation.</param>
/// <returns>A <see cref="ValueTask{TResult}"/> resulting in the response on success.</returns>
ValueTask RunRequest(
string route,
HttpMethod method,
long? instanceId,
bool tokenRefresh,
CancellationToken cancellationToken)
=> RunResultlessRequest<object>(
route,
null,
method,
instanceId,
tokenRefresh,
cancellationToken);
}
}
8 changes: 4 additions & 4 deletions src/Tgstation.Server.Client/Components/ByondClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ public ByondClient(IApiClient apiClient, Instance instance)
}

/// <inheritdoc />
public Task<ByondResponse> ActiveVersion(CancellationToken cancellationToken) => ApiClient.Read<ByondResponse>(Routes.Byond, instance.Id!.Value, cancellationToken);
public ValueTask<ByondResponse> ActiveVersion(CancellationToken cancellationToken) => ApiClient.Read<ByondResponse>(Routes.Byond, instance.Id!.Value, cancellationToken);

/// <inheritdoc />
public Task<JobResponse> DeleteVersion(ByondVersionDeleteRequest deleteRequest, CancellationToken cancellationToken)
public ValueTask<JobResponse> DeleteVersion(ByondVersionDeleteRequest deleteRequest, CancellationToken cancellationToken)
=> ApiClient.Delete<ByondVersionDeleteRequest, JobResponse>(Routes.Byond, deleteRequest, instance.Id!.Value, cancellationToken);

/// <inheritdoc />
public Task<IReadOnlyList<ByondResponse>> InstalledVersions(PaginationSettings? paginationSettings, CancellationToken cancellationToken)
public ValueTask<List<ByondResponse>> InstalledVersions(PaginationSettings? paginationSettings, CancellationToken cancellationToken)
=> ReadPaged<ByondResponse>(paginationSettings, Routes.ListRoute(Routes.Byond), instance.Id, cancellationToken);

/// <inheritdoc />
public async Task<ByondInstallResponse> SetActiveVersion(ByondVersionRequest installRequest, Stream? zipFileStream, CancellationToken cancellationToken)
public async ValueTask<ByondInstallResponse> SetActiveVersion(ByondVersionRequest installRequest, Stream? zipFileStream, CancellationToken cancellationToken)
{
if (installRequest == null)
throw new ArgumentNullException(nameof(installRequest));
Expand Down
10 changes: 5 additions & 5 deletions src/Tgstation.Server.Client/Components/ChatBotsClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,19 @@ public ChatBotsClient(IApiClient apiClient, Instance instance)
}

/// <inheritdoc />
public Task<ChatBotResponse> Create(ChatBotCreateRequest settings, CancellationToken cancellationToken) => ApiClient.Create<ChatBotCreateRequest, ChatBotResponse>(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken);
public ValueTask<ChatBotResponse> Create(ChatBotCreateRequest settings, CancellationToken cancellationToken) => ApiClient.Create<ChatBotCreateRequest, ChatBotResponse>(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken);

/// <inheritdoc />
public Task Delete(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken);
public ValueTask Delete(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Delete(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken);

/// <inheritdoc />
public Task<IReadOnlyList<ChatBotResponse>> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken)
public ValueTask<List<ChatBotResponse>> List(PaginationSettings? paginationSettings, CancellationToken cancellationToken)
=> ReadPaged<ChatBotResponse>(paginationSettings, Routes.ListRoute(Routes.Chat), instance.Id!.Value, cancellationToken);

/// <inheritdoc />
public Task<ChatBotResponse> Update(ChatBotUpdateRequest settings, CancellationToken cancellationToken) => ApiClient.Update<ChatBotUpdateRequest, ChatBotResponse>(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken);
public ValueTask<ChatBotResponse> Update(ChatBotUpdateRequest settings, CancellationToken cancellationToken) => ApiClient.Update<ChatBotUpdateRequest, ChatBotResponse>(Routes.Chat, settings ?? throw new ArgumentNullException(nameof(settings)), instance.Id!.Value, cancellationToken);

/// <inheritdoc />
public Task<ChatBotResponse> GetId(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Read<ChatBotResponse>(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken);
public ValueTask<ChatBotResponse> GetId(EntityId settingsId, CancellationToken cancellationToken) => ApiClient.Read<ChatBotResponse>(Routes.SetID(Routes.Chat, settingsId?.Id ?? throw new ArgumentNullException(nameof(settingsId))), instance.Id!.Value, cancellationToken);
}
}
Loading

0 comments on commit 0f7e289

Please sign in to comment.