Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Core: Use an HttpClient singleton to prevent unnecessary disposal #57

Merged
merged 1 commit into from
Apr 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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