mirror of
https://github.com/searxng/searxng.git
synced 2026-07-17 21:41:24 +00:00
[fix] clarify the mess of Engine.setup and Engine.init (#6343)
Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
This commit is contained in:
@@ -361,37 +361,43 @@ class Engine(abc.ABC): # pylint: disable=too-few-public-methods
|
|||||||
https: socks5://proxy:port
|
https: socks5://proxy:port
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def setup(self, engine_settings: dict[str, t.Any]) -> bool: # pylint: disable=unused-argument
|
def setup(self, engine_settings: dict[str, t.Any]) -> bool | None: # pylint: disable=unused-argument
|
||||||
"""Dynamic setup of the engine settings.
|
"""Dynamic setup of the engine settings.
|
||||||
|
|
||||||
With this method, the engine's setup is carried out. For example, to
|
With this method, the engine's setup is carried out. For example, to
|
||||||
check or dynamically adapt the values handed over in the parameter
|
check or dynamically adapt the values handed over in the parameter
|
||||||
``engine_settings``. The return value (True/False) indicates whether
|
``engine_settings``.
|
||||||
the setup was successful and the engine can be built or rejected.
|
|
||||||
|
|
||||||
The method is optional and is called synchronously as part of the
|
Whether the initialization was successful can be indicated by the return
|
||||||
|
value ``True`` or even ``False``.
|
||||||
|
|
||||||
|
- If no return value (``None`` ) is given from this method , this is
|
||||||
|
equivalent to ``True``.
|
||||||
|
|
||||||
|
- If an exception is thrown as part of the initialization, this is
|
||||||
|
equivalent to ``False``.
|
||||||
|
|
||||||
|
The method is optional and is called **synchronously** as part of the
|
||||||
initialization of the service and is therefore only suitable for simple
|
initialization of the service and is therefore only suitable for simple
|
||||||
(local) exams/changes at the engine setting. The :py:obj:`Engine.init`
|
(local) exams/changes at the engine setting.
|
||||||
method must be used for longer tasks in which values of a remote must be
|
|
||||||
determined, for example.
|
The :py:obj:`Engine.init` method must be used for longer tasks in which
|
||||||
|
values of a remote must be determined, for example.
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def init(self, engine_settings: dict[str, t.Any]) -> bool | None: # pylint: disable=unused-argument
|
def init(self, engine_settings: dict[str, t.Any]) -> bool | None: # pylint: disable=unused-argument
|
||||||
"""Initialization of the engine.
|
"""Initialization of the engine.
|
||||||
|
|
||||||
The method is optional and asynchronous (in a thread). It is suitable,
|
The method is optional and called **asynchronous** (in a thread). The
|
||||||
for example, for setting up a cache (for the engine) or for querying
|
method is comparable to :py:obj:`Engine.setup`, it is suitable, for
|
||||||
values (required by the engine) from a remote.
|
caching data that first needs to be requested from a remote.
|
||||||
|
|
||||||
Whether the initialization was successful can be indicated by the return
|
The method is optional and runs **asynchronously** (in a thread), it is
|
||||||
value ``True`` or even ``False``.
|
comparable to :py:obj:`Engine.setup`. For instance, it is suitable for
|
||||||
|
caching data that first needs to be requested from a remote source.
|
||||||
|
|
||||||
- If no return value is given from this init method (``None``), this is
|
The evaluation of the return value is analogous to :py:obj:`Engine.setup`.
|
||||||
equivalent to ``True``.
|
|
||||||
|
|
||||||
- If an exception is thrown as part of the initialization, this is
|
|
||||||
equivalent to ``False``.
|
|
||||||
"""
|
"""
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -269,21 +269,27 @@ def is_engine_active(engine: "Engine | types.ModuleType"):
|
|||||||
|
|
||||||
|
|
||||||
def call_engine_setup(engine: "Engine | types.ModuleType", engine_data: dict[str, t.Any]) -> bool:
|
def call_engine_setup(engine: "Engine | types.ModuleType", engine_data: dict[str, t.Any]) -> bool:
|
||||||
setup_ok = False
|
|
||||||
|
setup_ok: bool | None = False
|
||||||
setup_func = getattr(engine, "setup", None)
|
setup_func = getattr(engine, "setup", None)
|
||||||
|
|
||||||
if setup_func is None:
|
if setup_func is None:
|
||||||
setup_ok = True
|
setup_ok = True
|
||||||
elif not callable(setup_func):
|
elif not callable(setup_func):
|
||||||
logger.error("engine's setup method isn't a callable (is of type: %s)", type(setup_func))
|
logger.error(f"engine's setup method isn't a callable (is of type: {type(setup_func)})")
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
setup_ok = engine.setup(engine_data)
|
setup_ok = engine.setup(engine_data)
|
||||||
except Exception as e: # pylint: disable=broad-except
|
except Exception as e: # pylint: disable=broad-except
|
||||||
logger.exception('exception : {0}'.format(e))
|
logger.exception(f"(PID {os.getpid()}) {engine.name}: engine SETUP failed, exception: {e}")
|
||||||
|
setup_ok = False
|
||||||
|
|
||||||
|
# The evaluation of the return value is analogous to Engine.init
|
||||||
|
if setup_ok is None:
|
||||||
|
setup_ok = True
|
||||||
|
|
||||||
if not setup_ok:
|
if not setup_ok:
|
||||||
logger.error("%s: Engine setup was not successful, engine is set to inactive.", engine.name)
|
logger.error(f"(PID {os.getpid()}) {engine.name}: engine setup was not successful")
|
||||||
return setup_ok
|
return setup_ok
|
||||||
|
|
||||||
|
|
||||||
@@ -311,14 +317,16 @@ def load_engines(engine_list: list[dict[str, t.Any]]):
|
|||||||
for engine_data in engine_list:
|
for engine_data in engine_list:
|
||||||
if engine_data.get("inactive") is True:
|
if engine_data.get("inactive") is True:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
engine = load_engine(engine_data)
|
engine = load_engine(engine_data)
|
||||||
|
|
||||||
if engine:
|
if engine:
|
||||||
register_engine(engine)
|
register_engine(engine)
|
||||||
else:
|
else:
|
||||||
# if an engine can't be loaded (if for example the engine is missing
|
# if an engine can't be loaded (if for example the engine is missing
|
||||||
# tor or some other requirements) its set to inactive!
|
# tor or some other requirements) its set to inactive!
|
||||||
logger.error(
|
logger.error(
|
||||||
f"(PID {os.getpid()}) loading engine %s failed: set engine to inactive!", engine_data.get("name", "???")
|
f"(PID {os.getpid()}) {engine_data.get('name', '???')}: can't register engine (loading engine failed)"
|
||||||
)
|
)
|
||||||
engine_data["inactive"] = True
|
engine_data["inactive"] = True
|
||||||
return engines
|
return engines
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ __all__ = [
|
|||||||
|
|
||||||
import typing as t
|
import typing as t
|
||||||
|
|
||||||
|
import os
|
||||||
from searx import logger
|
from searx import logger
|
||||||
from searx import engines
|
from searx import engines
|
||||||
|
|
||||||
@@ -92,7 +93,9 @@ class ProcessorMap(dict[str, EngineProcessor]):
|
|||||||
self[eng_proc.engine.name] = eng_proc
|
self[eng_proc.engine.name] = eng_proc
|
||||||
# logger.debug("registered engine processor: %s", eng_proc.engine.name)
|
# logger.debug("registered engine processor: %s", eng_proc.engine.name)
|
||||||
else:
|
else:
|
||||||
logger.error("can't register engine processor: %s (init failed)", eng_proc.engine.name)
|
logger.error(
|
||||||
|
f"(PID {os.getpid()}) {eng_proc.engine.name}: can't register engines processor (init engine failed)"
|
||||||
|
)
|
||||||
|
|
||||||
return eng_proc_ok
|
return eng_proc_ok
|
||||||
|
|
||||||
|
|||||||
@@ -150,19 +150,26 @@ class EngineProcessor(ABC):
|
|||||||
threading.Thread(target=__init_processor_thread, daemon=True).start()
|
threading.Thread(target=__init_processor_thread, daemon=True).start()
|
||||||
|
|
||||||
def init_engine(self) -> bool:
|
def init_engine(self) -> bool:
|
||||||
|
|
||||||
eng_setting = get_engine_from_settings(self.engine.name)
|
eng_setting = get_engine_from_settings(self.engine.name)
|
||||||
init_ok: bool | None = False
|
init_ok: bool | None = False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
init_ok = self.engine.init(eng_setting)
|
init_ok = self.engine.init(eng_setting)
|
||||||
except Exception: # pylint: disable=broad-except
|
except Exception as e: # pylint: disable=broad-except
|
||||||
logger.exception(
|
logger.exception(f"(PID {os.getpid()}) {self.engine.name}: engine INIT failed, exception: {e}")
|
||||||
f"(PID {os.getpid()}) Init method of engine %s failed due to an exception.", self.engine.name
|
|
||||||
)
|
|
||||||
init_ok = False
|
init_ok = False
|
||||||
|
|
||||||
# In older engines, None is returned from the init method, which is
|
# In older engines, None is returned from the init method, which is
|
||||||
# equivalent to indicating that the initialization was successful.
|
# equivalent to indicating that the initialization was successful
|
||||||
|
# (compare: Engine.setup).
|
||||||
|
|
||||||
if init_ok is None:
|
if init_ok is None:
|
||||||
init_ok = True
|
init_ok = True
|
||||||
|
|
||||||
|
if not init_ok:
|
||||||
|
logger.error(f"(PID {os.getpid()}) {self.engine.name}: engine init was not successful")
|
||||||
|
|
||||||
return init_ok
|
return init_ok
|
||||||
|
|
||||||
def handle_exception(
|
def handle_exception(
|
||||||
|
|||||||
Reference in New Issue
Block a user