refactor: delay starting background tasks

* start background task only it is needed
* solve the problem that we can not use `ViewModels.Preference.Instance` until resource ready
* remove avatar sever settings
This commit is contained in:
leo 2024-08-18 23:09:55 +08:00
parent e7921db339
commit 7fe1df20cc
No known key found for this signature in database
13 changed files with 178 additions and 190 deletions

View file

@ -0,0 +1,120 @@
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace SourceGit.Models
{
public class AutoFetchManager
{
public static AutoFetchManager Instance
{
get
{
if (_instance == null)
_instance = new AutoFetchManager();
return _instance;
}
}
public class Job
{
public Commands.Fetch Cmd = null;
public DateTime NextRunTimepoint = DateTime.MinValue;
}
public bool IsEnabled
{
get;
set;
} = false;
public int Interval
{
get => _interval;
set
{
_interval = Math.Max(1, value);
lock (_lock)
{
foreach (var job in _jobs)
job.Value.NextRunTimepoint = DateTime.Now.AddMinutes(_interval * 1.0);
}
}
}
private static AutoFetchManager _instance = null;
private Dictionary<string, Job> _jobs = new Dictionary<string, Job>();
private object _lock = new object();
private int _interval = 10;
public void Start()
{
Task.Run(() =>
{
while (true)
{
if (!IsEnabled)
{
Thread.Sleep(10000);
continue;
}
var now = DateTime.Now;
var uptodate = new List<Job>();
lock (_lock)
{
foreach (var job in _jobs)
{
if (job.Value.NextRunTimepoint.Subtract(now).TotalSeconds <= 0)
uptodate.Add(job.Value);
}
}
foreach (var job in uptodate)
{
job.Cmd.Exec();
job.NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval));
}
Thread.Sleep(2000);
}
// ReSharper disable once FunctionNeverReturns
});
}
public void AddRepository(string repo)
{
var job = new Job
{
Cmd = new Commands.Fetch(repo, "--all", true, false, null) { RaiseError = false },
NextRunTimepoint = DateTime.Now.AddMinutes(Convert.ToDouble(Interval)),
};
lock (_lock)
{
_jobs[repo] = job;
}
}
public void RemoveRepository(string repo)
{
lock (_lock)
{
_jobs.Remove(repo);
}
}
public void MarkFetched(string repo)
{
lock (_lock)
{
if (_jobs.TryGetValue(repo, out var value))
value.NextRunTimepoint = DateTime.Now.AddMinutes(Interval * 1.0);
}
}
}
}

View file

@ -20,15 +20,31 @@ namespace SourceGit.Models
void OnAvatarResourceChanged(string email);
}
public static partial class AvatarManager
public partial class AvatarManager
{
public static string SelectedServer
public static AvatarManager Instance
{
get;
set;
} = "https://www.gravatar.com/avatar/";
get
{
if (_instance == null)
_instance = new AvatarManager();
static AvatarManager()
return _instance;
}
}
private static AvatarManager _instance = null;
[GeneratedRegex(@"^(?:(\d+)\+)?(.+?)@users\.noreply\.github\.com$")]
private static partial Regex REG_GITHUB_USER_EMAIL();
private object _synclock = new object();
private string _storePath;
private List<IAvatarHost> _avatars = new List<IAvatarHost>();
private Dictionary<string, Bitmap> _resources = new Dictionary<string, Bitmap>();
private HashSet<string> _requesting = new HashSet<string>();
public void Start()
{
_storePath = Path.Combine(Native.OS.DataDir, "avatars");
if (!Directory.Exists(_storePath))
@ -62,7 +78,7 @@ namespace SourceGit.Models
var matchGithubUser = REG_GITHUB_USER_EMAIL().Match(email);
var url = matchGithubUser.Success ?
$"https://avatars.githubusercontent.com/{matchGithubUser.Groups[2].Value}" :
$"{SelectedServer}{md5}?d=404";
$"https://www.gravatar.com/avatar/{md5}?d=404";
var localFile = Path.Combine(_storePath, md5);
var img = null as Bitmap;
@ -105,20 +121,22 @@ namespace SourceGit.Models
NotifyResourceChanged(email);
});
}
// ReSharper disable once FunctionNeverReturns
});
}
public static void Subscribe(IAvatarHost host)
public void Subscribe(IAvatarHost host)
{
_avatars.Add(host);
}
public static void Unsubscribe(IAvatarHost host)
public void Unsubscribe(IAvatarHost host)
{
_avatars.Remove(host);
}
public static Bitmap Request(string email, bool forceRefetch)
public Bitmap Request(string email, bool forceRefetch)
{
if (forceRefetch)
{
@ -167,7 +185,7 @@ namespace SourceGit.Models
return null;
}
private static string GetEmailHash(string email)
private string GetEmailHash(string email)
{
var lowered = email.ToLower(CultureInfo.CurrentCulture).Trim();
var hash = MD5.Create().ComputeHash(Encoding.Default.GetBytes(lowered));
@ -177,21 +195,12 @@ namespace SourceGit.Models
return builder.ToString();
}
private static void NotifyResourceChanged(string email)
private void NotifyResourceChanged(string email)
{
foreach (var avatar in _avatars)
{
avatar.OnAvatarResourceChanged(email);
}
}
private static readonly object _synclock = new object();
private static readonly string _storePath;
private static readonly List<IAvatarHost> _avatars = new List<IAvatarHost>();
private static readonly Dictionary<string, Bitmap> _resources = new Dictionary<string, Bitmap>();
private static readonly HashSet<string> _requesting = new HashSet<string>();
[GeneratedRegex(@"^(?:(\d+)\+)?(.+?)@users\.noreply\.github\.com$")]
private static partial Regex REG_GITHUB_USER_EMAIL();
}
}