ominfra 0.0.0.dev124__py3-none-any.whl → 0.0.0.dev125__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- ominfra/deploy/poly/_main.py +2 -6
- ominfra/deploy/poly/base.py +7 -8
- ominfra/scripts/supervisor.py +265 -148
- ominfra/supervisor/LICENSE.txt +19 -19
- ominfra/supervisor/context.py +5 -5
- ominfra/supervisor/dispatchers.py +5 -5
- ominfra/supervisor/events.py +3 -3
- ominfra/supervisor/groups.py +12 -18
- ominfra/supervisor/inject.py +10 -27
- ominfra/supervisor/main.py +30 -2
- ominfra/supervisor/process.py +8 -8
- ominfra/supervisor/supervisor.py +11 -16
- ominfra/supervisor/types.py +51 -6
- {ominfra-0.0.0.dev124.dist-info → ominfra-0.0.0.dev125.dist-info}/METADATA +3 -3
- {ominfra-0.0.0.dev124.dist-info → ominfra-0.0.0.dev125.dist-info}/RECORD +19 -19
- {ominfra-0.0.0.dev124.dist-info → ominfra-0.0.0.dev125.dist-info}/LICENSE +0 -0
- {ominfra-0.0.0.dev124.dist-info → ominfra-0.0.0.dev125.dist-info}/WHEEL +0 -0
- {ominfra-0.0.0.dev124.dist-info → ominfra-0.0.0.dev125.dist-info}/entry_points.txt +0 -0
- {ominfra-0.0.0.dev124.dist-info → ominfra-0.0.0.dev125.dist-info}/top_level.txt +0 -0
ominfra/supervisor/LICENSE.txt
CHANGED
@@ -1,28 +1,28 @@
|
|
1
1
|
Supervisor is licensed under the following license:
|
2
2
|
|
3
|
-
|
3
|
+
A copyright notice accompanies this license document that identifies the copyright holders.
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
6
|
+
following conditions are met:
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the
|
9
|
+
following disclaimer.
|
10
10
|
|
11
|
-
|
12
|
-
|
11
|
+
2. Redistributions in binary form must reproduce the accompanying copyright notice, this list of conditions, and the
|
12
|
+
following disclaimer in the documentation and/or other materials provided with the distribution.
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
3. Names of the copyright holders must not be used to endorse or promote products derived from this software without
|
15
|
+
prior written permission from the copyright holders.
|
16
16
|
|
17
|
-
|
18
|
-
|
17
|
+
4. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed the
|
18
|
+
files and the date of any change.
|
19
19
|
|
20
|
-
|
20
|
+
Disclaimer
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
|
23
|
+
NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
24
|
+
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
25
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
26
|
+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
27
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
28
|
+
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
ominfra/supervisor/context.py
CHANGED
@@ -20,8 +20,8 @@ from .exceptions import NotExecutableError
|
|
20
20
|
from .exceptions import NotFoundError
|
21
21
|
from .poller import Poller
|
22
22
|
from .states import SupervisorState
|
23
|
-
from .types import
|
24
|
-
from .types import
|
23
|
+
from .types import Process
|
24
|
+
from .types import ServerContext
|
25
25
|
from .utils import close_fd
|
26
26
|
from .utils import mktempfile
|
27
27
|
from .utils import real_exit
|
@@ -31,7 +31,7 @@ from .utils import try_unlink
|
|
31
31
|
ServerEpoch = ta.NewType('ServerEpoch', int)
|
32
32
|
|
33
33
|
|
34
|
-
class ServerContext
|
34
|
+
class ServerContextImpl(ServerContext):
|
35
35
|
def __init__(
|
36
36
|
self,
|
37
37
|
config: ServerConfig,
|
@@ -45,7 +45,7 @@ class ServerContext(AbstractServerContext):
|
|
45
45
|
self._poller = poller
|
46
46
|
self._epoch = epoch
|
47
47
|
|
48
|
-
self._pid_history: ta.Dict[int,
|
48
|
+
self._pid_history: ta.Dict[int, Process] = {}
|
49
49
|
self._state: SupervisorState = SupervisorState.RUNNING
|
50
50
|
|
51
51
|
if config.user is not None:
|
@@ -78,7 +78,7 @@ class ServerContext(AbstractServerContext):
|
|
78
78
|
self._state = state
|
79
79
|
|
80
80
|
@property
|
81
|
-
def pid_history(self) -> ta.Dict[int,
|
81
|
+
def pid_history(self) -> ta.Dict[int, Process]:
|
82
82
|
return self._pid_history
|
83
83
|
|
84
84
|
@property
|
@@ -12,7 +12,7 @@ from .events import EventCallbacks
|
|
12
12
|
from .events import ProcessCommunicationEvent
|
13
13
|
from .events import ProcessLogStderrEvent
|
14
14
|
from .events import ProcessLogStdoutEvent
|
15
|
-
from .types import
|
15
|
+
from .types import Process
|
16
16
|
from .utils import as_bytes
|
17
17
|
from .utils import compact_traceback
|
18
18
|
from .utils import find_prefix_at_end
|
@@ -23,7 +23,7 @@ from .utils import strip_escapes
|
|
23
23
|
class Dispatcher(abc.ABC):
|
24
24
|
def __init__(
|
25
25
|
self,
|
26
|
-
process:
|
26
|
+
process: Process,
|
27
27
|
channel: str,
|
28
28
|
fd: int,
|
29
29
|
*,
|
@@ -42,7 +42,7 @@ class Dispatcher(abc.ABC):
|
|
42
42
|
return f'<{self.__class__.__name__} at {id(self)} for {self._process} ({self._channel})>'
|
43
43
|
|
44
44
|
@property
|
45
|
-
def process(self) ->
|
45
|
+
def process(self) -> Process:
|
46
46
|
return self._process
|
47
47
|
|
48
48
|
@property
|
@@ -97,7 +97,7 @@ class OutputDispatcher(Dispatcher):
|
|
97
97
|
|
98
98
|
def __init__(
|
99
99
|
self,
|
100
|
-
process:
|
100
|
+
process: Process,
|
101
101
|
event_type: ta.Type[ProcessCommunicationEvent],
|
102
102
|
fd: int,
|
103
103
|
**kwargs: ta.Any,
|
@@ -306,7 +306,7 @@ class OutputDispatcher(Dispatcher):
|
|
306
306
|
class InputDispatcher(Dispatcher):
|
307
307
|
def __init__(
|
308
308
|
self,
|
309
|
-
process:
|
309
|
+
process: Process,
|
310
310
|
channel: str,
|
311
311
|
fd: int,
|
312
312
|
**kwargs: ta.Any,
|
ominfra/supervisor/events.py
CHANGED
@@ -5,6 +5,9 @@ import typing as ta
|
|
5
5
|
from .states import ProcessState
|
6
6
|
|
7
7
|
|
8
|
+
EventCallback = ta.Callable[['Event'], None]
|
9
|
+
|
10
|
+
|
8
11
|
##
|
9
12
|
|
10
13
|
|
@@ -15,9 +18,6 @@ class Event(abc.ABC): # noqa
|
|
15
18
|
##
|
16
19
|
|
17
20
|
|
18
|
-
EventCallback = ta.Callable[['Event'], None]
|
19
|
-
|
20
|
-
|
21
21
|
class EventCallbacks:
|
22
22
|
def __init__(self) -> None:
|
23
23
|
super().__init__()
|
ominfra/supervisor/groups.py
CHANGED
@@ -1,48 +1,42 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import dataclasses as dc
|
3
2
|
import typing as ta
|
4
3
|
|
5
|
-
from .
|
4
|
+
from omlish.lite.typing import Func
|
5
|
+
|
6
6
|
from .configs import ProcessGroupConfig
|
7
|
-
from .context import ServerContext
|
8
7
|
from .dispatchers import Dispatcher
|
9
8
|
from .events import EventCallbacks
|
10
9
|
from .events import ProcessGroupAddedEvent
|
11
10
|
from .events import ProcessGroupRemovedEvent
|
12
11
|
from .states import ProcessState
|
13
|
-
from .types import
|
14
|
-
from .types import
|
15
|
-
from .types import
|
12
|
+
from .types import Process
|
13
|
+
from .types import ProcessGroup
|
14
|
+
from .types import ServerContext
|
16
15
|
|
17
16
|
|
18
17
|
##
|
19
18
|
|
20
19
|
|
21
|
-
|
22
|
-
class SubprocessFactory:
|
23
|
-
fn: ta.Callable[[ProcessConfig, AbstractProcessGroup], AbstractSubprocess]
|
24
|
-
|
25
|
-
def __call__(self, config: ProcessConfig, group: AbstractProcessGroup) -> AbstractSubprocess:
|
26
|
-
return self.fn(config, group)
|
20
|
+
ProcessFactory = ta.NewType('ProcessFactory', Func[Process]) # (config: ProcessConfig, group: ProcessGroup)
|
27
21
|
|
28
22
|
|
29
|
-
class ProcessGroup
|
23
|
+
class ProcessGroupImpl(ProcessGroup):
|
30
24
|
def __init__(
|
31
25
|
self,
|
32
26
|
config: ProcessGroupConfig,
|
33
27
|
context: ServerContext,
|
34
28
|
*,
|
35
|
-
|
29
|
+
process_factory: ProcessFactory,
|
36
30
|
):
|
37
31
|
super().__init__()
|
38
32
|
|
39
33
|
self._config = config
|
40
34
|
self._context = context
|
41
|
-
self.
|
35
|
+
self._process_factory = process_factory
|
42
36
|
|
43
37
|
self._processes = {}
|
44
38
|
for pconfig in self._config.processes or []:
|
45
|
-
process = self.
|
39
|
+
process = self._process_factory(pconfig, self)
|
46
40
|
self._processes[pconfig.name] = process
|
47
41
|
|
48
42
|
@property
|
@@ -54,7 +48,7 @@ class ProcessGroup(AbstractProcessGroup):
|
|
54
48
|
return self._config.name
|
55
49
|
|
56
50
|
@property
|
57
|
-
def context(self) ->
|
51
|
+
def context(self) -> ServerContext:
|
58
52
|
return self._context
|
59
53
|
|
60
54
|
def __repr__(self):
|
@@ -89,7 +83,7 @@ class ProcessGroup(AbstractProcessGroup):
|
|
89
83
|
# BACKOFF -> FATAL
|
90
84
|
proc.give_up()
|
91
85
|
|
92
|
-
def get_unstopped_processes(self) -> ta.List[
|
86
|
+
def get_unstopped_processes(self) -> ta.List[Process]:
|
93
87
|
return [x for x in self._processes.values() if not x.get_state().stopped]
|
94
88
|
|
95
89
|
def get_dispatchers(self) -> ta.Dict[int, Dispatcher]:
|
ominfra/supervisor/inject.py
CHANGED
@@ -1,32 +1,26 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import functools
|
3
2
|
import typing as ta
|
4
3
|
|
5
|
-
from omlish.lite.inject import Injector
|
6
4
|
from omlish.lite.inject import InjectorBindingOrBindings
|
7
5
|
from omlish.lite.inject import InjectorBindings
|
8
6
|
from omlish.lite.inject import inj
|
9
7
|
|
10
|
-
from .configs import ProcessConfig
|
11
|
-
from .configs import ProcessGroupConfig
|
12
8
|
from .configs import ServerConfig
|
13
|
-
from .context import
|
9
|
+
from .context import ServerContextImpl
|
14
10
|
from .context import ServerEpoch
|
15
11
|
from .events import EventCallbacks
|
16
|
-
from .groups import
|
17
|
-
from .groups import
|
12
|
+
from .groups import ProcessFactory
|
13
|
+
from .groups import ProcessGroupImpl
|
18
14
|
from .poller import Poller
|
19
15
|
from .poller import get_poller_impl
|
20
16
|
from .process import InheritedFds
|
21
|
-
from .process import
|
17
|
+
from .process import ProcessImpl
|
22
18
|
from .signals import SignalReceiver
|
23
19
|
from .supervisor import ProcessGroupFactory
|
24
20
|
from .supervisor import ProcessGroups
|
25
21
|
from .supervisor import SignalHandler
|
26
22
|
from .supervisor import Supervisor
|
27
|
-
from .types import
|
28
|
-
from .types import AbstractServerContext
|
29
|
-
from .types import AbstractSubprocess
|
23
|
+
from .types import ServerContext
|
30
24
|
|
31
25
|
|
32
26
|
##
|
@@ -43,8 +37,8 @@ def bind_server(
|
|
43
37
|
|
44
38
|
inj.bind(get_poller_impl(), key=Poller, singleton=True),
|
45
39
|
|
46
|
-
inj.bind(
|
47
|
-
inj.bind(
|
40
|
+
inj.bind(ServerContextImpl, singleton=True),
|
41
|
+
inj.bind(ServerContext, to_key=ServerContextImpl),
|
48
42
|
|
49
43
|
inj.bind(EventCallbacks, singleton=True),
|
50
44
|
|
@@ -53,21 +47,10 @@ def bind_server(
|
|
53
47
|
inj.bind(SignalHandler, singleton=True),
|
54
48
|
inj.bind(ProcessGroups, singleton=True),
|
55
49
|
inj.bind(Supervisor, singleton=True),
|
56
|
-
]
|
57
|
-
|
58
|
-
#
|
59
50
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
return ProcessGroupFactory(inner)
|
64
|
-
lst.append(inj.bind(make_process_group_factory))
|
65
|
-
|
66
|
-
def make_subprocess_factory(injector: Injector) -> SubprocessFactory:
|
67
|
-
def inner(process_config: ProcessConfig, group: AbstractProcessGroup) -> AbstractSubprocess:
|
68
|
-
return injector.inject(functools.partial(Subprocess, process_config, group))
|
69
|
-
return SubprocessFactory(inner)
|
70
|
-
lst.append(inj.bind(make_subprocess_factory))
|
51
|
+
inj.bind_factory(ProcessGroupFactory, ProcessGroupImpl),
|
52
|
+
inj.bind_factory(ProcessFactory, ProcessImpl),
|
53
|
+
]
|
71
54
|
|
72
55
|
#
|
73
56
|
|
ominfra/supervisor/main.py
CHANGED
@@ -1,6 +1,34 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
# ruff: noqa: UP006 UP007
|
3
3
|
# @omlish-amalg ../scripts/supervisor.py
|
4
|
+
# Supervisor is licensed under the following license:
|
5
|
+
#
|
6
|
+
# A copyright notice accompanies this license document that identifies the copyright holders.
|
7
|
+
#
|
8
|
+
# Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
9
|
+
# following conditions are met:
|
10
|
+
#
|
11
|
+
# 1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the
|
12
|
+
# following disclaimer.
|
13
|
+
#
|
14
|
+
# 2. Redistributions in binary form must reproduce the accompanying copyright notice, this list of conditions, and the
|
15
|
+
# following disclaimer in the documentation and/or other materials provided with the distribution.
|
16
|
+
#
|
17
|
+
# 3. Names of the copyright holders must not be used to endorse or promote products derived from this software without
|
18
|
+
# prior written permission from the copyright holders.
|
19
|
+
#
|
20
|
+
# 4. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed
|
21
|
+
# the files and the date of any change.
|
22
|
+
#
|
23
|
+
# Disclaimer
|
24
|
+
#
|
25
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT
|
26
|
+
# NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
27
|
+
# EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
28
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
29
|
+
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
30
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
31
|
+
# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
4
32
|
import itertools
|
5
33
|
import os.path
|
6
34
|
import typing as ta
|
@@ -13,7 +41,7 @@ from omlish.lite.logs import configure_standard_logging
|
|
13
41
|
from ..configs import read_config_file
|
14
42
|
from .configs import ServerConfig
|
15
43
|
from .configs import prepare_server_config
|
16
|
-
from .context import
|
44
|
+
from .context import ServerContextImpl
|
17
45
|
from .context import ServerEpoch
|
18
46
|
from .inject import bind_server
|
19
47
|
from .process import InheritedFds
|
@@ -74,7 +102,7 @@ def main(
|
|
74
102
|
inherited_fds=inherited_fds,
|
75
103
|
))
|
76
104
|
|
77
|
-
context = injector[
|
105
|
+
context = injector[ServerContextImpl]
|
78
106
|
supervisor = injector[Supervisor]
|
79
107
|
|
80
108
|
try:
|
ominfra/supervisor/process.py
CHANGED
@@ -30,9 +30,9 @@ from .exceptions import ProcessError
|
|
30
30
|
from .signals import sig_name
|
31
31
|
from .states import ProcessState
|
32
32
|
from .states import SupervisorState
|
33
|
-
from .types import
|
34
|
-
from .types import
|
35
|
-
from .types import
|
33
|
+
from .types import Process
|
34
|
+
from .types import ProcessGroup
|
35
|
+
from .types import ServerContext
|
36
36
|
from .utils import as_bytes
|
37
37
|
from .utils import as_string
|
38
38
|
from .utils import close_fd
|
@@ -48,15 +48,15 @@ InheritedFds = ta.NewType('InheritedFds', ta.FrozenSet[int])
|
|
48
48
|
##
|
49
49
|
|
50
50
|
|
51
|
-
class
|
51
|
+
class ProcessImpl(Process):
|
52
52
|
"""A class to manage a subprocess."""
|
53
53
|
|
54
54
|
def __init__(
|
55
55
|
self,
|
56
56
|
config: ProcessConfig,
|
57
|
-
group:
|
57
|
+
group: ProcessGroup,
|
58
58
|
*,
|
59
|
-
context:
|
59
|
+
context: ServerContext,
|
60
60
|
event_callbacks: EventCallbacks,
|
61
61
|
|
62
62
|
inherited_fds: ta.Optional[InheritedFds] = None,
|
@@ -95,7 +95,7 @@ class Subprocess(AbstractSubprocess):
|
|
95
95
|
return self._pid
|
96
96
|
|
97
97
|
@property
|
98
|
-
def group(self) ->
|
98
|
+
def group(self) -> ProcessGroup:
|
99
99
|
return self._group
|
100
100
|
|
101
101
|
@property
|
@@ -103,7 +103,7 @@ class Subprocess(AbstractSubprocess):
|
|
103
103
|
return self._config
|
104
104
|
|
105
105
|
@property
|
106
|
-
def context(self) ->
|
106
|
+
def context(self) -> ServerContext:
|
107
107
|
return self._context
|
108
108
|
|
109
109
|
@property
|
ominfra/supervisor/supervisor.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1
1
|
# ruff: noqa: UP006 UP007
|
2
|
-
import dataclasses as dc
|
3
2
|
import signal
|
4
3
|
import time
|
5
4
|
import typing as ta
|
@@ -7,9 +6,10 @@ import typing as ta
|
|
7
6
|
from omlish.lite.cached import cached_nullary
|
8
7
|
from omlish.lite.check import check_not_none
|
9
8
|
from omlish.lite.logs import log
|
9
|
+
from omlish.lite.typing import Func
|
10
10
|
|
11
11
|
from .configs import ProcessGroupConfig
|
12
|
-
from .context import
|
12
|
+
from .context import ServerContextImpl
|
13
13
|
from .dispatchers import Dispatcher
|
14
14
|
from .events import TICK_EVENTS
|
15
15
|
from .events import EventCallbacks
|
@@ -18,10 +18,10 @@ from .events import SupervisorStoppingEvent
|
|
18
18
|
from .groups import ProcessGroup
|
19
19
|
from .groups import ProcessGroups
|
20
20
|
from .poller import Poller
|
21
|
-
from .process import Subprocess
|
22
21
|
from .signals import SignalReceiver
|
23
22
|
from .signals import sig_name
|
24
23
|
from .states import SupervisorState
|
24
|
+
from .types import Process
|
25
25
|
from .utils import ExitNow
|
26
26
|
from .utils import as_string
|
27
27
|
from .utils import decode_wait_status
|
@@ -35,7 +35,7 @@ class SignalHandler:
|
|
35
35
|
def __init__(
|
36
36
|
self,
|
37
37
|
*,
|
38
|
-
context:
|
38
|
+
context: ServerContextImpl,
|
39
39
|
signal_receiver: SignalReceiver,
|
40
40
|
process_groups: ProcessGroups,
|
41
41
|
) -> None:
|
@@ -87,19 +87,14 @@ class SignalHandler:
|
|
87
87
|
##
|
88
88
|
|
89
89
|
|
90
|
-
|
91
|
-
class ProcessGroupFactory:
|
92
|
-
fn: ta.Callable[[ProcessGroupConfig], ProcessGroup]
|
93
|
-
|
94
|
-
def __call__(self, config: ProcessGroupConfig) -> ProcessGroup:
|
95
|
-
return self.fn(config)
|
90
|
+
ProcessGroupFactory = ta.NewType('ProcessGroupFactory', Func[ProcessGroup]) # (config: ProcessGroupConfig)
|
96
91
|
|
97
92
|
|
98
93
|
class Supervisor:
|
99
94
|
def __init__(
|
100
95
|
self,
|
101
96
|
*,
|
102
|
-
context:
|
97
|
+
context: ServerContextImpl,
|
103
98
|
poller: Poller,
|
104
99
|
process_groups: ProcessGroups,
|
105
100
|
signal_handler: SignalHandler,
|
@@ -123,7 +118,7 @@ class Supervisor:
|
|
123
118
|
#
|
124
119
|
|
125
120
|
@property
|
126
|
-
def context(self) ->
|
121
|
+
def context(self) -> ServerContextImpl:
|
127
122
|
return self._context
|
128
123
|
|
129
124
|
def get_state(self) -> SupervisorState:
|
@@ -170,16 +165,16 @@ class Supervisor:
|
|
170
165
|
return True
|
171
166
|
|
172
167
|
def get_process_map(self) -> ta.Dict[int, Dispatcher]:
|
173
|
-
process_map = {}
|
168
|
+
process_map: ta.Dict[int, Dispatcher] = {}
|
174
169
|
for group in self._process_groups:
|
175
170
|
process_map.update(group.get_dispatchers())
|
176
171
|
return process_map
|
177
172
|
|
178
|
-
def shutdown_report(self) -> ta.List[
|
179
|
-
unstopped: ta.List[
|
173
|
+
def shutdown_report(self) -> ta.List[Process]:
|
174
|
+
unstopped: ta.List[Process] = []
|
180
175
|
|
181
176
|
for group in self._process_groups:
|
182
|
-
unstopped.extend(group.get_unstopped_processes())
|
177
|
+
unstopped.extend(group.get_unstopped_processes())
|
183
178
|
|
184
179
|
if unstopped:
|
185
180
|
# throttle 'waiting for x to die' reports
|
ominfra/supervisor/types.py
CHANGED
@@ -10,7 +10,7 @@ from .states import ProcessState
|
|
10
10
|
from .states import SupervisorState
|
11
11
|
|
12
12
|
|
13
|
-
class
|
13
|
+
class ServerContext(abc.ABC):
|
14
14
|
@property
|
15
15
|
@abc.abstractmethod
|
16
16
|
def config(self) -> ServerConfig:
|
@@ -27,12 +27,24 @@ class AbstractServerContext(abc.ABC):
|
|
27
27
|
|
28
28
|
@property
|
29
29
|
@abc.abstractmethod
|
30
|
-
def pid_history(self) -> ta.Dict[int, '
|
30
|
+
def pid_history(self) -> ta.Dict[int, 'Process']:
|
31
31
|
raise NotImplementedError
|
32
32
|
|
33
33
|
|
34
|
+
# class Dispatcher(abc.ABC):
|
35
|
+
# pass
|
36
|
+
#
|
37
|
+
#
|
38
|
+
# class OutputDispatcher(Dispatcher, abc.ABC):
|
39
|
+
# pass
|
40
|
+
#
|
41
|
+
#
|
42
|
+
# class InputDispatcher(Dispatcher, abc.ABC):
|
43
|
+
# pass
|
44
|
+
|
45
|
+
|
34
46
|
@functools.total_ordering
|
35
|
-
class
|
47
|
+
class Process(abc.ABC):
|
36
48
|
@property
|
37
49
|
@abc.abstractmethod
|
38
50
|
def pid(self) -> int:
|
@@ -51,7 +63,7 @@ class AbstractSubprocess(abc.ABC):
|
|
51
63
|
|
52
64
|
@property
|
53
65
|
@abc.abstractmethod
|
54
|
-
def context(self) ->
|
66
|
+
def context(self) -> ServerContext:
|
55
67
|
raise NotImplementedError
|
56
68
|
|
57
69
|
@abc.abstractmethod
|
@@ -87,12 +99,12 @@ class AbstractSubprocess(abc.ABC):
|
|
87
99
|
raise NotImplementedError
|
88
100
|
|
89
101
|
@abc.abstractmethod
|
90
|
-
def get_dispatchers(self) -> ta.Mapping[int, ta.Any]: #
|
102
|
+
def get_dispatchers(self) -> ta.Mapping[int, ta.Any]: # Dispatcher]:
|
91
103
|
raise NotImplementedError
|
92
104
|
|
93
105
|
|
94
106
|
@functools.total_ordering
|
95
|
-
class
|
107
|
+
class ProcessGroup(abc.ABC):
|
96
108
|
@property
|
97
109
|
@abc.abstractmethod
|
98
110
|
def config(self) -> ProcessGroupConfig:
|
@@ -103,3 +115,36 @@ class AbstractProcessGroup(abc.ABC):
|
|
103
115
|
|
104
116
|
def __eq__(self, other):
|
105
117
|
return self.config.priority == other.config.priority
|
118
|
+
|
119
|
+
@abc.abstractmethod
|
120
|
+
def transition(self) -> None:
|
121
|
+
raise NotImplementedError
|
122
|
+
|
123
|
+
@abc.abstractmethod
|
124
|
+
def stop_all(self) -> None:
|
125
|
+
raise NotImplementedError
|
126
|
+
|
127
|
+
@property
|
128
|
+
@abc.abstractmethod
|
129
|
+
def name(self) -> str:
|
130
|
+
raise NotImplementedError
|
131
|
+
|
132
|
+
@abc.abstractmethod
|
133
|
+
def before_remove(self) -> None:
|
134
|
+
raise NotImplementedError
|
135
|
+
|
136
|
+
@abc.abstractmethod
|
137
|
+
def get_dispatchers(self) -> ta.Mapping[int, ta.Any]: # Dispatcher]:
|
138
|
+
raise NotImplementedError
|
139
|
+
|
140
|
+
@abc.abstractmethod
|
141
|
+
def reopen_logs(self) -> None:
|
142
|
+
raise NotImplementedError
|
143
|
+
|
144
|
+
@abc.abstractmethod
|
145
|
+
def get_unstopped_processes(self) -> ta.List[Process]:
|
146
|
+
raise NotImplementedError
|
147
|
+
|
148
|
+
@abc.abstractmethod
|
149
|
+
def after_setuid(self) -> None:
|
150
|
+
raise NotImplementedError
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: ominfra
|
3
|
-
Version: 0.0.0.
|
3
|
+
Version: 0.0.0.dev125
|
4
4
|
Summary: ominfra
|
5
5
|
Author: wrmsr
|
6
6
|
License: BSD-3-Clause
|
@@ -12,8 +12,8 @@ Classifier: Operating System :: OS Independent
|
|
12
12
|
Classifier: Operating System :: POSIX
|
13
13
|
Requires-Python: >=3.12
|
14
14
|
License-File: LICENSE
|
15
|
-
Requires-Dist: omdev==0.0.0.
|
16
|
-
Requires-Dist: omlish==0.0.0.
|
15
|
+
Requires-Dist: omdev==0.0.0.dev125
|
16
|
+
Requires-Dist: omlish==0.0.0.dev125
|
17
17
|
Provides-Extra: all
|
18
18
|
Requires-Dist: paramiko~=3.5; extra == "all"
|
19
19
|
Requires-Dist: asyncssh~=2.18; extra == "all"
|