mirror of
https://git.deluge-torrent.org/deluge
synced 2025-04-20 11:35:49 +00:00
[UI] Add --profile to GTKUI and console and allow custom filename
Add --profile to commonoptions making the option now available for daemon and all UIs. --profile option now prints to stdout unless an optional filename is specified.
This commit is contained in:
parent
7b54a2a1ee
commit
c90af1ce6c
7 changed files with 77 additions and 49 deletions
|
@ -726,7 +726,6 @@ class VersionSplit(object):
|
|||
|
||||
"""
|
||||
def __init__(self, ver):
|
||||
import re
|
||||
version_re = re.compile(r'''
|
||||
^
|
||||
(?P<version>\d+\.\d+) # minimum 'N.N'
|
||||
|
@ -993,3 +992,40 @@ def unicode_argv():
|
|||
encoding = encoding or "utf-8"
|
||||
|
||||
return [arg.decode(encoding) for arg in sys.argv]
|
||||
|
||||
|
||||
def run_profiled(func, *args, **kwargs):
|
||||
"""
|
||||
Profile a function with cProfile
|
||||
|
||||
Args:
|
||||
func (func): The function to profile
|
||||
*args (tuple): The arguments to pass to the function
|
||||
do_profile (bool, optional): If profiling should be performed. Defaults to True.
|
||||
output_file (str, optional): Filename to save profile results. If None, print to stdout.
|
||||
Defaults to None.
|
||||
"""
|
||||
if kwargs.get("do_profile", True) is not False:
|
||||
import cProfile
|
||||
profiler = cProfile.Profile()
|
||||
|
||||
def on_shutdown():
|
||||
output_file = kwargs.get("output_file", None)
|
||||
if output_file:
|
||||
profiler.dump_stats(output_file)
|
||||
log.info("Profile stats saved to %s", output_file)
|
||||
print "Profile stats saved to %s" % output_file
|
||||
else:
|
||||
import pstats
|
||||
import StringIO
|
||||
strio = StringIO.StringIO()
|
||||
ps = pstats.Stats(profiler, stream=strio).sort_stats('cumulative')
|
||||
ps.print_stats()
|
||||
print strio.getvalue()
|
||||
|
||||
try:
|
||||
return profiler.runcall(func, *args)
|
||||
finally:
|
||||
on_shutdown()
|
||||
else:
|
||||
return func(*args)
|
||||
|
|
|
@ -214,19 +214,5 @@ def start_daemon(skip_start=False):
|
|||
if options.pidfile:
|
||||
os.remove(options.pidfile)
|
||||
|
||||
if options.profile:
|
||||
import cProfile
|
||||
profiler = cProfile.Profile()
|
||||
profile_output = deluge.configmanager.get_config_dir("deluged.profile")
|
||||
|
||||
# Twisted catches signals to terminate
|
||||
def save_profile_stats():
|
||||
profiler.dump_stats(profile_output)
|
||||
print("Profile stats saved to %s" % profile_output)
|
||||
|
||||
from twisted.internet import reactor
|
||||
reactor.addSystemEventTrigger("before", "shutdown", save_profile_stats)
|
||||
print("Running with profiler...")
|
||||
profiler.runcall(run_daemon, options)
|
||||
else:
|
||||
return run_daemon(options)
|
||||
return deluge.common.run_profiled(run_daemon, options, output_file=options.profile,
|
||||
do_profile=options.profile)
|
||||
|
|
|
@ -106,6 +106,9 @@ class BaseArgParser(argparse.ArgumentParser):
|
|||
help="Sets the log level to 'none', this is the same as `-L none`")
|
||||
self.group.add_argument("-r", "--rotate-logs", action="store_true", default=False,
|
||||
help="Rotate logfiles.")
|
||||
self.group.add_argument("--profile", metavar="<results file>", action="store", nargs="?", default=False,
|
||||
help="Profile %(prog)s with cProfile. Prints results to stdout"
|
||||
"unless a filename is specififed.")
|
||||
self.group.add_argument("-h", "--help", action=HelpAction, help='Show this help message and exit')
|
||||
|
||||
def parse_args(self, *args):
|
||||
|
|
|
@ -8,12 +8,15 @@
|
|||
# See LICENSE for more details.
|
||||
#
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
import deluge.common
|
||||
from deluge.ui.baseargparser import DelugeTextHelpFormatter
|
||||
from deluge.ui.console import UI_PATH
|
||||
from deluge.ui.ui import UI
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
#
|
||||
# Note: Cannot import from console.main here because it imports the twisted reactor.
|
||||
|
@ -76,4 +79,13 @@ class Console(UI):
|
|||
def start(self, args=None):
|
||||
super(Console, self).start(args)
|
||||
from deluge.ui.console.main import ConsoleUI # import here because (see top)
|
||||
ConsoleUI(self.options, self.console_cmds)
|
||||
|
||||
def run(options):
|
||||
try:
|
||||
ConsoleUI(self.options, self.console_cmds)
|
||||
except Exception as ex:
|
||||
log.exception(ex)
|
||||
raise
|
||||
|
||||
deluge.common.run_profiled(run, self.options, output_file=self.options.profile,
|
||||
do_profile=self.options.profile)
|
||||
|
|
|
@ -184,7 +184,7 @@ class ConsoleUI(component.Component):
|
|||
curses.wrapper(self.run)
|
||||
elif self.interactive and deluge.common.windows_check():
|
||||
print("""\nDeluge-console does not run in interactive mode on Windows. \n
|
||||
Please use commands from the command line, eg:\n
|
||||
Please use commands from the command line, e.g.:\n
|
||||
deluge-console.exe help
|
||||
deluge-console.exe info
|
||||
deluge-console.exe "add --help"
|
||||
|
|
|
@ -146,9 +146,17 @@ class Gtk(UI):
|
|||
" to a currently running Deluge GTK instance")
|
||||
|
||||
def start(self, args=None):
|
||||
from gtkui import GtkUI
|
||||
super(Gtk, self).start(args)
|
||||
GtkUI(self.options)
|
||||
|
||||
def run(options):
|
||||
try:
|
||||
GtkUI(options)
|
||||
except Exception as ex:
|
||||
log.exception(ex)
|
||||
raise
|
||||
|
||||
deluge.common.run_profiled(run, self.options, output_file=self.options.profile,
|
||||
do_profile=self.options.profile)
|
||||
|
||||
|
||||
class GtkUI(object):
|
||||
|
|
|
@ -9,17 +9,14 @@
|
|||
|
||||
from __future__ import print_function
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
||||
from deluge.common import osx_check, windows_check
|
||||
from deluge.common import osx_check, run_profiled, windows_check
|
||||
from deluge.configmanager import get_config_dir
|
||||
from deluge.ui.ui import UI
|
||||
|
||||
|
||||
#
|
||||
# Note: Cannot import twisted.internet.reactor because Web is imported from
|
||||
# from web/__init__.py loaded by the script entry points defined in setup.py
|
||||
#
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class WebUI(object):
|
||||
|
@ -56,8 +53,6 @@ class Web(UI):
|
|||
help="Binds the webserver to a specific IP address")
|
||||
group.add_argument("-p", "--port", metavar="<port>", type=int, action="store", default=None,
|
||||
help="Sets the port to be used for the webserver")
|
||||
group.add_argument("--profile", action="store_true", default=False,
|
||||
help="Profile the web server code")
|
||||
try:
|
||||
import OpenSSL
|
||||
assert OpenSSL.__version__
|
||||
|
@ -123,26 +118,14 @@ class Web(UI):
|
|||
|
||||
self.server.https = self.options.ssl
|
||||
|
||||
def run_server():
|
||||
self.server.install_signal_handlers()
|
||||
self.server.start()
|
||||
|
||||
if self.options.profile:
|
||||
import cProfile
|
||||
profiler = cProfile.Profile()
|
||||
profile_output = get_config_dir("delugeweb.profile")
|
||||
|
||||
# Twisted catches signals to terminate
|
||||
def save_profile_stats():
|
||||
profiler.dump_stats(profile_output)
|
||||
print("Profile stats saved to %s" % profile_output)
|
||||
|
||||
from twisted.internet import reactor # import here because (see top)
|
||||
reactor.addSystemEventTrigger("before", "shutdown", save_profile_stats)
|
||||
print("Running with profiler...")
|
||||
profiler.runcall(run_server)
|
||||
else:
|
||||
run_server()
|
||||
def run():
|
||||
try:
|
||||
self.server.install_signal_handlers()
|
||||
self.server.start()
|
||||
except Exception as ex:
|
||||
log.exception(ex)
|
||||
raise
|
||||
run_profiled(run, output_file=self.options.profile, do_profile=self.options.profile)
|
||||
|
||||
|
||||
def start():
|
||||
|
|
Loading…
Add table
Reference in a new issue