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.
@@ -1,28 +1,28 @@
1
1
  Supervisor is licensed under the following license:
2
2
 
3
- A copyright notice accompanies this license document that identifies the copyright holders.
3
+ A copyright notice accompanies this license document that identifies the copyright holders.
4
4
 
5
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6
- following conditions are met:
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
- 1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the
9
- following disclaimer.
8
+ 1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the
9
+ following disclaimer.
10
10
 
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.
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
- 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.
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
- 4. If any files are modified, you must cause the modified files to carry prominent notices stating that you changed
18
- the files and the date of any change.
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
- Disclaimer
20
+ Disclaimer
21
21
 
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.
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.
@@ -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 AbstractServerContext
24
- from .types import AbstractSubprocess
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(AbstractServerContext):
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, AbstractSubprocess] = {}
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, AbstractSubprocess]:
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 AbstractSubprocess
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: AbstractSubprocess,
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) -> AbstractSubprocess:
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: AbstractSubprocess,
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: AbstractSubprocess,
309
+ process: Process,
310
310
  channel: str,
311
311
  fd: int,
312
312
  **kwargs: ta.Any,
@@ -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__()
@@ -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 .configs import ProcessConfig
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 AbstractProcessGroup
14
- from .types import AbstractServerContext
15
- from .types import AbstractSubprocess
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
- @dc.dataclass(frozen=True)
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(AbstractProcessGroup):
23
+ class ProcessGroupImpl(ProcessGroup):
30
24
  def __init__(
31
25
  self,
32
26
  config: ProcessGroupConfig,
33
27
  context: ServerContext,
34
28
  *,
35
- subprocess_factory: SubprocessFactory,
29
+ process_factory: ProcessFactory,
36
30
  ):
37
31
  super().__init__()
38
32
 
39
33
  self._config = config
40
34
  self._context = context
41
- self._subprocess_factory = subprocess_factory
35
+ self._process_factory = process_factory
42
36
 
43
37
  self._processes = {}
44
38
  for pconfig in self._config.processes or []:
45
- process = self._subprocess_factory(pconfig, 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) -> AbstractServerContext:
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[AbstractSubprocess]:
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]:
@@ -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 ServerContext
9
+ from .context import ServerContextImpl
14
10
  from .context import ServerEpoch
15
11
  from .events import EventCallbacks
16
- from .groups import ProcessGroup
17
- from .groups import SubprocessFactory
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 Subprocess
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 AbstractProcessGroup
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(ServerContext, singleton=True),
47
- inj.bind(AbstractServerContext, to_key=ServerContext),
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
- def make_process_group_factory(injector: Injector) -> ProcessGroupFactory:
61
- def inner(group_config: ProcessGroupConfig) -> ProcessGroup:
62
- return injector.inject(functools.partial(ProcessGroup, group_config))
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
 
@@ -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 ServerContext
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[ServerContext]
105
+ context = injector[ServerContextImpl]
78
106
  supervisor = injector[Supervisor]
79
107
 
80
108
  try:
@@ -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 AbstractProcessGroup
34
- from .types import AbstractServerContext
35
- from .types import AbstractSubprocess
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 Subprocess(AbstractSubprocess):
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: AbstractProcessGroup,
57
+ group: ProcessGroup,
58
58
  *,
59
- context: AbstractServerContext,
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) -> AbstractProcessGroup:
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) -> AbstractServerContext:
106
+ def context(self) -> ServerContext:
107
107
  return self._context
108
108
 
109
109
  @property
@@ -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 ServerContext
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: ServerContext,
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
- @dc.dataclass(frozen=True)
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: ServerContext,
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) -> ServerContext:
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[Subprocess]:
179
- unstopped: ta.List[Subprocess] = []
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()) # type: ignore
177
+ unstopped.extend(group.get_unstopped_processes())
183
178
 
184
179
  if unstopped:
185
180
  # throttle 'waiting for x to die' reports
@@ -10,7 +10,7 @@ from .states import ProcessState
10
10
  from .states import SupervisorState
11
11
 
12
12
 
13
- class AbstractServerContext(abc.ABC):
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, 'AbstractSubprocess']:
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 AbstractSubprocess(abc.ABC):
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) -> AbstractServerContext:
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]: # dict[int, Dispatcher]
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 AbstractProcessGroup(abc.ABC):
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.dev124
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.dev124
16
- Requires-Dist: omlish==0.0.0.dev124
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"