So here is what I did (not perfect but it serves its purpose). For the curious, the context is here
from multiprocessing import Process
import ipywdgets as widgets
class MyWidget(widgets.VBox):
def __init__(self):
...
self.run_btn = widgets.Button(description="run")
self.run_btn.button_style = "info"
self.run_btn.on_click(self.run)
self.interupt_button = widgets.Button(description="stop")
self.interupt_button.on_click(self.stop)
self.current_process = Process(target=lambda: print("Not set"))
...
def run(self, btn):
if self.current_process.is_alive():
return
self.current_process.close()
with self.output:
if not self.kwargs:
self.run_btn.button_style = "danger"
self.run_btn.description = "errored"
return
self.run_btn.description = "running ..."
self.run_btn.button_style = "warning"
self.current_process = Process(target=a_long_job, name="main")
self.current_process.start()
self.output.clear_output()
return 0
def stop(self, btn):
if not self.current_process.is_alive():
return
self.run_btn.description = "stopping"
self.current_process.terminate()
self.current_process.join()
self.current_process.close()
self.run_btn.description = "stopped"
self.run_btn.button_style = "danger"
I tried +/- the same code with a Thread
instead of a Process
but could not get signal.pthread_kill
to behave like I wanted to.
There is a strange behavior with notebook restart (the kernel crashes when I try to restart the notebook after I stopped the process). I assume it is because there are hanging threads somewhere, but could not find a solution to that.
Thanks again for the help!