Skip to content

Commit

Permalink
Merge pull request #57 from goodtrailer/static-http-client
Browse files Browse the repository at this point in the history
Core: Use an `HttpClient` singleton to prevent unnecessary disposal
  • Loading branch information
goodtrailer committed Apr 3, 2023
2 parents 57d1272 + 5ed1377 commit 50da0f8
Show file tree
Hide file tree
Showing 13 changed files with 115 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public interface IPublicPathConfiguration : IReadOnlyPathConfiguration
/// The serialization directory (e.g. for the <see cref="TaskConfiguration"/> JSON).
/// </summary>
new string SerializationDir { get; set; }

/// <summary>
/// Asynchronously sets the assembly directory (e.g. for the task executable).
/// </summary>
Expand Down
30 changes: 15 additions & 15 deletions DailyDesktop.Core/Configuration/PathConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -81,34 +81,34 @@ public string SerializationDir
/// <inheritdoc/>
public async Task SetAssemblyDirAsync(string assemblyDir, CancellationToken cancellationToken)
{
if (this.assemblyDir == assemblyDir)
return;
if (this.assemblyDir == assemblyDir)
return;

Directory.CreateDirectory(assemblyDir);
this.assemblyDir = assemblyDir;
await UpdateAsync(cancellationToken);
Directory.CreateDirectory(assemblyDir);
this.assemblyDir = assemblyDir;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetProvidersDirAsync(string providersDir, CancellationToken cancellationToken)
{
if (this.providersDir == providersDir)
return;
if (this.providersDir == providersDir)
return;

Directory.CreateDirectory(providersDir);
this.providersDir = providersDir;
await UpdateAsync(cancellationToken);
Directory.CreateDirectory(providersDir);
this.providersDir = providersDir;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetSerializationDirAsync(string serializationDir, CancellationToken cancellationToken)
{
if (this.serializationDir == serializationDir)
return;
if (this.serializationDir == serializationDir)
return;

Directory.CreateDirectory(serializationDir);
this.serializationDir = serializationDir;
await UpdateAsync(cancellationToken);
Directory.CreateDirectory(serializationDir);
this.serializationDir = serializationDir;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
Expand Down
10 changes: 5 additions & 5 deletions DailyDesktop.Core/Configuration/TaskConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public int BlurStrength
Update();
}
}

/// <inheritdoc/>
public async Task SetDllAsync(string dll, CancellationToken cancellationToken)
{
Expand All @@ -111,7 +111,7 @@ public async Task SetDllAsync(string dll, CancellationToken cancellationToken)
this.dll = dll;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetIsEnabledAsync(bool isEnabled, CancellationToken cancellationToken)
{
Expand All @@ -121,7 +121,7 @@ public async Task SetIsEnabledAsync(bool isEnabled, CancellationToken cancellati
this.isEnabled = isEnabled;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetUpdateTimeAsync(DateTime updateTime, CancellationToken cancellationToken)
{
Expand All @@ -131,7 +131,7 @@ public async Task SetUpdateTimeAsync(DateTime updateTime, CancellationToken canc
this.updateTime = updateTime;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetDoResizeAsync(bool doResize, CancellationToken cancellationToken)
{
Expand All @@ -151,7 +151,7 @@ public async Task SetDoBlurredFitAsync(bool doBlurredFit, CancellationToken canc
this.doBlurredFit = doBlurredFit;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetBlurStrengthAsync(int blurStrength, CancellationToken cancellationToken)
{
Expand Down
10 changes: 5 additions & 5 deletions DailyDesktop.Core/Configuration/WallpaperConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ public async Task SetImageUriAsync(string imageUri, CancellationToken cancellati
this.imageUri = imageUri;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetAuthorAsync(string? author, CancellationToken cancellationToken)
{
Expand All @@ -175,7 +175,7 @@ public async Task SetAuthorAsync(string? author, CancellationToken cancellationT
this.author = author;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetAuthorUriAsync(string? authorUri, CancellationToken cancellationToken)
{
Expand All @@ -185,7 +185,7 @@ public async Task SetAuthorUriAsync(string? authorUri, CancellationToken cancell
this.authorUri = authorUri;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetTitleAsync(string? title, CancellationToken cancellationToken)
{
Expand All @@ -195,7 +195,7 @@ public async Task SetTitleAsync(string? title, CancellationToken cancellationTok
this.title = title;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetTitleUriAsync(string? titleUri, CancellationToken cancellationToken)
{
Expand All @@ -205,7 +205,7 @@ public async Task SetTitleUriAsync(string? titleUri, CancellationToken cancellat
this.titleUri = titleUri;
await UpdateAsync(cancellationToken);
}

/// <inheritdoc/>
public async Task SetDescriptionAsync(string? description, CancellationToken cancellationToken)
{
Expand Down
31 changes: 9 additions & 22 deletions DailyDesktop.Core/Providers/IProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@

using System;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading;
using System.Threading.Tasks;
using DailyDesktop.Core.Configuration;
using DailyDesktop.Core.Util;

namespace DailyDesktop.Core.Providers
{
Expand Down Expand Up @@ -36,10 +38,10 @@ public interface IProvider
/// Configures an <see cref="HttpClient"/> to be used for the
/// <see cref="WallpaperConfiguration.ImageUri"/> returned by
/// <see cref="ConfigureWallpaperAsync"/>. Used by
/// <see cref="IProviderExtensions.CreateHttpClient(IProvider)"/>.
/// <see cref="IProviderExtensions.ConfigureWallpaperAsync(IProvider, IPublicWallpaperConfiguration, CancellationToken)"/>.
/// </summary>
/// <param name="client">The <see cref="HttpClient"/> to configure.</param>
void ConfigureHttpClient(HttpClient client) { }
/// <param name="headers">The <see cref="HttpRequestHeaders"/> to configure.</param>
void ConfigureHttpRequestHeaders(HttpRequestHeaders headers) { }

/// <summary>
/// Asynchronously onfigures a <see cref="IPublicWallpaperConfiguration"/> using a given
Expand Down Expand Up @@ -73,32 +75,17 @@ static IProvider Instantiate(Type type)
public static class IProviderExtensions
{
/// <summary>
/// Creates an <see cref="HttpClient"/> with a proper User-Agent header and
/// configured by <see cref="IProvider.ConfigureHttpClient(HttpClient)"/>.
/// </summary>
/// <param name="provider">The <see cref="IProvider"/> configuring the returned <see cref="HttpClient"/>.</param>
/// <returns>The pre-configured <see cref="HttpClient"/>.</returns>
public static HttpClient CreateHttpClient(this IProvider provider)
{
var client = new HttpClient();
client.DefaultRequestHeaders.Add("User-Agent", "daily-desktop/0.0 (https://github.com/goodtrailer/daily-desktop)");
provider.ConfigureHttpClient(client);

return client;
}

/// <summary>
/// Asynchronously configures a <see cref="WallpaperConfiguration"/> using a pre-configured
/// <see cref="HttpClient"/> created by <see cref="CreateHttpClient(IProvider)"/>.
/// Asynchronously configures a <see cref="WallpaperConfiguration"/>.
/// </summary>
/// <param name="provider">The <see cref="IProvider"/> configuring the <see cref="WallpaperConfiguration"/>.</param>
/// <param name="wallpaperConfig">The <see cref="IPublicWallpaperConfiguration"/> to configure.</param>
/// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
/// <returns>The up-to-date <see cref="WallpaperConfiguration"/>.</returns>
public static async Task ConfigureWallpaperAsync(this IProvider provider, IPublicWallpaperConfiguration wallpaperConfig, CancellationToken cancellationToken)
{
using (var client = provider.CreateHttpClient())
await provider.ConfigureWallpaperAsync(client, wallpaperConfig, cancellationToken);
HttpUtils.ResetRequestHeaders();
provider.ConfigureHttpRequestHeaders(HttpUtils.Client.DefaultRequestHeaders);
await provider.ConfigureWallpaperAsync(HttpUtils.Client, wallpaperConfig, cancellationToken);

wallpaperConfig.NullifyWhitespace();
}
Expand Down
4 changes: 2 additions & 2 deletions DailyDesktop.Core/Providers/ProviderStore.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ namespace DailyDesktop.Core.Providers
public class ProviderStore
{
private const string PROVIDERS_SEARCH_PATTERN = "*.dll";

/// <summary>
/// Dictionary of <see cref="IProvider"/> <see cref="Type"/>s
/// added through <see cref="Scan"/> and <see cref="Add"/>.
Expand Down Expand Up @@ -46,7 +46,7 @@ public async Task<Type> Add(string dllPath, CancellationToken cancellationToken)
return Providers[dllPath];

var assembly = Assembly.Load(await File.ReadAllBytesAsync(dllPath, cancellationToken));

foreach (var type in assembly.GetTypes())
{
bool isPublic = type.IsPublic;
Expand Down
2 changes: 1 addition & 1 deletion DailyDesktop.Core/Util/AsyncUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
namespace DailyDesktop.Core.Util
{
/// <summary>
/// Utility functions for async logic.
/// Utilities for async logic.
/// </summary>
public static class AsyncUtils
{
Expand Down
29 changes: 29 additions & 0 deletions DailyDesktop.Core/Util/HttpUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (c) Alden Wu <aldenwu0@gmail.com>. Licensed under the MIT Licence.
// See the LICENSE file in the repository root for full licence text.

using System.Net.Http;

namespace DailyDesktop.Core.Util
{
/// <summary>
/// Utilities for Http logic.
/// </summary>
public static class HttpUtils
{
/// <summary>
/// An <see cref="HttpClient"/> singleton for use everywhere.
/// </summary>
public static HttpClient Client => client ??= new HttpClient();
private static HttpClient? client;

/// <summary>
/// Resets <see cref="Client"/>'s request headers, which includes adding
/// a user agent header that points to Daily Desktop.
/// </summary>
public static void ResetRequestHeaders()
{
Client.DefaultRequestHeaders.Clear();
Client.DefaultRequestHeaders.Add("User-Agent", "daily-desktop/0.0 (https://github.com/goodtrailer/daily-desktop)");
}
}
}
40 changes: 21 additions & 19 deletions DailyDesktop.Desktop/MainForm.cs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@ private void updateProviderInfo()
{
providerDescriptionLabel.Text = core.CurrentProvider?.Description ?? null_description;
providerSourceLinkLabel.Text = core.CurrentProvider?.SourceUri ?? null_text;
providerSourceLinkLabel.Links[0].Enabled = Uri.TryCreate(providerSourceLinkLabel.Text, UriKind.Absolute, out _);
providerSourceLinkLabel.TabStop = wallpaperAuthorLinkLabel.Links[0].Enabled;
}

private async Task repopulateProviderComboBox()
Expand Down Expand Up @@ -225,28 +227,28 @@ private async void optionsResizeCheckBox_CheckedChanged(object? _, EventArgs e)
private void updateWallpaperInfo_Impl(bool isDeserializationSuccessful)
{
if (isDeserializationSuccessful)
{
wallpaperUpdatedLabel.Text = $"{fetched_text} {wallpaperConfig.Date.ToString("dddd, MMMM d") ?? null_text}";
wallpaperTitleLinkLabel.Text = wallpaperConfig.Title ?? null_text;
wallpaperAuthorLinkLabel.Text = wallpaperConfig.Author ?? null_text;
wallpaperDescriptionRichTextBox.Text = Regex.Replace(wallpaperConfig.Description ?? null_description, "(?<=[^\r])\n", "\r\n");
{
wallpaperUpdatedLabel.Text = $"{fetched_text} {wallpaperConfig.Date.ToString("dddd, MMMM d") ?? null_text}";
wallpaperTitleLinkLabel.Text = wallpaperConfig.Title ?? null_text;
wallpaperAuthorLinkLabel.Text = wallpaperConfig.Author ?? null_text;
wallpaperDescriptionRichTextBox.Text = Regex.Replace(wallpaperConfig.Description ?? null_description, "(?<=[^\r])\n", "\r\n");

wallpaperTitleLinkLabel.Links[0].Enabled = Uri.TryCreate(wallpaperConfig.TitleUri, UriKind.Absolute, out _);
wallpaperTitleLinkLabel.TabStop = wallpaperTitleLinkLabel.Links[0].Enabled;
wallpaperTitleLinkLabel.Links[0].Enabled = Uri.TryCreate(wallpaperConfig.TitleUri, UriKind.Absolute, out _);
wallpaperTitleLinkLabel.TabStop = wallpaperTitleLinkLabel.Links[0].Enabled;

wallpaperAuthorLinkLabel.Links[0].Enabled = Uri.TryCreate(wallpaperConfig.AuthorUri, UriKind.Absolute, out _);
wallpaperAuthorLinkLabel.TabStop = wallpaperAuthorLinkLabel.Links[0].Enabled;
}
else
{
wallpaperUpdatedLabel.Text = $"{fetched_text} {null_text}";
wallpaperTitleLinkLabel.Text = null_text;
wallpaperAuthorLinkLabel.Text = null_text;
wallpaperDescriptionRichTextBox.Text = null_description;
wallpaperAuthorLinkLabel.Links[0].Enabled = Uri.TryCreate(wallpaperConfig.AuthorUri, UriKind.Absolute, out _);
wallpaperAuthorLinkLabel.TabStop = wallpaperAuthorLinkLabel.Links[0].Enabled;
}
else
{
wallpaperUpdatedLabel.Text = $"{fetched_text} {null_text}";
wallpaperTitleLinkLabel.Text = null_text;
wallpaperAuthorLinkLabel.Text = null_text;
wallpaperDescriptionRichTextBox.Text = null_description;

wallpaperTitleLinkLabel.Links[0].Enabled = false;
wallpaperAuthorLinkLabel.Links[0].Enabled = false;
}
wallpaperTitleLinkLabel.Links[0].Enabled = false;
wallpaperAuthorLinkLabel.Links[0].Enabled = false;
}
}

private void stateBackgroundWorker_DoWork(object? _, EventArgs e)
Expand Down
1 change: 0 additions & 1 deletion DailyDesktop.Providers.Bing/BingProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
using System.Threading.Tasks;
using DailyDesktop.Core.Configuration;
using DailyDesktop.Core.Providers;
using DailyDesktop.Core.Util;

namespace DailyDesktop.Providers.Bing
{
Expand Down
5 changes: 3 additions & 2 deletions DailyDesktop.Providers.Pixiv/PixivProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
Expand All @@ -26,9 +27,9 @@ public class PixivProvider : IProvider
"Using blurred-fit mode is highly recommended due to the large variety of aspect ratios of illustrations found on pixiv.";
public string SourceUri => "https://www.pixiv.net/ranking.php?content=illust";

public void ConfigureHttpClient(HttpClient client)
public void ConfigureHttpRequestHeaders(HttpRequestHeaders headers)
{
client.DefaultRequestHeaders.Referrer = new Uri("https://www.pixiv.net");
headers.Referrer = new Uri("https://www.pixiv.net");
}

public async Task ConfigureWallpaperAsync(HttpClient client, IPublicWallpaperConfiguration wallpaperConfig, CancellationToken cancellationToken)
Expand Down
11 changes: 4 additions & 7 deletions DailyDesktop.Task/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright (c) Alden Wu <aldenwu0@gmail.com>. Licensed under the MIT Licence.
// See the LICENSE file in the repository root for full licence text.

using System;
using System.CommandLine;
using System.CommandLine.Invocation;
using System.Drawing;
Expand Down Expand Up @@ -76,12 +75,10 @@ private static async Task<string> downloadWallpaper(IProvider provider, string j
await provider.ConfigureWallpaperAsync(wallpaperConfig, cancellationToken);
await wallpaperConfig.TrySerializeAsync(cancellationToken);

using (var client = provider.CreateHttpClient())
{
var stream = await client.GetStreamAsync(wallpaperConfig.ImageUri, cancellationToken);
using (var fstream = new FileStream(imagePath, FileMode.OpenOrCreate))
await stream.CopyToAsync(fstream, cancellationToken);
}
provider.ConfigureHttpRequestHeaders(HttpUtils.Client.DefaultRequestHeaders);
var stream = await HttpUtils.Client.GetStreamAsync(wallpaperConfig.ImageUri, cancellationToken);
using (var fstream = new FileStream(imagePath, FileMode.OpenOrCreate))
await stream.CopyToAsync(fstream, cancellationToken);

return imagePath;
}
Expand Down
Loading

0 comments on commit 50da0f8

Please sign in to comment.