2222import tornado .web
2323from tornado .routing import Rule , RuleRouter , HostMatches
2424
25+ from mockintosh .config import ConfigService , ConfigExternalFilePath
2526from mockintosh .definition import Definition
2627from mockintosh .exceptions import CertificateLoadingError
2728from mockintosh .handlers import GenericHandler
4950 ManagementServiceTagHandler ,
5051 UnhandledData
5152)
52- from mockintosh .services .asynchronous ._looping import run_loops as async_run_loops
53+ from mockintosh .services .asynchronous ._looping import run_loops as async_run_loops , stop_loops as async_stop_loops
5354from mockintosh .services .http import (
5455 HttpService ,
5556 HttpPath ,
@@ -75,8 +76,16 @@ def get_server(
7576 def serve (self ):
7677 raise NotImplementedError
7778
79+ @abstractmethod
80+ def stop (self ):
81+ raise NotImplementedError
82+
7883
7984class TornadoImpl (Impl ):
85+ def __init__ (self ) -> None :
86+ super ().__init__ ()
87+ self .ioloop = None
88+ self .servers = []
8089
8190 def get_server (
8291 self ,
@@ -89,14 +98,32 @@ def get_server(
8998 else :
9099 server = tornado .web .HTTPServer (router )
91100
101+ self .servers .append (server )
92102 return server
93103
94104 def serve (self ) -> None :
105+ self .ioloop = tornado .ioloop .IOLoop .current ()
106+ logging .debug ("Starting ioloop: %s" , self .ioloop )
95107 try :
96- tornado .ioloop . IOLoop . current () .start ()
108+ self .ioloop .start ()
97109 except KeyboardInterrupt :
98110 logging .debug ("Shutdown: %s" , traceback .format_exc ())
99111
112+ logging .debug ("IOLoop has completed" )
113+
114+ def stop (self ):
115+ logging .debug ("Stopping servers..." )
116+ for server in self .servers :
117+ logging .debug ("Stopping: %s" , server )
118+ self .ioloop .add_callback (server .close_all_connections )
119+ server .stop ()
120+
121+ logging .debug ("Stopping IOLoop..." )
122+ logging .debug ("%s" , self .ioloop )
123+ self .ioloop .add_callback_from_signal (self .ioloop .stop )
124+
125+ logging .debug ("TornadoImpl is stopped" )
126+
100127
101128class _Listener :
102129 def __init__ (self , hostname : Union [str , None ], port : int , address : Union [str , None ]):
@@ -191,19 +218,20 @@ def load_service(self, service: HttpService, rules: list, ssl: bool, ssl_options
191218 http_path_list , management_root = self .prepare_app (service )
192219 app = self .make_app (service , http_path_list , self .globals , debug = self .debug , management_root = management_root )
193220 self ._apps .apps [service .internal_http_service_id ] = app
221+ address_str = self .address if self .address else 'localhost'
194222 self ._apps .listeners [service .internal_http_service_id ] = _Listener (
195223 service .hostname ,
196224 service .port ,
197- self . address if self . address else 'localhost'
225+ address_str
198226 )
199227
200228 if service .hostname is None :
201229 server = self .impl .get_server (app , ssl , ssl_options )
230+ logging .debug ('Will listen: %s:%d' , address_str , service .port )
202231 server .listen (service .port , address = self .address )
203- logging .debug ('Will listen port number: %d' , service .port )
204232 self .services_log .append ('Serving at %s://%s:%s%s' % (
205233 protocol ,
206- self . address if self . address else 'localhost' ,
234+ address_str ,
207235 service .port ,
208236 ' the mock for %r' % service .get_name_or_empty ()
209237 ))
@@ -250,8 +278,8 @@ def load(self) -> None:
250278 if rules :
251279 router = RuleRouter (rules )
252280 server = self .impl .get_server (router , ssl , ssl_options )
281+ logging .debug ('Listening on port: %s:%d' , self .address , service .port )
253282 server .listen (services [0 ].port , address = self .address )
254- logging .debug ('Will listen port number: %d' , service .port )
255283
256284 self .load_management_api ()
257285
@@ -538,10 +566,24 @@ def load_management_api(self) -> None:
538566 )
539567 )
540568 ])
569+ logging .debug ("Listening on port %s:%s" , self .address , config_management .port )
541570 server = self .impl .get_server (app , ssl , ssl_options )
542571 server .listen (config_management .port , address = self .address )
543572 self .services_log .append ('Serving management UI+API at %s://%s:%s' % (
544573 protocol ,
545574 self .address if self .address else 'localhost' ,
546575 config_management .port
547576 ))
577+
578+ def clear_lists (self ):
579+ HttpService .services = []
580+ ConfigService .services = []
581+ ConfigExternalFilePath .files = []
582+
583+ def stop (self ):
584+ logging .info ("Stopping server..." )
585+ self .impl .stop ()
586+ logging .debug ("Stoppping async actor threads" )
587+ async_stop_loops ()
588+ self .clear_lists ()
589+ logging .debug ("Done shutdown" )
0 commit comments