8
8
_SubParsersAction ,
9
9
)
10
10
import asyncio
11
+ from enum import (
12
+ auto ,
13
+ Enum ,
14
+ )
11
15
import logging
12
16
from multiprocessing import (
13
17
Process
38
42
)
39
43
from trinity .extensibility .exceptions import (
40
44
EventBusNotReady ,
45
+ InvalidPluginStatus ,
41
46
)
42
47
from trinity .utils .ipc import (
43
48
kill_process_gracefully
50
55
)
51
56
52
57
58
+ class PluginStatus (Enum ):
59
+ NOT_READY = auto ()
60
+ READY = auto ()
61
+ STARTED = auto ()
62
+ STOPPED = auto ()
63
+
64
+
65
+ INVALID_START_STATUS = (PluginStatus .NOT_READY , PluginStatus .STARTED ,)
66
+
67
+
53
68
class TrinityBootInfo (NamedTuple ):
54
69
args : Namespace
55
70
trinity_config : TrinityConfig
@@ -65,7 +80,7 @@ class PluginContext:
65
80
66
81
The :class:`~trinity.extensibility.plugin.PluginContext` is set during startup and is
67
82
guaranteed to exist by the time that a plugin receives its
68
- :meth:`~trinity.extensibility.plugin.BasePlugin.ready ` call.
83
+ :meth:`~trinity.extensibility.plugin.BasePlugin.on_ready ` call.
69
84
"""
70
85
71
86
def __init__ (self , endpoint : Endpoint , boot_info : TrinityBootInfo ) -> None :
@@ -112,7 +127,7 @@ def trinity_config(self) -> TrinityConfig:
112
127
class BasePlugin (ABC ):
113
128
114
129
context : PluginContext = None
115
- running : bool = False
130
+ status : PluginStatus = PluginStatus . NOT_READY
116
131
117
132
@property
118
133
@abstractmethod
@@ -140,13 +155,28 @@ def event_bus(self) -> Endpoint:
140
155
141
156
return self .context .event_bus
142
157
158
+ @property
159
+ def running (self ) -> bool :
160
+ """
161
+ Return ``True`` if the ``status`` is ``PluginStatus.STARTED``, otherwise return ``False``.
162
+ """
163
+ return self .status is PluginStatus .STARTED
164
+
143
165
def set_context (self , context : PluginContext ) -> None :
144
166
"""
145
167
Set the :class:`~trinity.extensibility.plugin.PluginContext` for this plugin.
146
168
"""
147
169
self .context = context
148
170
149
171
def ready (self ) -> None :
172
+ """
173
+ Set the ``status`` to ``PluginStatus.READY`` and delegate to
174
+ :meth:`~trinity.extensibility.plugin.BasePlugin.on_ready`
175
+ """
176
+ self .status = PluginStatus .READY
177
+ self .on_ready ()
178
+
179
+ def on_ready (self ) -> None :
150
180
"""
151
181
Notify the plugin that it is ready to bootstrap itself. Plugins can rely
152
182
on the :class:`~trinity.extensibility.plugin.PluginContext` to be set
@@ -157,7 +187,7 @@ def ready(self) -> None:
157
187
def configure_parser (self , arg_parser : ArgumentParser , subparser : _SubParsersAction ) -> None :
158
188
"""
159
189
Give the plugin a chance to amend the Trinity CLI argument parser. This hook is called
160
- before :meth:`~trinity.extensibility.plugin.BasePlugin.ready `
190
+ before :meth:`~trinity.extensibility.plugin.BasePlugin.on_ready `
161
191
"""
162
192
pass
163
193
@@ -167,7 +197,13 @@ def start(self) -> None:
167
197
to ``True``. Broadcast a :class:`~trinity.extensibility.events.PluginStartedEvent` on the
168
198
:class:`~lahja.eventbus.EventBus` and hence allow other plugins to act accordingly.
169
199
"""
170
- self .running = True
200
+
201
+ if self .status in INVALID_START_STATUS :
202
+ raise InvalidPluginStatus (
203
+ f"Can not start plugin when the plugin status is { self .status } "
204
+ )
205
+
206
+ self .status = PluginStatus .STARTED
171
207
self .do_start ()
172
208
self .event_bus .broadcast (
173
209
PluginStartedEvent (type (self ))
@@ -202,7 +238,7 @@ def stop(self) -> None:
202
238
plugin to stop and setting ``running`` to ``False``.
203
239
"""
204
240
self .do_stop ()
205
- self .running = False
241
+ self .status = PluginStatus . STOPPED
206
242
207
243
208
244
class BaseAsyncStopPlugin (BasePlugin ):
@@ -223,7 +259,7 @@ async def stop(self) -> None:
223
259
plugin to stop asynchronously and setting ``running`` to ``False``.
224
260
"""
225
261
await self .do_stop ()
226
- self .running = False
262
+ self .status = PluginStatus . STOPPED
227
263
228
264
229
265
class BaseMainProcessPlugin (BasePlugin ):
@@ -252,7 +288,7 @@ def start(self) -> None:
252
288
"""
253
289
Prepare the plugin to get started and eventually call ``do_start`` in a separate process.
254
290
"""
255
- self .running = True
291
+ self .status = PluginStatus . STARTED
256
292
self ._process = ctx .Process (
257
293
target = self ._prepare_start ,
258
294
)
0 commit comments