1- global  using  CMN  =  System . Runtime . CompilerServices . CallerMemberNameAttribute ; 
1+ global  using  EC  =  System . Runtime . CompilerServices . EnumeratorCancellationAttribute ; 
2+ global  using  CMN  =  System . Runtime . CompilerServices . CallerMemberNameAttribute ; 
23global  using  JI  =  System . Text . Json . Serialization . JsonIgnoreAttribute ; 
34global  using  ICBN  =  JetBrains . Annotations . ItemCanBeNullAttribute ; 
45global  using  INN  =  JetBrains . Annotations . ItemNotNullAttribute ; 
3435using  SmartImage . Lib . Results . Data ; 
3536using  static  System . Runtime . InteropServices . JavaScript . JSType ; 
3637using  SmartImage . Lib . Utilities . Diagnostics ; 
38+ using  Kantan . Monad ; 
3739
3840namespace  SmartImage . Lib ; 
3941
@@ -62,12 +64,13 @@ public SearchClient(SearchConfig cfg)
6264
6365	} 
6466
65- 	static   SearchClient ( ) 
66- 	{  } 
67+ 	static   SearchClient ( )  {  } 
6768
6869	[ ModuleInitializer ] 
6970	public  static   void  Init ( ) 
7071	{ 
72+ 		Trace . AutoFlush  =  true ; 
73+ 		Debug . AutoFlush  =  true ; 
7174		s_logger . LogInformation ( "Init" ) ; 
7275
7376
@@ -99,23 +102,27 @@ public void OpenChannel()
99102	{ 
100103		var  ok  =  ResultChannel ? . Writer . TryComplete ( new  ChannelClosedException ( "Reopened channel" ) ) ; 
101104
102- 		if  ( ok . HasValue  &&  ok . Value )  {  } 
105+ 		if  ( ok . HasValue  &&  ok . Value )  { 
106+ 			// ... 
107+ 		} 
103108
104109		ResultChannel  =  Channel . CreateUnbounded < SearchResult > ( new  UnboundedChannelOptions ( ) 
105110		{ 
106111			SingleWriter  =  true , 
112+ 
107113		} ) ; 
108114	} 
109115
116+ #if OLD 
110117	/// <summary> 
111118	/// Runs a search of <paramref name="query"/>. 
112119	/// </summary> 
113120	/// <param name="query">Search query</param> 
114121	/// <param name="scheduler"></param> 
115122	/// <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 ) 
119126	{ 
120127		scheduler  ??=  TaskScheduler . Default ; 
121128
@@ -140,12 +147,12 @@ public async Task<SearchResult[]> RunSearchAsync(SearchQuery query,
140147
141148		Debug . WriteLine ( $ "Config: { Config }  | { Engines . QuickJoin ( ) } ") ; 
142149
143- 		List < Task < SearchResult > >  tasks  =  GetSearchTasks ( query ,  scheduler ,  token ) . ToList ( ) ; 
150+ 		var  tasks  =  GetSearchTasks ( query ,  scheduler ,  token ) ; 
144151
145- 		var  results  =  new  SearchResult [ tasks . Count ] ; 
146- 		int  i         =  0 ; 
152+ 		//  var results = new SearchResult[tasks.Count];
153+ 		int  i  =  0 ; 
147154
148- 		while  ( tasks . Count  >  0 )  { 
155+ 		/* while (tasks.Count > 0) {
149156			if (token.IsCancellationRequested) { 
150157
151158				Debugger.Break(); 
@@ -164,6 +171,19 @@ public async Task<SearchResult[]> RunSearchAsync(SearchQuery query,
164171
165172			results[i] = result; 
166173			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 ) ; 
167187		} 
168188
169189		CompleteSearchAsync ( ) ; 
@@ -191,8 +211,60 @@ public async Task<SearchResult[]> RunSearchAsync(SearchQuery query,
191211
192212		return  results ; 
193213	} 
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+ 	} 
194266
195- 	public  static   SearchResultItem  GetBest ( SearchResult [ ]  results ) 
267+ 	public  static   SearchResultItem  GetBest ( IEnumerable < SearchResult >  results ) 
196268	{ 
197269		var  ordered  =  results . Select ( x =>  x . GetBestResult ( ) ) 
198270			. Where ( x =>  x  !=  null ) 
@@ -259,16 +331,10 @@ public IEnumerable<Task<SearchResult>> GetSearchTasks(SearchQuery query, TaskSch
259331	{ 
260332		var  tasks  =  Engines . Select ( e => 
261333		{ 
262- 			try  { 
334+ 			/* try {
263335				Debug.WriteLine($"Starting {e} for {query}"); 
264336
265- 				Task < SearchResult >  res  =  e . GetResultAsync ( query ,  token :  token ) 
266- 					. ContinueWith ( ( r )  => 
267- 					{ 
268- 						ProcessResult ( r . Result ) ; 
269- 						return  r . Result ; 
270337
271- 					} ,  token ,  TaskContinuationOptions . None ,  scheduler ) ; 
272338
273339				return res; 
274340			} 
@@ -279,7 +345,19 @@ public IEnumerable<Task<SearchResult>> GetSearchTasks(SearchQuery query, TaskSch
279345				// return  Task.FromException(exception); 
280346			} 
281347
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 ; 
283361		} ) ; 
284362
285363		return  tasks ; 
@@ -306,7 +384,7 @@ public async ValueTask LoadEnginesAsync(CancellationToken token = default)
306384		} 
307385
308386		if  ( Config . FlareSolverr  &&  ! FlareSolverrClient . Value . IsInitialized )  { 
309- 			 
387+ 
310388
311389			var  ok  =  FlareSolverrClient . Value . Configure ( Config . FlareSolverrApiUrl ) ; 
312390
@@ -360,4 +438,4 @@ public void Dispose()
360438		ResultChannel ? . Writer . Complete ( ) ; 
361439	} 
362440
363- } 
441+ } 
0 commit comments