core (launcher): set AsyncIO reactor in launcher

The reactor is now set in the launcher, as it is the first script to be
loaded. This should avoid race conditions when some Twisted or libervia
packages are imported and end up importing `twisted.internet.reactor`,
which installs the default reactor before the AsyncIO one. The AsyncIO
reactor is still set in `twisted.plugin.libervia_backend_plugin` (but it
no longer fails if already set), in case the backend is started as a
plugin (although this is not recommended anyway)
This commit is contained in:
Goffi 2026-03-11 10:58:24 +01:00
commit 364f365bc7
2 changed files with 22 additions and 4 deletions

View file

@ -22,10 +22,17 @@ import sys
import os
import argparse
from pathlib import Path
from twisted.application import app
from twisted.python import usage
# We want to install asyncreactor before any import from twisted or Libervia to be sure
# that the right reactor is used.
from twisted.internet import asyncioreactor
asyncioreactor.install()
from libervia.backend.core.constants import Const as C
from libervia.backend.tools.config import parse_main_conf
from twisted.application import app
from twisted.python import usage
class LiberviaLogger(app.AppLogger):

View file

@ -17,12 +17,14 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from twisted.internet.error import ReactorAlreadyInstalledError
from zope.interface import implementer
from twisted.python import usage
from twisted.plugin import IPlugin
from twisted.application.service import IServiceMaker
# XXX: We need to configure logs before any log method is used, so here is the best place.
from libervia.backend.core import exceptions
from libervia.backend.core.constants import Const as C
from libervia.backend.core.i18n import _
@ -33,7 +35,8 @@ install_wokkel_patches()
def initialise(options):
"""Method to initialise global modules"""
# XXX: We need to configure logs before any log method is used, so here is the best place.
# XXX: We need to configure logs before any log method is used, so here is the best
# place.
from libervia.backend.core import log_config
log_config.libervia_configure(C.LOG_BACKEND_TWISTED, C, backend_data=options)
@ -67,7 +70,15 @@ class LiberviaMaker:
def makeService(self, options):
from twisted.internet import asyncioreactor
asyncioreactor.install()
try:
asyncioreactor.install()
except ReactorAlreadyInstalledError as e:
from twisted.internet import reactor
if not isinstance(reactor, asyncioreactor.AsyncioSelectorReactor):
raise exceptions.InternalError(
f"Wrong reactor installed: {reactor}"
) from e
self.set_debugger()
# XXX: Libervia must be imported after log configuration,
# because it write stuff to logs