Skip to content

Commit 66524d3

Browse files
committed
Give processables the ability to defer their next processing. Make Threads/Boards use this to obey the newly named "MinSecondsBetweenScrapes" setting
1 parent 32e9ecc commit 66524d3

13 files changed

+183
-143
lines changed

GChan/App.config

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@
1313
<setting name="SavePath" serializeAs="String">
1414
<value>C:\GChan</value>
1515
</setting>
16-
<setting name="ScanTimer" serializeAs="String">
17-
<value>60000</value>
16+
<setting name="MinSecondsBetweenScrapes" serializeAs="String">
17+
<value>60</value>
1818
</setting>
1919
<setting name="SaveHtml" serializeAs="String">
2020
<value>False</value>

GChan/Forms/SettingsForm.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ private void Settings_Shown(object sender, EventArgs e)
6868
directory = Settings.Default.SavePath;
6969
directoryTextBox.Text = directory;
7070

71-
timerNumeric.Value = (Settings.Default.ScanTimer / 1000);
71+
minSecondsBetweenScrapesNumeric.Value = Settings.Default.MinSecondsBetweenScrapes;
7272
max1RequestPerSecondCheckBox.Checked = Settings.Default.Max1RequestPerSecond;
7373
concurrentDownloadsNumeric.Value = Settings.Default.MaximumConcurrentDownloads;
7474

@@ -96,7 +96,7 @@ private void buttonSave_Click(object sender, EventArgs e)
9696
return;
9797
}
9898

99-
if (timerNumeric.Value < 5)
99+
if (minSecondsBetweenScrapesNumeric.Value < 5)
100100
{
101101
MessageBox.Show("Timer must be greater than 5 seconds.");
102102
return;
@@ -115,7 +115,7 @@ private void SaveSettings()
115115
{
116116
Settings.Default.UserAgent = userAgentTextBox.Text;
117117
Settings.Default.SavePath = directory;
118-
Settings.Default.ScanTimer = (int)timerNumeric.Value * 1000;
118+
Settings.Default.MinSecondsBetweenScrapes = (int)minSecondsBetweenScrapesNumeric.Value;
119119
Settings.Default.Max1RequestPerSecond = max1RequestPerSecondCheckBox.Checked;
120120
Settings.Default.MaximumConcurrentDownloads = (int)concurrentDownloadsNumeric.Value;
121121
Settings.Default.ImageFilenameFormat = (byte)imageFilenameFormatComboBox.SelectedIndex;

GChan/Forms/SettingsForm.designer.cs

+117-117
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

GChan/Models/Thumbnail.cs

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public class Thumbnail : IAsset, IEquatable<Thumbnail>
2121

2222
public bool ShouldProcess => Settings.Default.SaveThumbnails && thread.ShouldProcess;
2323

24+
public DateTimeOffset? ReadyToProcessAt => null;
25+
2426
/// <summary>
2527
/// URL to download the thumbnail.
2628
/// </summary>

GChan/Models/Trackers/Board.cs

+3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using GChan.Data.Models;
2+
using GChan.Properties;
23
using GChan.Services;
34
using System;
45
using System.Linq;
@@ -48,6 +49,8 @@ public int ThreadCount
4849

4950
public bool ShouldProcess => !cancellationTokenSource.IsCancellationRequested;
5051

52+
public DateTimeOffset? ReadyToProcessAt => LastScrape + TimeSpan.FromSeconds(Settings.Default.MinSecondsBetweenScrapes);
53+
5154
protected Board(string url) : base(url)
5255
{
5356
Type = Type.Board;

GChan/Models/Trackers/Thread.cs

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public abstract class Thread : Tracker, IProcessable, INotifyPropertyChanged
3333

3434
public bool ShouldProcess => !Gone && !cancellationTokenSource.IsCancellationRequested;
3535

36+
public DateTimeOffset? ReadyToProcessAt => LastScrape + TimeSpan.FromSeconds(Settings.Default.MinSecondsBetweenScrapes);
37+
3638
public string Subject
3739
{
3840
get => subject ?? NO_SUBJECT;

GChan/Models/Trackers/Tracker.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public abstract class Tracker
3939
/// When this tracker was last succesfully scraped, null if not yet scraped.<br/>
4040
/// <see cref="DateTimeOffset"/> because that's what HttpClient header property accepts.
4141
/// </summary>
42-
public DateTimeOffset? LastScrape { get; internal set; }
42+
public DateTimeOffset? LastScrape { get; protected set; }
4343

4444
/// <summary>
4545
/// Whether or not to keep scraping this tracker.

GChan/Models/Upload.cs

+2
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ public class Upload : IAsset, IEquatable<Upload>
5959

6060
public bool ShouldProcess => Thread.ShouldProcess;
6161

62+
public DateTimeOffset? ReadyToProcessAt => null;
63+
6264
public Upload(
6365
long tim,
6466
string url,

GChan/Properties/Settings.Designer.cs

+4-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

GChan/Properties/Settings.settings

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
<Setting Name="SavePath" Type="System.String" Scope="User">
66
<Value Profile="(Default)">C:\GChan</Value>
77
</Setting>
8-
<Setting Name="ScanTimer" Type="System.Int32" Scope="User">
9-
<Value Profile="(Default)">60000</Value>
8+
<Setting Name="MinSecondsBetweenScrapes" Type="System.Int32" Scope="User">
9+
<Value Profile="(Default)">60</Value>
1010
</Setting>
1111
<Setting Name="SaveHtml" Type="System.Boolean" Scope="User">
1212
<Value Profile="(Default)">False</Value>

GChan/Services/IProcessable.cs

+9-3
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,18 @@ public interface IProcessable : IAsyncDisposable
4848
public CancellationToken CancellationToken { get; }
4949

5050
/// <summary>
51-
/// Should this item be downloaded.<br/>
52-
/// Decision may have changed since being added to download manager.<br/>
53-
/// If this ever goes false it should never go back to being true.
51+
/// Should this item be processed<br/>
52+
/// Decision may have changed since being added to queue.<br/>
53+
/// If this ever goes false it should never go back to being true, thus it should be discarded from the queue.
5454
/// </summary>
5555
public bool ShouldProcess { get; }
5656

57+
/// <summary>
58+
/// When will this processable by ready to process.<br/>
59+
/// Set to null for any time, otherwise the item is deferred until it is next found in the queue with a ready time.
60+
/// </summary>
61+
public DateTimeOffset? ReadyToProcessAt { get; }
62+
5763
/// <summary>
5864
/// Perform download for this item.<br/>
5965
/// Must never throw, must always return a <see cref="ProcessResult"/>.

GChan/Services/ProcessQueue.cs

+35-10
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
using GChan.Models.Trackers;
22
using GChan.Properties;
3+
using NetTopologySuite.Triangulate.QuadEdge;
34
using NLog;
45
using System;
56
using System.Collections.Concurrent;
7+
using System.Collections.Generic;
68
using System.Threading;
79
using System.Threading.Tasks;
10+
using System.Windows.Documents;
811

912
#nullable enable
1013

@@ -78,22 +81,44 @@ public async Task WorkAsync()
7881
/// </summary>
7982
private IProcessable? MaybeDequeue()
8083
{
81-
while (true)
84+
var deferredProcessables = new List<IProcessable>();
85+
86+
try
8287
{
83-
if (queue.TryDequeue(out var processable))
88+
while (true)
8489
{
85-
if (processable.ShouldProcess)
90+
if (queue.TryDequeue(out var processable))
8691
{
87-
logger.Trace("Dequeued processable {0}.", processable);
88-
return processable;
92+
if (processable.ShouldProcess)
93+
{
94+
if (processable.ReadyToProcessAt == null || processable.ReadyToProcessAt <= DateTimeOffset.Now)
95+
{
96+
logger.Trace("Dequeued processable {0}.", processable);
97+
return processable;
98+
}
99+
else
100+
{
101+
deferredProcessables.Add(processable);
102+
logger.Trace("Deferring processable {0}. Ready to process at {1}.", processable, processable.ReadyToProcessAt);
103+
}
104+
}
105+
else
106+
{
107+
logger.Trace("Discarding dequeued processable {0}.", processable);
108+
}
109+
}
110+
else
111+
{
112+
logger.Trace("Processable queue empty.");
113+
return null;
89114
}
90-
91-
logger.Trace("Discarding dequeued processable {0}.", processable);
92115
}
93-
else
116+
}
117+
finally
118+
{
119+
foreach (var deferredProcessable in deferredProcessables)
94120
{
95-
logger.Trace("Processable queue empty.");
96-
return null;
121+
queue.Enqueue(deferredProcessable);
97122
}
98123
}
99124
}

GChan/ViewModels/MainFormModel.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public string NotificationTrayTooltip
3535
{
3636
get
3737
{
38-
return $"Scraping {Threads.Count} thread{(Threads.Count != 1 ? "s" : "")} and {Boards.Count} board{(Boards.Count != 1 ? "s" : "")} every {Settings.Default.ScanTimer / 60 / 1000} minute{(Settings.Default.ScanTimer / 60 / 1000 != 1 ? "s" : "")}." +
38+
return $"Scraping {Threads.Count} thread{(Threads.Count != 1 ? "s" : "")} and {Boards.Count} board{(Boards.Count != 1 ? "s" : "")} every {Settings.Default.MinSecondsBetweenScrapes / 60 / 1000} minute{(Settings.Default.MinSecondsBetweenScrapes / 60 / 1000 != 1 ? "s" : "")}." +
3939
"\nClick to show/hide.";
4040
}
4141
}

0 commit comments

Comments
 (0)