learning-loop-node 0.13.3__py3-none-any.whl → 0.13.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of learning-loop-node might be problematic. Click here for more details.
- learning_loop_node/detector/detector_logic.py +11 -6
- learning_loop_node/detector/detector_node.py +18 -7
- learning_loop_node/detector/exceptions.py +7 -0
- {learning_loop_node-0.13.3.dist-info → learning_loop_node-0.13.5.dist-info}/METADATA +1 -1
- {learning_loop_node-0.13.3.dist-info → learning_loop_node-0.13.5.dist-info}/RECORD +6 -5
- {learning_loop_node-0.13.3.dist-info → learning_loop_node-0.13.5.dist-info}/WHEEL +0 -0
|
@@ -6,6 +6,7 @@ import numpy as np
|
|
|
6
6
|
|
|
7
7
|
from ..data_classes import ImageMetadata, ModelInformation
|
|
8
8
|
from ..globals import GLOBALS
|
|
9
|
+
from .exceptions import NodeNeedsRestartError
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
class DetectorLogic():
|
|
@@ -14,6 +15,8 @@ class DetectorLogic():
|
|
|
14
15
|
self.model_format: str = model_format
|
|
15
16
|
self._model_info: Optional[ModelInformation] = None
|
|
16
17
|
|
|
18
|
+
self._remaining_init_attempts: int = 2
|
|
19
|
+
|
|
17
20
|
async def soft_reload(self):
|
|
18
21
|
self._model_info = None
|
|
19
22
|
|
|
@@ -27,20 +30,22 @@ class DetectorLogic():
|
|
|
27
30
|
def is_initialized(self) -> bool:
|
|
28
31
|
return self._model_info is not None
|
|
29
32
|
|
|
30
|
-
def
|
|
33
|
+
def load_model_info_and_init_model(self):
|
|
31
34
|
logging.info('Loading model from %s', GLOBALS.data_folder)
|
|
32
|
-
|
|
33
|
-
if
|
|
35
|
+
self._model_info = ModelInformation.load_from_disk(f'{GLOBALS.data_folder}/model')
|
|
36
|
+
if self._model_info is None:
|
|
34
37
|
logging.error('No model found')
|
|
35
38
|
self._model_info = None
|
|
36
|
-
raise Exception('No model found')
|
|
37
39
|
try:
|
|
38
|
-
self._model_info = model_info
|
|
39
40
|
self.init()
|
|
40
41
|
logging.info('Successfully loaded model %s', self._model_info)
|
|
42
|
+
self._remaining_init_attempts = 2
|
|
41
43
|
except Exception:
|
|
44
|
+
self._remaining_init_attempts -= 1
|
|
42
45
|
self._model_info = None
|
|
43
|
-
logging.error('Could not init model %s',
|
|
46
|
+
logging.error('Could not init model %s. Retries left: %s', self._model_info, self._remaining_init_attempts)
|
|
47
|
+
if self._remaining_init_attempts == 0:
|
|
48
|
+
raise NodeNeedsRestartError('Could not init model') from None
|
|
44
49
|
raise
|
|
45
50
|
|
|
46
51
|
@abstractmethod
|
|
@@ -3,6 +3,7 @@ import contextlib
|
|
|
3
3
|
import os
|
|
4
4
|
import shutil
|
|
5
5
|
import subprocess
|
|
6
|
+
import sys
|
|
6
7
|
from dataclasses import asdict
|
|
7
8
|
from datetime import datetime
|
|
8
9
|
from threading import Thread
|
|
@@ -23,6 +24,7 @@ from ..globals import GLOBALS
|
|
|
23
24
|
from ..helpers import environment_reader
|
|
24
25
|
from ..node import Node
|
|
25
26
|
from .detector_logic import DetectorLogic
|
|
27
|
+
from .exceptions import NodeNeedsRestartError
|
|
26
28
|
from .inbox_filter.relevance_filter import RelevanceFilter
|
|
27
29
|
from .outbox import Outbox
|
|
28
30
|
from .rest import about as rest_about
|
|
@@ -170,13 +172,13 @@ class DetectorNode(Node):
|
|
|
170
172
|
|
|
171
173
|
# simulate startup
|
|
172
174
|
await self.detector_logic.soft_reload()
|
|
173
|
-
self.detector_logic.
|
|
175
|
+
self.detector_logic.load_model_info_and_init_model()
|
|
174
176
|
self.operation_mode = OperationMode.Idle
|
|
175
177
|
|
|
176
178
|
async def on_startup(self) -> None:
|
|
177
179
|
try:
|
|
178
180
|
self.outbox.ensure_continuous_upload()
|
|
179
|
-
self.detector_logic.
|
|
181
|
+
self.detector_logic.load_model_info_and_init_model()
|
|
180
182
|
except Exception:
|
|
181
183
|
self.log.exception("error during 'startup'")
|
|
182
184
|
self.operation_mode = OperationMode.Idle
|
|
@@ -200,8 +202,11 @@ class DetectorNode(Node):
|
|
|
200
202
|
"""The DetectorNode acts as a SocketIO server. This method sets up the server and defines the event handlers."""
|
|
201
203
|
# pylint: disable=unused-argument
|
|
202
204
|
|
|
203
|
-
# Initialize the Socket.IO server
|
|
204
|
-
self.sio = socketio.AsyncServer(
|
|
205
|
+
# Initialize the Socket.IO server with 20MB buffer size
|
|
206
|
+
self.sio = socketio.AsyncServer(
|
|
207
|
+
async_mode='asgi',
|
|
208
|
+
max_http_buffer_size=2e7, # 20MB
|
|
209
|
+
)
|
|
205
210
|
# Initialize and mount the ASGI app
|
|
206
211
|
self.sio_app = socketio.ASGIApp(self.sio, socketio_path='/socket.io')
|
|
207
212
|
self.mount('/ws', self.sio_app)
|
|
@@ -318,9 +323,12 @@ class DetectorNode(Node):
|
|
|
318
323
|
self.log.debug('not checking for updates; no target model selected')
|
|
319
324
|
return
|
|
320
325
|
|
|
321
|
-
|
|
326
|
+
if self.detector_logic.is_initialized:
|
|
327
|
+
current_version = self.detector_logic.model_info.version
|
|
328
|
+
else:
|
|
329
|
+
current_version = None
|
|
322
330
|
|
|
323
|
-
if
|
|
331
|
+
if current_version != self.target_model.version:
|
|
324
332
|
self.log.info('Current model "%s" needs to be updated to %s',
|
|
325
333
|
current_version or "-", self.target_model.version)
|
|
326
334
|
|
|
@@ -346,7 +354,10 @@ class DetectorNode(Node):
|
|
|
346
354
|
self.log.info('Updated symlink for model to %s', os.readlink(model_symlink))
|
|
347
355
|
|
|
348
356
|
try:
|
|
349
|
-
self.detector_logic.
|
|
357
|
+
self.detector_logic.load_model_info_and_init_model()
|
|
358
|
+
except NodeNeedsRestartError:
|
|
359
|
+
self.log.error('Node needs restart')
|
|
360
|
+
sys.exit(0)
|
|
350
361
|
except Exception:
|
|
351
362
|
self.log.exception('Could not load model, will retry download on next check')
|
|
352
363
|
shutil.rmtree(target_model_folder, ignore_errors=True)
|
|
@@ -11,8 +11,9 @@ learning_loop_node/data_classes/socket_response.py,sha256=tIdt-oYf6ULoJIDYQCecNM
|
|
|
11
11
|
learning_loop_node/data_classes/training.py,sha256=FFPsr2AA7ynYz39MLZaFJ0sF_9Axll5HHbAA8nnirp0,5726
|
|
12
12
|
learning_loop_node/data_exchanger.py,sha256=IG5ki3f3IsVuXbyw6q_gUIakgv-GMT6e9nhOhzjKgW4,9055
|
|
13
13
|
learning_loop_node/detector/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
-
learning_loop_node/detector/detector_logic.py,sha256=
|
|
15
|
-
learning_loop_node/detector/detector_node.py,sha256=
|
|
14
|
+
learning_loop_node/detector/detector_logic.py,sha256=M6iGCj6OMscd460NUyqIfig-gNK6pNcnBZz-1iKBSLg,2506
|
|
15
|
+
learning_loop_node/detector/detector_node.py,sha256=u_SWqwELmMKHJSC_R6KFVemteNBc1KaNu9WeCYVl9Js,25391
|
|
16
|
+
learning_loop_node/detector/exceptions.py,sha256=C6KbNPlSbtfgDrZx2Hbhm7Suk9jVoR3fMRCO0CkrMsQ,196
|
|
16
17
|
learning_loop_node/detector/inbox_filter/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
18
|
learning_loop_node/detector/inbox_filter/cam_observation_history.py,sha256=1PHgXRrhSQ34HSFw7mdX8ndRxHf_i1aP5nXXnrZxhAY,3312
|
|
18
19
|
learning_loop_node/detector/inbox_filter/relevance_filter.py,sha256=NPEmrAtuGjIWCtHS0B3zDmnYWkhVFCLbd_7RUp08_AM,1372
|
|
@@ -96,6 +97,6 @@ learning_loop_node/trainer/test_executor.py,sha256=6BVGDN_6f5GEMMEvDLSG1yzMybSvg
|
|
|
96
97
|
learning_loop_node/trainer/trainer_logic.py,sha256=eK-01qZzi10UjLMCQX8vy5eW2FoghPj3rzzDC-s3Si4,8792
|
|
97
98
|
learning_loop_node/trainer/trainer_logic_generic.py,sha256=RQqon8JIVzxaNh0KdEe6tMxebsY0DgZllEohHR-AgqU,26846
|
|
98
99
|
learning_loop_node/trainer/trainer_node.py,sha256=Dl4ZQAjjXQggibeBjvhXAoFClw1ZX2Kkt3v_fjrJnCI,4508
|
|
99
|
-
learning_loop_node-0.13.
|
|
100
|
-
learning_loop_node-0.13.
|
|
101
|
-
learning_loop_node-0.13.
|
|
100
|
+
learning_loop_node-0.13.5.dist-info/METADATA,sha256=QiQQwfbMoEjN14j_IDkjuWccGrRa__pOIo1NKqMbW7s,12761
|
|
101
|
+
learning_loop_node-0.13.5.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
|
|
102
|
+
learning_loop_node-0.13.5.dist-info/RECORD,,
|
|
File without changes
|