Skip to content

Commit

Permalink
Handle keyboard interrupts more cleanly
Browse files Browse the repository at this point in the history
  • Loading branch information
ybnd committed Feb 4, 2020
1 parent 4970585 commit 02600ce
Showing 1 changed file with 45 additions and 29 deletions.
74 changes: 45 additions & 29 deletions beetsplug/replaygain.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import enum
from multiprocessing.pool import ThreadPool, RUN
from threading import Thread, Event
import signal
import xml.parsers.expat
from six.moves import zip, queue
import six
Expand Down Expand Up @@ -1193,6 +1194,7 @@ class ReplayGainPlugin(BeetsPlugin):

def __init__(self):
super(ReplayGainPlugin, self).__init__()
signal.signal(signal.SIGINT, self._interrupt)

# default backend is 'command' for backward-compatibility.
self.config.add({
Expand Down Expand Up @@ -1480,10 +1482,20 @@ def terminate_pool(self):
"""Terminate the `ThreadPool` instance in `self.pool`
(e.g. stop execution in case of exception)
"""
if self._has_pool():
self.pool.terminate()
self.pool.join()
self.exc_watcher.join()
# Don't call self._as_pool() here,
# self.pool._state may not be == RUN
self.pool.terminate()
self.pool.join()
self.exc_watcher.join()

def _interrupt(self, signal, frame):
try:
self._log.info('interrupted')
self.terminate_pool()
exit(0)
except ValueError:
# Silence interrupt exception
pass

def close_pool(self):
"""Close the `ThreadPool` instance in `self.pool` (if there is one)
Expand Down Expand Up @@ -1515,32 +1527,36 @@ def commands(self):
"""Return the "replaygain" ui subcommand.
"""
def func(lib, opts, args):
write = ui.should_write(opts.write)
force = opts.force

# Bypass self.open_pool() if called with `--threads 0`
if opts.threads != 0:
threads = opts.threads or self.config['threads'].get(int)
self.open_pool(threads)

if opts.album:
albums = lib.albums(ui.decargs(args))
self._log.info(
"Analyzing {} albums ~ {} backend..."
.format(len(albums), self.backend_name)
)
for album in albums:
self.handle_album(album, write, force)
else:
items = lib.items(ui.decargs(args))
self._log.info(
"Analyzing {} tracks ~ {} backend..."
.format(len(items), self.backend_name)
)
for item in items:
self.handle_track(item, write, force)
try:
write = ui.should_write(opts.write)
force = opts.force

# Bypass self.open_pool() if called with `--threads 0`
if opts.threads != 0:
threads = opts.threads or self.config['threads'].get(int)
self.open_pool(threads)

if opts.album:
albums = lib.albums(ui.decargs(args))
self._log.info(
"Analyzing {} albums ~ {} backend..."
.format(len(albums), self.backend_name)
)
for album in albums:
self.handle_album(album, write, force)
else:
items = lib.items(ui.decargs(args))
self._log.info(
"Analyzing {} tracks ~ {} backend..."
.format(len(items), self.backend_name)
)
for item in items:
self.handle_track(item, write, force)

self.close_pool()
self.close_pool()
except (SystemExit, KeyboardInterrupt):
# Silence interrupt exceptions
pass

cmd = ui.Subcommand('replaygain', help=u'analyze for ReplayGain')
cmd.parser.add_album_option()
Expand Down

0 comments on commit 02600ce

Please sign in to comment.