ominfra 0.0.0.dev123__py3-none-any.whl → 0.0.0.dev125__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.
@@ -0,0 +1,28 @@
1
+ Supervisor is licensed under the following license:
2
+
3
+ A copyright notice accompanies this license document that identifies the copyright holders.
4
+
5
+ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
6
+ following conditions are met:
7
+
8
+ 1. Redistributions in source code must retain the accompanying copyright notice, this list of conditions, and the
9
+ following disclaimer.
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.
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.
16
+
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
+
20
+ Disclaimer
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.
@@ -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]:
@@ -0,0 +1,64 @@
1
+ # ruff: noqa: UP006 UP007
2
+ import typing as ta
3
+
4
+ from omlish.lite.inject import InjectorBindingOrBindings
5
+ from omlish.lite.inject import InjectorBindings
6
+ from omlish.lite.inject import inj
7
+
8
+ from .configs import ServerConfig
9
+ from .context import ServerContextImpl
10
+ from .context import ServerEpoch
11
+ from .events import EventCallbacks
12
+ from .groups import ProcessFactory
13
+ from .groups import ProcessGroupImpl
14
+ from .poller import Poller
15
+ from .poller import get_poller_impl
16
+ from .process import InheritedFds
17
+ from .process import ProcessImpl
18
+ from .signals import SignalReceiver
19
+ from .supervisor import ProcessGroupFactory
20
+ from .supervisor import ProcessGroups
21
+ from .supervisor import SignalHandler
22
+ from .supervisor import Supervisor
23
+ from .types import ServerContext
24
+
25
+
26
+ ##
27
+
28
+
29
+ def bind_server(
30
+ config: ServerConfig,
31
+ *,
32
+ server_epoch: ta.Optional[ServerEpoch] = None,
33
+ inherited_fds: ta.Optional[InheritedFds] = None,
34
+ ) -> InjectorBindings:
35
+ lst: ta.List[InjectorBindingOrBindings] = [
36
+ inj.bind(config),
37
+
38
+ inj.bind(get_poller_impl(), key=Poller, singleton=True),
39
+
40
+ inj.bind(ServerContextImpl, singleton=True),
41
+ inj.bind(ServerContext, to_key=ServerContextImpl),
42
+
43
+ inj.bind(EventCallbacks, singleton=True),
44
+
45
+ inj.bind(SignalReceiver, singleton=True),
46
+
47
+ inj.bind(SignalHandler, singleton=True),
48
+ inj.bind(ProcessGroups, singleton=True),
49
+ inj.bind(Supervisor, singleton=True),
50
+
51
+ inj.bind_factory(ProcessGroupFactory, ProcessGroupImpl),
52
+ inj.bind_factory(ProcessFactory, ProcessImpl),
53
+ ]
54
+
55
+ #
56
+
57
+ if server_epoch is not None:
58
+ lst.append(inj.bind(server_epoch, key=ServerEpoch))
59
+ if inherited_fds is not None:
60
+ lst.append(inj.bind(inherited_fds, key=InheritedFds))
61
+
62
+ #
63
+
64
+ return inj.as_bindings(*lst)
@@ -1,41 +1,52 @@
1
1
  #!/usr/bin/env python3
2
2
  # ruff: noqa: UP006 UP007
3
3
  # @omlish-amalg ../scripts/supervisor.py
4
- import functools
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.
5
32
  import itertools
6
33
  import os.path
7
34
  import typing as ta
8
35
 
9
- from omlish.lite.inject import Injector
10
- from omlish.lite.inject import InjectorBindingOrBindings
11
- from omlish.lite.inject import InjectorBindings
36
+ from omlish.lite.http.coroserver import CoroHttpServer
12
37
  from omlish.lite.inject import inj
13
38
  from omlish.lite.journald import journald_log_handler_factory
14
39
  from omlish.lite.logs import configure_standard_logging
15
40
 
16
41
  from ..configs import read_config_file
17
- from .configs import ProcessConfig
18
- from .configs import ProcessGroupConfig
19
42
  from .configs import ServerConfig
20
43
  from .configs import prepare_server_config
21
- from .context import ServerContext
44
+ from .context import ServerContextImpl
22
45
  from .context import ServerEpoch
23
- from .events import EventCallbacks
24
- from .groups import ProcessGroup
25
- from .groups import SubprocessFactory
26
- from .poller import Poller
27
- from .poller import get_poller_impl
46
+ from .inject import bind_server
28
47
  from .process import InheritedFds
29
- from .process import Subprocess
30
- from .signals import SignalReceiver
31
48
  from .states import SupervisorState
32
- from .supervisor import ProcessGroupFactory
33
- from .supervisor import ProcessGroups
34
- from .supervisor import SignalHandler
35
49
  from .supervisor import Supervisor
36
- from .types import AbstractProcessGroup
37
- from .types import AbstractServerContext
38
- from .types import AbstractSubprocess
39
50
  from .utils import ExitNow
40
51
  from .utils import get_open_fds
41
52
 
@@ -43,63 +54,15 @@ from .utils import get_open_fds
43
54
  ##
44
55
 
45
56
 
46
- def build_server_bindings(
47
- config: ServerConfig,
48
- *,
49
- server_epoch: ta.Optional[ServerEpoch] = None,
50
- inherited_fds: ta.Optional[InheritedFds] = None,
51
- ) -> InjectorBindings:
52
- lst: ta.List[InjectorBindingOrBindings] = [
53
- inj.bind(config),
54
-
55
- inj.bind(get_poller_impl(), key=Poller, singleton=True),
56
-
57
- inj.bind(ServerContext, singleton=True),
58
- inj.bind(AbstractServerContext, to_key=ServerContext),
59
-
60
- inj.bind(EventCallbacks, singleton=True),
61
-
62
- inj.bind(SignalReceiver, singleton=True),
63
-
64
- inj.bind(SignalHandler, singleton=True),
65
- inj.bind(ProcessGroups, singleton=True),
66
- inj.bind(Supervisor, singleton=True),
67
- ]
68
-
69
- #
70
-
71
- def make_process_group_factory(injector: Injector) -> ProcessGroupFactory:
72
- def inner(group_config: ProcessGroupConfig) -> ProcessGroup:
73
- return injector.inject(functools.partial(ProcessGroup, group_config))
74
- return ProcessGroupFactory(inner)
75
- lst.append(inj.bind(make_process_group_factory))
76
-
77
- def make_subprocess_factory(injector: Injector) -> SubprocessFactory:
78
- def inner(process_config: ProcessConfig, group: AbstractProcessGroup) -> AbstractSubprocess:
79
- return injector.inject(functools.partial(Subprocess, process_config, group))
80
- return SubprocessFactory(inner)
81
- lst.append(inj.bind(make_subprocess_factory))
82
-
83
- #
84
-
85
- if server_epoch is not None:
86
- lst.append(inj.bind(server_epoch, key=ServerEpoch))
87
- if inherited_fds is not None:
88
- lst.append(inj.bind(inherited_fds, key=InheritedFds))
89
-
90
- #
91
-
92
- return inj.as_bindings(*lst)
93
-
94
-
95
- ##
96
-
97
-
98
57
  def main(
99
58
  argv: ta.Optional[ta.Sequence[str]] = None,
100
59
  *,
101
60
  no_logging: bool = False,
102
61
  ) -> None:
62
+ server_cls = CoroHttpServer # noqa
63
+
64
+ #
65
+
103
66
  import argparse
104
67
 
105
68
  parser = argparse.ArgumentParser()
@@ -133,14 +96,14 @@ def main(
133
96
  prepare=prepare_server_config,
134
97
  )
135
98
 
136
- injector = inj.create_injector(build_server_bindings(
99
+ injector = inj.create_injector(bind_server(
137
100
  config,
138
101
  server_epoch=ServerEpoch(epoch),
139
102
  inherited_fds=inherited_fds,
140
103
  ))
141
104
 
142
- context = injector.provide(ServerContext)
143
- supervisor = injector.provide(Supervisor)
105
+ context = injector[ServerContextImpl]
106
+ supervisor = injector[Supervisor]
144
107
 
145
108
  try:
146
109
  supervisor.main()
@@ -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.dev123
3
+ Version: 0.0.0.dev125
4
4
  Summary: ominfra
5
5
  Author: wrmsr
6
6
  License: BSD-3-Clause
@@ -12,12 +12,11 @@ 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.dev123
16
- Requires-Dist: omlish ==0.0.0.dev123
15
+ Requires-Dist: omdev==0.0.0.dev125
16
+ Requires-Dist: omlish==0.0.0.dev125
17
17
  Provides-Extra: all
18
- Requires-Dist: paramiko ~=3.5 ; extra == 'all'
19
- Requires-Dist: asyncssh ~=2.18 ; extra == 'all'
18
+ Requires-Dist: paramiko~=3.5; extra == "all"
19
+ Requires-Dist: asyncssh~=2.18; extra == "all"
20
20
  Provides-Extra: ssh
21
- Requires-Dist: paramiko ~=3.5 ; extra == 'ssh'
22
- Requires-Dist: asyncssh ~=2.18 ; extra == 'ssh'
23
-
21
+ Requires-Dist: paramiko~=3.5; extra == "ssh"
22
+ Requires-Dist: asyncssh~=2.18; extra == "ssh"