Fix the missing env variable issue (#5467)
Fixes #5448, #5453, #5457 - Relaxed env var requirements in the images, no mandatory ones - RQ workers now use a custom python class for remote debugging - Factored out common remote debugging implementationmain
parent
7b13216e2d
commit
f6d2a8fe46
@ -0,0 +1,56 @@
|
|||||||
|
# Copyright (C) 2018-2022 Intel Corporation
|
||||||
|
# Copyright (C) 2022 CVAT.ai Corporation
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
from rq import Worker
|
||||||
|
|
||||||
|
import cvat.utils.remote_debugger as debug
|
||||||
|
|
||||||
|
|
||||||
|
DefaultWorker = Worker
|
||||||
|
|
||||||
|
|
||||||
|
class BaseDeathPenalty:
|
||||||
|
def __init__(self, timeout, exception, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def __exit__(self, exc_type, exc_value, traceback):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class SimpleWorker(Worker):
|
||||||
|
"""
|
||||||
|
Allows to work with at most 1 worker thread. Useful for debugging.
|
||||||
|
"""
|
||||||
|
|
||||||
|
death_penalty_class = BaseDeathPenalty
|
||||||
|
|
||||||
|
def main_work_horse(self, *args, **kwargs):
|
||||||
|
raise NotImplementedError("Test worker does not implement this method")
|
||||||
|
|
||||||
|
def execute_job(self, *args, **kwargs):
|
||||||
|
"""Execute job in same thread/process, do not fork()"""
|
||||||
|
return self.perform_job(*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
if debug.is_debugging_enabled():
|
||||||
|
class RemoteDebugWorker(SimpleWorker):
|
||||||
|
"""
|
||||||
|
Support for VS code debugger
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
self.__debugger = debug.RemoteDebugger()
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
|
||||||
|
def execute_job(self, *args, **kwargs):
|
||||||
|
"""Execute job in same thread/process, do not fork()"""
|
||||||
|
self.__debugger.attach_current_thread()
|
||||||
|
|
||||||
|
return super().execute_job(*args, **kwargs)
|
||||||
|
|
||||||
|
DefaultWorker = RemoteDebugWorker
|
||||||
@ -1,28 +0,0 @@
|
|||||||
|
|
||||||
# Copyright (C) 2018-2022 Intel Corporation
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: MIT
|
|
||||||
|
|
||||||
from rq import Worker
|
|
||||||
|
|
||||||
|
|
||||||
class BaseDeathPenalty:
|
|
||||||
def __init__(self, timeout, exception, **kwargs):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __enter__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, traceback):
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class SimpleWorker(Worker):
|
|
||||||
death_penalty_class = BaseDeathPenalty
|
|
||||||
|
|
||||||
def main_work_horse(self, *args, **kwargs):
|
|
||||||
raise NotImplementedError("Test worker does not implement this method")
|
|
||||||
|
|
||||||
def execute_job(self, *args, **kwargs):
|
|
||||||
"""Execute job in same thread/process, do not fork()"""
|
|
||||||
return self.perform_job(*args, **kwargs)
|
|
||||||
@ -0,0 +1,59 @@
|
|||||||
|
# Copyright (C) 2022 CVAT.ai Corporation
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: MIT
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
|
||||||
|
def is_debugging_enabled() -> bool:
|
||||||
|
return os.environ.get('CVAT_DEBUG_ENABLED') == 'yes'
|
||||||
|
|
||||||
|
if is_debugging_enabled():
|
||||||
|
import debugpy
|
||||||
|
|
||||||
|
class RemoteDebugger:
|
||||||
|
"""
|
||||||
|
Support for VS code debugger.
|
||||||
|
|
||||||
|
Supports both single- and multi-thread scenarios.
|
||||||
|
|
||||||
|
Read docs: https://github.com/microsoft/debugpy
|
||||||
|
Read more: https://modwsgi.readthedocs.io/en/develop/user-guides/debugging-techniques.html
|
||||||
|
"""
|
||||||
|
|
||||||
|
ENV_VAR_PORT = 'CVAT_DEBUG_PORT'
|
||||||
|
ENV_VAR_WAIT = 'CVAT_DEBUG_WAIT'
|
||||||
|
__debugger_initialized = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _singleton_init(cls):
|
||||||
|
if cls.__debugger_initialized:
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
port = int(os.environ[cls.ENV_VAR_PORT])
|
||||||
|
|
||||||
|
# The only intended use is in Docker.
|
||||||
|
# Using 127.0.0.1 will not allow host connections
|
||||||
|
addr = ('0.0.0.0', port) # nosec - B104:hardcoded_bind_all_interfaces
|
||||||
|
|
||||||
|
# Debugpy is a singleton
|
||||||
|
# We put it in the main thread of the process and then report new threads
|
||||||
|
debugpy.listen(addr)
|
||||||
|
|
||||||
|
# In most cases it makes no sense to debug subprocesses
|
||||||
|
# Feel free to enable if needed.
|
||||||
|
debugpy.configure({"subProcess": False})
|
||||||
|
|
||||||
|
if os.environ.get(cls.ENV_VAR_WAIT) == 'yes':
|
||||||
|
debugpy.wait_for_client()
|
||||||
|
except Exception as ex:
|
||||||
|
raise Exception("failed to set debugger") from ex
|
||||||
|
|
||||||
|
cls.__debugger_initialized = True
|
||||||
|
|
||||||
|
def __init__(self) -> None:
|
||||||
|
self._singleton_init()
|
||||||
|
|
||||||
|
def attach_current_thread(self) -> None:
|
||||||
|
debugpy.debug_this_thread()
|
||||||
Loading…
Reference in New Issue