|
@@ -21,6 +21,8 @@ import re
|
21
|
21
|
from itertools import izip_longest, chain
|
22
|
22
|
from datetime import datetime
|
23
|
23
|
from operator import itemgetter
|
|
24
|
+from Queue import Queue
|
|
25
|
+from time import time
|
24
|
26
|
from urlparse import urlparse, unquote
|
25
|
27
|
from searx.engines import (
|
26
|
28
|
categories, engines
|
|
@@ -34,6 +36,8 @@ number_of_searches = 0
|
34
|
36
|
|
35
|
37
|
|
36
|
38
|
def threaded_requests(requests):
|
|
39
|
+ timeout_limit = max(r[2]['timeout'] for r in requests)
|
|
40
|
+ search_start = time()
|
37
|
41
|
for fn, url, request_args in requests:
|
38
|
42
|
th = threading.Thread(
|
39
|
43
|
target=fn,
|
|
@@ -45,7 +49,11 @@ def threaded_requests(requests):
|
45
|
49
|
|
46
|
50
|
for th in threading.enumerate():
|
47
|
51
|
if th.name == 'search_request':
|
48
|
|
- th.join()
|
|
52
|
+ remaining_time = max(0.0, timeout_limit - (time() - search_start))
|
|
53
|
+ th.join(remaining_time)
|
|
54
|
+ if th.isAlive():
|
|
55
|
+ print('engine timeout')
|
|
56
|
+
|
49
|
57
|
|
50
|
58
|
|
51
|
59
|
# get default reqest parameter
|
|
@@ -56,7 +64,7 @@ def default_request_params():
|
56
|
64
|
|
57
|
65
|
# create a callback wrapper for the search engine results
|
58
|
66
|
def make_callback(engine_name,
|
59
|
|
- results,
|
|
67
|
+ results_queue,
|
60
|
68
|
suggestions,
|
61
|
69
|
answers,
|
62
|
70
|
infoboxes,
|
|
@@ -74,7 +82,7 @@ def make_callback(engine_name,
|
74
|
82
|
except Exception, e:
|
75
|
83
|
# increase errors stats
|
76
|
84
|
engines[engine_name].stats['errors'] += 1
|
77
|
|
- results[engine_name] = cb_res
|
|
85
|
+ results_queue.put_nowait((engine_name, cb_res))
|
78
|
86
|
|
79
|
87
|
# print engine name and specific error message
|
80
|
88
|
print '[E] Error with engine "{0}":\n\t{1}'.format(
|
|
@@ -104,7 +112,7 @@ def make_callback(engine_name,
|
104
|
112
|
# append result
|
105
|
113
|
cb_res.append(result)
|
106
|
114
|
|
107
|
|
- results[engine_name] = cb_res
|
|
115
|
+ results_queue.put_nowait((engine_name, cb_res))
|
108
|
116
|
|
109
|
117
|
# update stats with current page-load-time
|
110
|
118
|
engines[engine_name].stats['page_load_time'] += \
|
|
@@ -420,7 +428,7 @@ class Search(object):
|
420
|
428
|
|
421
|
429
|
# init vars
|
422
|
430
|
requests = []
|
423
|
|
- results = {}
|
|
431
|
+ results_queue = Queue()
|
424
|
432
|
suggestions = set()
|
425
|
433
|
answers = set()
|
426
|
434
|
infoboxes = []
|
|
@@ -468,7 +476,7 @@ class Search(object):
|
468
|
476
|
# create a callback wrapper for the search engine results
|
469
|
477
|
callback = make_callback(
|
470
|
478
|
selected_engine['name'],
|
471
|
|
- results,
|
|
479
|
+ results_queue,
|
472
|
480
|
suggestions,
|
473
|
481
|
answers,
|
474
|
482
|
infoboxes,
|
|
@@ -502,6 +510,11 @@ class Search(object):
|
502
|
510
|
# send all search-request
|
503
|
511
|
threaded_requests(requests)
|
504
|
512
|
|
|
513
|
+ results = {}
|
|
514
|
+ while not results_queue.empty():
|
|
515
|
+ engine_name, engine_results = results_queue.get_nowait()
|
|
516
|
+ results[engine_name] = engine_results
|
|
517
|
+
|
505
|
518
|
# update engine-specific stats
|
506
|
519
|
for engine_name, engine_results in results.items():
|
507
|
520
|
engines[engine_name].stats['search_count'] += 1
|