1
- global using CMN = System . Runtime . CompilerServices . CallerMemberNameAttribute ;
1
+ global using EC = System . Runtime . CompilerServices . EnumeratorCancellationAttribute ;
2
+ global using CMN = System . Runtime . CompilerServices . CallerMemberNameAttribute ;
2
3
global using JI = System . Text . Json . Serialization . JsonIgnoreAttribute ;
3
4
global using ICBN = JetBrains . Annotations . ItemCanBeNullAttribute ;
4
5
global using INN = JetBrains . Annotations . ItemNotNullAttribute ;
34
35
using SmartImage . Lib . Results . Data ;
35
36
using static System . Runtime . InteropServices . JavaScript . JSType ;
36
37
using SmartImage . Lib . Utilities . Diagnostics ;
38
+ using Kantan . Monad ;
37
39
38
40
namespace SmartImage . Lib ;
39
41
@@ -62,12 +64,13 @@ public SearchClient(SearchConfig cfg)
62
64
63
65
}
64
66
65
- static SearchClient ( )
66
- { }
67
+ static SearchClient ( ) { }
67
68
68
69
[ ModuleInitializer ]
69
70
public static void Init ( )
70
71
{
72
+ Trace . AutoFlush = true ;
73
+ Debug . AutoFlush = true ;
71
74
s_logger . LogInformation ( "Init" ) ;
72
75
73
76
@@ -99,23 +102,27 @@ public void OpenChannel()
99
102
{
100
103
var ok = ResultChannel ? . Writer . TryComplete ( new ChannelClosedException ( "Reopened channel" ) ) ;
101
104
102
- if ( ok . HasValue && ok . Value ) { }
105
+ if ( ok . HasValue && ok . Value ) {
106
+ // ...
107
+ }
103
108
104
109
ResultChannel = Channel . CreateUnbounded < SearchResult > ( new UnboundedChannelOptions ( )
105
110
{
106
111
SingleWriter = true ,
112
+
107
113
} ) ;
108
114
}
109
115
116
+ #if OLD
110
117
/// <summary>
111
118
/// Runs a search of <paramref name="query"/>.
112
119
/// </summary>
113
120
/// <param name="query">Search query</param>
114
121
/// <param name="scheduler"></param>
115
122
/// <param name="token">Cancellation token passed to <see cref="WebSearchEngine{T}.GetResultAsync(SmartImage.Lib.SearchQuery,System.Threading.CancellationToken)"/></param>
116
- public async Task < SearchResult [ ] > RunSearchAsync ( SearchQuery query ,
117
- TaskScheduler scheduler = default ,
118
- CancellationToken token = default )
123
+ public async Task < SearchResult [ ] > RunSearchAsync1 ( SearchQuery query ,
124
+ TaskScheduler scheduler = default ,
125
+ CancellationToken token = default )
119
126
{
120
127
scheduler ??= TaskScheduler . Default ;
121
128
@@ -140,12 +147,12 @@ public async Task<SearchResult[]> RunSearchAsync(SearchQuery query,
140
147
141
148
Debug . WriteLine ( $ "Config: { Config } | { Engines . QuickJoin ( ) } ") ;
142
149
143
- List < Task < SearchResult > > tasks = GetSearchTasks ( query , scheduler , token ) . ToList ( ) ;
150
+ var tasks = GetSearchTasks ( query , scheduler , token ) ;
144
151
145
- var results = new SearchResult [ tasks . Count ] ;
146
- int i = 0 ;
152
+ // var results = new SearchResult[tasks.Count];
153
+ int i = 0 ;
147
154
148
- while ( tasks . Count > 0 ) {
155
+ /* while (tasks.Count > 0) {
149
156
if (token.IsCancellationRequested) {
150
157
151
158
Debugger.Break();
@@ -164,6 +171,19 @@ public async Task<SearchResult[]> RunSearchAsync(SearchQuery query,
164
171
165
172
results[i] = result;
166
173
i++;
174
+ }*/
175
+
176
+
177
+ await foreach ( var task in Task . WhenEach ( tasks ) . WithCancellation ( token ) ) {
178
+ if ( token . IsCancellationRequested ) {
179
+
180
+ Debugger . Break ( ) ;
181
+ s_logger . LogWarning ( "Cancellation requested" ) ;
182
+ CompleteSearchAsync ( ) ;
183
+ }
184
+
185
+ var result = await task ;
186
+ ProcessResult ( result ) ;
167
187
}
168
188
169
189
CompleteSearchAsync ( ) ;
@@ -191,8 +211,60 @@ public async Task<SearchResult[]> RunSearchAsync(SearchQuery query,
191
211
192
212
return results ;
193
213
}
214
+ #endif
215
+
216
+ public async IAsyncEnumerable < SearchResult > RunSearchAsync ( SearchQuery query ,
217
+ TaskScheduler scheduler = default ,
218
+ [ EC ] CancellationToken token = default )
219
+ {
220
+ await RunSearchAsync2 ( query , ResultChannel . Writer , token ) ;
221
+
222
+ await foreach ( var result in ResultChannel . Reader . ReadAllAsync ( token ) ) {
223
+ yield return result ;
224
+ }
225
+ }
226
+
227
+
228
+ /// <summary>
229
+ /// Runs a search of <paramref name="query"/>.
230
+ /// </summary>
231
+ public async ValueTask < bool > RunSearchAsync2 ( SearchQuery query ,
232
+ ChannelWriter < SearchResult > cw ,
233
+ CancellationToken token = default )
234
+ {
235
+ if ( ! query . IsUploaded ) {
236
+ throw new SmartImageException ( $ "{ query } was not uploaded") ;
237
+ }
238
+
239
+ var tasks = Engines . Select ( e =>
240
+ {
241
+ var task = e . GetResultAsync ( query , token ) ;
242
+ return task ;
243
+ } ) ;
244
+
245
+ await foreach ( var task in Task . WhenEach ( tasks ) . WithCancellation ( token ) ) {
246
+
247
+ var result = await task ;
248
+
249
+ if ( task . IsFaulted || task . IsCanceled ) {
250
+ Trace . WriteLine ( $ "{ task } faulted or was canceled") ;
251
+ }
252
+
253
+ if ( cw . TryWrite ( result ) ) {
254
+ //
255
+ }
256
+
257
+ if ( Config . PriorityEngines . HasFlag ( result . Engine . EngineOption ) ) {
258
+ var url = Config . OpenRaw ? result . RawUrl : result . GetBestResult ( ) ? . Url ;
259
+
260
+ OpenResult ( url ) ;
261
+ }
262
+ }
263
+
264
+ return default ;
265
+ }
194
266
195
- public static SearchResultItem GetBest ( SearchResult [ ] results )
267
+ public static SearchResultItem GetBest ( IEnumerable < SearchResult > results )
196
268
{
197
269
var ordered = results . Select ( x => x . GetBestResult ( ) )
198
270
. Where ( x => x != null )
@@ -259,16 +331,10 @@ public IEnumerable<Task<SearchResult>> GetSearchTasks(SearchQuery query, TaskSch
259
331
{
260
332
var tasks = Engines . Select ( e =>
261
333
{
262
- try {
334
+ /* try {
263
335
Debug.WriteLine($"Starting {e} for {query}");
264
336
265
- Task < SearchResult > res = e . GetResultAsync ( query , token : token )
266
- . ContinueWith ( ( r ) =>
267
- {
268
- ProcessResult ( r . Result ) ;
269
- return r . Result ;
270
337
271
- } , token , TaskContinuationOptions . None , scheduler ) ;
272
338
273
339
return res;
274
340
}
@@ -279,7 +345,19 @@ public IEnumerable<Task<SearchResult>> GetSearchTasks(SearchQuery query, TaskSch
279
345
// return Task.FromException(exception);
280
346
}
281
347
282
- return default ;
348
+ return default;*/
349
+
350
+ /*Task<SearchResult> res = e.GetResultAsync(query, token: token)
351
+ .ContinueWith((r) =>
352
+ {
353
+ ProcessResult(r.Result);
354
+ return r.Result;
355
+
356
+ }, token, TaskContinuationOptions.None, scheduler)*/
357
+ ;
358
+
359
+ Task < SearchResult > res = e . GetResultAsync ( query , token : token ) ;
360
+ return res ;
283
361
} ) ;
284
362
285
363
return tasks ;
@@ -306,7 +384,7 @@ public async ValueTask LoadEnginesAsync(CancellationToken token = default)
306
384
}
307
385
308
386
if ( Config . FlareSolverr && ! FlareSolverrClient . Value . IsInitialized ) {
309
-
387
+
310
388
311
389
var ok = FlareSolverrClient . Value . Configure ( Config . FlareSolverrApiUrl ) ;
312
390
@@ -360,4 +438,4 @@ public void Dispose()
360
438
ResultChannel ? . Writer . Complete ( ) ;
361
439
}
362
440
363
- }
441
+ }
0 commit comments