1
- using System . Collections . Concurrent ;
2
1
using System . Diagnostics ;
3
2
using NTorSpectator . Observer . TorIntegration ;
4
3
using NTorSpectator . Services ;
@@ -23,13 +22,15 @@ public class SpectatorJob : IJob
23
22
24
23
private readonly ILogger < SpectatorJob > _logger ;
25
24
private readonly ISitesCatalogue _sitesCatalogue ;
26
- private readonly IServiceProvider _services ;
27
-
28
- public SpectatorJob ( ILogger < SpectatorJob > logger , ISitesCatalogue sitesCatalogue , IServiceProvider services )
25
+ private readonly TorControlManager _torControl ;
26
+ private readonly ISiteObserver _siteObserver ;
27
+
28
+ public SpectatorJob ( ILogger < SpectatorJob > logger , ISitesCatalogue sitesCatalogue , TorControlManager torControl , ISiteObserver siteObserver )
29
29
{
30
30
_logger = logger ;
31
31
_sitesCatalogue = sitesCatalogue ;
32
- _services = services ;
32
+ _torControl = torControl ;
33
+ _siteObserver = siteObserver ;
33
34
}
34
35
35
36
public async Task Execute ( IJobExecutionContext context )
@@ -39,74 +40,50 @@ public async Task Execute(IJobExecutionContext context)
39
40
_logger . LogDebug ( "Starting sites observations" ) ;
40
41
var sites = await _sitesCatalogue . GetAllSites ( ) ;
41
42
_logger . LogDebug ( "Got {Count} sites to observe" , sites . Count ) ;
42
- var queuedSites = sites . Select ( x => new QueuedSite ( x , 0 ) ) ;
43
- var siteQueue = new ConcurrentQueue < QueuedSite > ( queuedSites ) ;
44
- while ( true )
43
+
44
+ var siteQueue = new Queue < QueuedSite > ( sites . Select ( x => new QueuedSite ( x , 0 ) ) ) ;
45
+ while ( siteQueue . TryDequeue ( out var queuedSite ) )
45
46
{
46
47
QueueLength . Set ( siteQueue . Count ) ;
47
- if ( ! siteQueue . Any ( ) )
48
- break ;
49
- var chunk = TryDequeueMax ( siteQueue , 4 ) ;
50
- var tasks = chunk . Select ( x => TryCheckSite ( x , s => siteQueue . Enqueue ( s ) ) ) . ToArray ( ) ;
51
- await Task . WhenAll ( tasks ) ;
52
- }
53
- _logger . LogDebug ( "The queue is finally empty, observations finished" ) ;
54
- sw . Stop ( ) ;
55
- TotalSessionDuration . Set ( sw . ElapsedMilliseconds ) ;
56
- }
57
-
58
-
59
- private QueuedSite [ ] TryDequeueMax ( ConcurrentQueue < QueuedSite > queue , int max )
60
- {
61
- var result = new List < QueuedSite > ( max ) ;
62
- for ( int i = 0 ; i < max ; ++ i )
63
- {
64
- if ( queue . TryDequeue ( out var item ) )
65
- result . Add ( item ) ;
66
- }
67
- return result . ToArray ( ) ;
68
- }
69
-
70
- private async Task TryCheckSite ( QueuedSite queuedSite , Action < QueuedSite > putBackIntoQueue )
71
- {
72
- using var _ = _logger . BeginScope ( new Dictionary < string , object > { { "HiddenService" , queuedSite . Site . SiteUri } } ) ;
73
- using var scope = _services . CreateScope ( ) ;
74
- var torControl = scope . ServiceProvider . GetRequiredService < TorControlManager > ( ) ;
75
- var siteObserver = scope . ServiceProvider . GetRequiredService < ISiteObserver > ( ) ;
76
- _logger . LogDebug ( "Starting observations on the next site" ) ;
77
- try
78
- {
79
- var observations = await ObserveSite ( queuedSite . Site . SiteUri , torControl ) ;
80
- ObservationsCount . Inc ( ) ;
81
- if ( ! observations . IsOk )
48
+ using var _ = _logger . BeginScope ( new Dictionary < string , object > { { "HiddenService" , queuedSite . Site . SiteUri } } ) ;
49
+ _logger . LogDebug ( "Starting observations on the next site" ) ;
50
+ try
82
51
{
83
- _logger . LogDebug ( "Site observed as not available" ) ;
84
- var siteObservationsCount = queuedSite . ObservationsCount ;
85
- if ( siteObservationsCount < 3 )
52
+ var observations = await ObserveSite ( queuedSite . Site . SiteUri ) ;
53
+ ObservationsCount . Inc ( ) ;
54
+ if ( ! observations . IsOk )
86
55
{
87
- _logger . LogDebug ( "Site has been observed {Count} times, returning it to queue" , siteObservationsCount ) ;
88
- putBackIntoQueue ( queuedSite with { ObservationsCount = siteObservationsCount + 1 } ) ;
89
- RetriesCount . Inc ( ) ;
90
- return ;
56
+ _logger . LogDebug ( "Site observed as not available" ) ;
57
+ var siteObservationsCount = queuedSite . ObservationsCount ;
58
+ if ( siteObservationsCount < 3 )
59
+ {
60
+ _logger . LogDebug ( "Site has been observed {Count} times, returning it to queue" , siteObservationsCount ) ;
61
+ siteQueue . Enqueue ( queuedSite with { ObservationsCount = siteObservationsCount + 1 } ) ;
62
+ RetriesCount . Inc ( ) ;
63
+ continue ;
64
+ }
91
65
}
66
+ _logger . LogDebug ( "Site seems to be up" ) ;
67
+ await _siteObserver . AddNewObservation ( queuedSite . Site . SiteUri , observations . IsOk ) ;
68
+ SiteStatus . WithLabels ( queuedSite . Site . SiteUri ) . Set ( observations . IsOk ? 1 : 0 ) ;
69
+ _logger . LogInformation ( "Site observed" ) ;
70
+ }
71
+ catch ( Exception e )
72
+ {
73
+ _logger . LogError ( e , "Observation for site failed" ) ;
92
74
}
93
- _logger . LogDebug ( "Site seems to be up" ) ;
94
- await siteObserver . AddNewObservation ( queuedSite . Site . SiteUri , observations . IsOk ) ;
95
- SiteStatus . WithLabels ( queuedSite . Site . SiteUri ) . Set ( observations . IsOk ? 1 : 0 ) ;
96
- _logger . LogInformation ( "Site observed" ) ;
97
- }
98
- catch ( Exception e )
99
- {
100
- _logger . LogError ( e , "Observation for site failed" ) ;
101
75
}
76
+ _logger . LogDebug ( "The queue is finally empty, observations finished" ) ;
77
+ sw . Stop ( ) ;
78
+ TotalSessionDuration . Set ( sw . ElapsedMilliseconds ) ;
102
79
}
103
-
80
+
104
81
private record QueuedSite ( Site Site , int ObservationsCount ) ;
105
82
106
- private async Task < TorWatchResults > ObserveSite ( string site , TorControlManager torControl )
83
+ private async Task < TorWatchResults > ObserveSite ( string site )
107
84
{
108
85
using var _ = RequestDuration . NewTimer ( ) ;
109
- var torReply = await torControl . HsFetch ( site ) ;
86
+ var torReply = await _torControl . HsFetch ( site ) ;
110
87
var positive = torReply . Count ( x => x . Action == HsDescAction . Received ) ;
111
88
var negative = torReply . Count ( x => x . Action == HsDescAction . Failed ) ;
112
89
return new ( site , positive , negative ) ;
0 commit comments