77 Namespace ,
88 _SubParsersAction ,
99)
10- from enum import (
11- auto ,
12- Enum ,
13- )
10+ import asyncio
1411import logging
1512from multiprocessing import (
1613 Process
4845)
4946
5047
51- class PluginProcessScope (Enum ):
52- """
53- Define the process model in which a plugin operates:
54-
55- - ISOLATED: The plugin runs in its own separate process
56- - MAIN: The plugin takes over the Trinity main process (e.g. attach)
57- - SHARED: The plugin runs in a process that is shared with other plugins
58- """
59-
60- ISOLATED = auto ()
61- MAIN = auto ()
62- SHARED = auto ()
63-
64-
6548class PluginContext :
6649 """
6750 The ``PluginContext`` holds valuable contextual information such as the parsed
@@ -98,14 +81,6 @@ def name(self) -> str:
9881 "Must be implemented by subclasses"
9982 )
10083
101- @property
102- def process_scope (self ) -> PluginProcessScope :
103- """
104- Return the :class:`~trinity.extensibility.plugin.PluginProcessScope` that the plugin uses
105- to operate. The default scope is ``PluginProcessScope.SHARED``.
106- """
107- return PluginProcessScope .SHARED
108-
10984 @property
11085 def logger (self ) -> logging .Logger :
11186 return logging .getLogger ('trinity.extensibility.plugin.BasePlugin#{0}' .format (self .name ))
@@ -147,21 +122,42 @@ def start(self) -> None:
147122 """
148123 pass
149124
125+
126+ class BaseSyncStopPlugin (BasePlugin ):
127+ """
128+ A ``BaseSyncStopPlugin`` unwinds synchronoulsy, hence blocks until shut down is done.
129+ """
150130 def stop (self ) -> None :
151- """
152- Called when the plugin gets stopped. Should be overwritten to perform cleanup
153- work in case the plugin set up external resources.
154- """
155131 pass
156132
157133
158- class BaseIsolatedPlugin (BasePlugin ):
134+ class BaseAsyncStopPlugin (BasePlugin ):
135+ """
136+ A ``BaseAsyncStopPlugin`` unwinds asynchronoulsy, hence needs to be awaited.
137+ """
159138
160- _process : Process = None
139+ async def stop (self ) -> None :
140+ pass
161141
162- @property
163- def process_scope (self ) -> PluginProcessScope :
164- return PluginProcessScope .ISOLATED
142+
143+ class BaseMainProcessPlugin (BasePlugin ):
144+ """
145+ A ``BaseMainProcessPlugin`` overtakes the whole main process before most of the Trinity boot
146+ process had a chance to start. In that sense it redefines the whole meaning of the ``trinity``
147+ process.
148+ """
149+ pass
150+
151+
152+ class BaseIsolatedPlugin (BaseSyncStopPlugin ):
153+ """
154+ A ``BaseIsolatedPlugin`` runs in an isolated process and doesn't dictate whether its
155+ implementation is based on non-blocking asyncio or synchronous calls. When an isolated
156+ plugin is stopped it will first receive a SIGINT followed by a SIGTERM soon after.
157+ It is up to the plugin to handle these signals accordingly.
158+ """
159+
160+ _process : Process = None
165161
166162 def _start (self ) -> None :
167163 self ._process = ctx .Process (
@@ -182,7 +178,7 @@ def stop(self) -> None:
182178 kill_process_gracefully (self ._process , self .logger )
183179
184180
185- class DebugPlugin (BasePlugin ):
181+ class DebugPlugin (BaseAsyncStopPlugin ):
186182 """
187183 This is a dummy plugin useful for demonstration and debugging purposes
188184 """
@@ -195,11 +191,22 @@ def configure_parser(self, arg_parser: ArgumentParser, subparser: _SubParsersAct
195191 arg_parser .add_argument ("--debug-plugin" , type = bool , required = False )
196192
197193 def handle_event (self , activation_event : BaseEvent ) -> None :
198- self .logger .info ("Debug plugin: handle_event called: " , activation_event )
194+ self .logger .info ("Debug plugin: handle_event called: %s " , activation_event )
199195
200196 def should_start (self ) -> bool :
201197 self .logger .info ("Debug plugin: should_start called" )
202198 return True
203199
204200 def start (self ) -> None :
205201 self .logger .info ("Debug plugin: start called" )
202+ asyncio .ensure_future (self .count_forever ())
203+
204+ async def count_forever (self ) -> None :
205+ i = 0
206+ while True :
207+ self .logger .info (i )
208+ i += 1
209+ await asyncio .sleep (1 )
210+
211+ async def stop (self ) -> None :
212+ self .logger .info ("Debug plugin: stop called" )
0 commit comments