Skip to content

Commit 99f44ec

Browse files
committed
Plugins: replace running bool with PluginStatus enum
This enables the plugin to read the status of the four formal states a plugin can be in. Previously even though the four states existed implicitly, it could only be differentiated between the STARTED/STOPPED state based on the `running` bool. This change also has the nice benefit that we can make stronger assumptions about the status inside `start()` and raise an exception if `start()` was called on a plugin that isn't in the correct status to call `start()`
1 parent 58e4eaf commit 99f44ec

File tree

6 files changed

+56
-12
lines changed

6 files changed

+56
-12
lines changed

trinity/extensibility/exceptions.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@
66
class EventBusNotReady(BaseTrinityError):
77
"""
88
Raised when a plugin tried to access an :class:`~lahja.eventbus.EventBus` before the plugin
9-
had received its :meth:`~trinity.extensibility.plugin.BasePlugin.ready` call.
9+
had received its :meth:`~trinity.extensibility.plugin.BasePlugin.on_ready` call.
10+
"""
11+
pass
12+
13+
14+
class InvalidPluginStatus(BaseTrinityError):
15+
"""
16+
Raised when it was attempted to perform an action while the current
17+
:class:`~trinity.extensibility.plugin.PluginStatus` does not allow to perform such action.
1018
"""
1119
pass
1220

trinity/extensibility/plugin.py

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88
_SubParsersAction,
99
)
1010
import asyncio
11+
from enum import (
12+
auto,
13+
Enum,
14+
)
1115
import logging
1216
from multiprocessing import (
1317
Process
@@ -38,6 +42,7 @@
3842
)
3943
from trinity.extensibility.exceptions import (
4044
EventBusNotReady,
45+
InvalidPluginStatus,
4146
)
4247
from trinity.utils.ipc import (
4348
kill_process_gracefully
@@ -50,6 +55,16 @@
5055
)
5156

5257

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+
5368
class TrinityBootInfo(NamedTuple):
5469
args: Namespace
5570
trinity_config: TrinityConfig
@@ -65,7 +80,7 @@ class PluginContext:
6580
6681
The :class:`~trinity.extensibility.plugin.PluginContext` is set during startup and is
6782
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.
6984
"""
7085

7186
def __init__(self, endpoint: Endpoint, boot_info: TrinityBootInfo) -> None:
@@ -112,7 +127,7 @@ def trinity_config(self) -> TrinityConfig:
112127
class BasePlugin(ABC):
113128

114129
context: PluginContext = None
115-
running: bool = False
130+
status: PluginStatus = PluginStatus.NOT_READY
116131

117132
@property
118133
@abstractmethod
@@ -140,13 +155,28 @@ def event_bus(self) -> Endpoint:
140155

141156
return self.context.event_bus
142157

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+
143165
def set_context(self, context: PluginContext) -> None:
144166
"""
145167
Set the :class:`~trinity.extensibility.plugin.PluginContext` for this plugin.
146168
"""
147169
self.context = context
148170

149171
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:
150180
"""
151181
Notify the plugin that it is ready to bootstrap itself. Plugins can rely
152182
on the :class:`~trinity.extensibility.plugin.PluginContext` to be set
@@ -157,7 +187,7 @@ def ready(self) -> None:
157187
def configure_parser(self, arg_parser: ArgumentParser, subparser: _SubParsersAction) -> None:
158188
"""
159189
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`
161191
"""
162192
pass
163193

@@ -167,7 +197,13 @@ def start(self) -> None:
167197
to ``True``. Broadcast a :class:`~trinity.extensibility.events.PluginStartedEvent` on the
168198
:class:`~lahja.eventbus.EventBus` and hence allow other plugins to act accordingly.
169199
"""
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
171207
self.do_start()
172208
self.event_bus.broadcast(
173209
PluginStartedEvent(type(self))
@@ -202,7 +238,7 @@ def stop(self) -> None:
202238
plugin to stop and setting ``running`` to ``False``.
203239
"""
204240
self.do_stop()
205-
self.running = False
241+
self.status = PluginStatus.STOPPED
206242

207243

208244
class BaseAsyncStopPlugin(BasePlugin):
@@ -223,7 +259,7 @@ async def stop(self) -> None:
223259
plugin to stop asynchronously and setting ``running`` to ``False``.
224260
"""
225261
await self.do_stop()
226-
self.running = False
262+
self.status = PluginStatus.STOPPED
227263

228264

229265
class BaseMainProcessPlugin(BasePlugin):
@@ -252,7 +288,7 @@ def start(self) -> None:
252288
"""
253289
Prepare the plugin to get started and eventually call ``do_start`` in a separate process.
254290
"""
255-
self.running = True
291+
self.status = PluginStatus.STARTED
256292
self._process = ctx.Process(
257293
target=self._prepare_start,
258294
)

trinity/plugins/builtin/ethstats/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ def configure_parser(self, arg_parser: ArgumentParser, subparser: _SubParsersAct
7171
default=os.environ.get('ETHSTATS_NODE_CONTACT', ''),
7272
)
7373

74-
def ready(self) -> None:
74+
def on_ready(self) -> None:
7575
args = self.context.args
7676

7777
if not args.ethstats:

trinity/plugins/builtin/json_rpc/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class JsonRpcServerPlugin(BaseIsolatedPlugin):
3333
def name(self) -> str:
3434
return "JSON-RPC Server"
3535

36-
def ready(self) -> None:
36+
def on_ready(self) -> None:
3737
if not self.context.args.disable_rpc:
3838
self.start()
3939

trinity/plugins/builtin/light_peer_chain_bridge/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class LightPeerChainBridgePlugin(BaseAsyncStopPlugin):
4040
def name(self) -> str:
4141
return "LightPeerChain Bridge"
4242

43-
def ready(self) -> None:
43+
def on_ready(self) -> None:
4444
if self.context.trinity_config.sync_mode != SYNC_LIGHT:
4545
return
4646

trinity/plugins/builtin/tx_pool/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ def configure_parser(self, arg_parser: ArgumentParser, subparser: _SubParsersAct
5454
help="Enables the Transaction Pool (experimental)",
5555
)
5656

57-
def ready(self) -> None:
57+
def on_ready(self) -> None:
5858

5959
light_mode = self.context.args.sync_mode == SYNC_LIGHT
6060
self.is_enabled = self.context.args.tx_pool and not light_mode

0 commit comments

Comments
 (0)