Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit15f393b

Browse files
authored
Merge pull request#3000 from takluyver/stop-cmd-http
Send HTTP shutdown request on 'stop' subcommand
2 parents4918eb1 +6410585 commit15f393b

File tree

2 files changed

+67
-8
lines changed

2 files changed

+67
-8
lines changed

‎notebook/notebookapp.py‎

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
importsocket
2525
importsys
2626
importthreading
27+
importtime
2728
importwarnings
2829
importwebbrowser
2930

@@ -351,6 +352,51 @@ def start(self):
351352
set_password(config_file=self.config_file)
352353
self.log.info("Wrote hashed password to %s"%self.config_file)
353354

355+
defshutdown_server(server_info,timeout=5,log=None):
356+
"""Shutdown a notebook server in a separate process.
357+
358+
*server_info* should be a dictionary as produced by list_running_servers().
359+
360+
Will first try to request shutdown using /api/shutdown .
361+
On Unix, if the server is still running after *timeout* seconds, it will
362+
send SIGTERM. After another timeout, it escalates to SIGKILL.
363+
364+
Returns True if the server was stopped by any means, False if stopping it
365+
failed (on Windows).
366+
"""
367+
fromtornado.httpclientimportHTTPClient,HTTPRequest
368+
url=server_info['url']
369+
pid=server_info['pid']
370+
req=HTTPRequest(url+'api/shutdown',method='POST',body=b'',headers={
371+
'Authorization':'token '+server_info['token']
372+
})
373+
iflog:log.debug("POST request to %sapi/shutdown",url)
374+
HTTPClient().fetch(req)
375+
376+
# Poll to see if it shut down.
377+
for_inrange(timeout*10):
378+
ifcheck_pid(pid):
379+
iflog:log.debug("Server PID %s is gone",pid)
380+
returnTrue
381+
time.sleep(0.1)
382+
383+
ifsys.platform.startswith('win'):
384+
returnFalse
385+
386+
iflog:log.debug("SIGTERM to PID %s",pid)
387+
os.kill(pid,signal.SIGTERM)
388+
389+
# Poll to see if it shut down.
390+
for_inrange(timeout*10):
391+
ifcheck_pid(pid):
392+
iflog:log.debug("Server PID %s is gone",pid)
393+
returnTrue
394+
time.sleep(0.1)
395+
396+
iflog:log.debug("SIGKILL to PID %s",pid)
397+
os.kill(pid,signal.SIGKILL)
398+
returnTrue# SIGKILL cannot be caught
399+
354400

355401
classNbserverStopApp(JupyterApp):
356402
version=__version__
@@ -364,14 +410,18 @@ def parse_command_line(self, argv=None):
364410
ifself.extra_args:
365411
self.port=int(self.extra_args[0])
366412

413+
defshutdown_server(self,server):
414+
returnshutdown_server(server,log=self.log)
415+
367416
defstart(self):
368417
servers=list(list_running_servers(self.runtime_dir))
369418
ifnotservers:
370419
self.exit("There are no running servers")
371420
forserverinservers:
372421
ifserver['port']==self.port:
373-
self.log.debug("Shutting down notebook server with PID: %i",server['pid'])
374-
os.kill(server['pid'],signal.SIGTERM)
422+
print("Shutting down server on port",self.port,"...")
423+
ifnotself.shutdown_server(server):
424+
sys.exit("Could not stop server")
375425
return
376426
else:
377427
print("There is currently no server running on port {}".format(self.port),file=sys.stderr)

‎notebook/tests/test_notebookapp.py‎

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,15 @@ def test_notebook_password():
140140
nt.assert_not_equal(nb.password,'')
141141
passwd_check(nb.password,password)
142142

143+
classTestingStopApp(notebookapp.NbserverStopApp):
144+
"""For testing the logic of NbserverStopApp."""
145+
def__init__(self,**kwargs):
146+
super(TestingStopApp,self).__init__(**kwargs)
147+
self.servers_shut_down= []
148+
149+
defshutdown_server(self,server):
150+
self.servers_shut_down.append(server)
151+
returnTrue
143152

144153
deftest_notebook_stop():
145154
deflist_running_servers(runtime_dir):
@@ -159,18 +168,18 @@ def list_running_servers(runtime_dir):
159168
mock_servers=patch('notebook.notebookapp.list_running_servers',list_running_servers)
160169

161170
# test stop with a match
162-
withmock_servers,patch('os.kill')asos_kill:
163-
app=notebookapp.NbserverStopApp()
171+
withmock_servers:
172+
app=TestingStopApp()
164173
app.initialize(['105'])
165174
app.start()
166-
nt.assert_equal(os_kill.call_count,1)
167-
nt.assert_equal(os_kill.call_args, ((1105,signal.SIGTERM),))
175+
nt.assert_equal(len(app.servers_shut_down),1)
176+
nt.assert_equal(app.servers_shut_down[0]['port'],105)
168177

169178
# test no match
170179
withmock_servers,patch('os.kill')asos_kill:
171-
app=notebookapp.NbserverStopApp()
180+
app=TestingStopApp()
172181
app.initialize(['999'])
173182
withnt.assert_raises(SystemExit)asexc:
174183
app.start()
175184
nt.assert_equal(exc.exception.code,1)
176-
nt.assert_equal(os_kill.call_count,0)
185+
nt.assert_equal(len(app.servers_shut_down),0)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp