3.12: Move code around

This commit is contained in:
enkore 2013-03-10 21:22:58 +01:00
parent 19aca9149a
commit b42cd6aa15
12 changed files with 152 additions and 156 deletions

View File

@ -3,14 +3,14 @@
import sys import sys
from .core import Status from .core import Status
from .core.modules import Module, AsyncModule, IntervalModule from .core.modules import Module, IntervalModule
from .core.settings import SettingsBase from .core.settings import SettingsBase
from .core.config import ConfigFinder from .core.config import ConfigFinder
from .core.render import render_json from .core.render import render_json
__all__ = [ __all__ = [
"SettingsBase", "SettingsBase",
"Module", "AsyncModule", "IntervalModule", "Module", "IntervalModule",
"Status", "Status",
] ]
@ -25,7 +25,6 @@ def test_config():
def run(self): def run(self):
self.call_start_hooks() self.call_start_hooks()
for module in self.modules: for module in self.modules:
sys.stdout.write("{module}: ".format(module=module.__name__)) sys.stdout.write("{module}: ".format(module=module.__name__))
sys.stdout.flush() sys.stdout.flush()
module.run() module.run()

View File

@ -1,7 +1,7 @@
import sys import sys
import threading
import os import os
from threading import Thread
from . import io, util from . import io, util
from .modules import Module, START_HOOKS from .modules import Module, START_HOOKS
@ -11,7 +11,7 @@ class Status:
self.standalone = standalone self.standalone = standalone
if standalone: if standalone:
self.io = io.StandaloneIO(interval) self.io = io.StandaloneIO(interval)
self.ce_thread = threading.Thread(target=self.run_command_endpoint) self.ce_thread = Thread(target=self.run_command_endpoint)
self.ce_thread.daemon = True self.ce_thread.daemon = True
self.ce_thread.start() self.ce_thread.start()
else: else:

View File

@ -51,7 +51,7 @@ class StandaloneIO(IOHandler):
""" """
n = -1 n = -1
proto = ('{"version":1,"bidirectional":true}', "[", "[]", ",[]", ) proto = ('{"version":1,"bidirectional":true}', "[", "[]", ",[]",)
def __init__(self, interval=1): def __init__(self, interval=1):
super().__init__() super().__init__()

View File

@ -1,8 +1,8 @@
from threading import Thread
import time import time
from .settings import SettingsBase from .settings import SettingsBase
from .threads import AutomagicManager from .threading import Manager
__all__ = [ __all__ = [
"Module", "AsyncModule", "IntervalModule", "Module", "AsyncModule", "IntervalModule",
@ -36,15 +36,6 @@ class Module(SettingsBase):
def __repr__(self): def __repr__(self):
return self.__class__.__name__ return self.__class__.__name__
class AsyncModule(Module):
def registered(self, status_handler):
self.thread = Thread(target=self.mainloop)
self.thread.daemon = True
self.thread.start()
def mainloop(self):
"""This is run in a separate daemon-thread"""
class IntervalModule(Module): class IntervalModule(Module):
interval = 5 # seconds interval = 5 # seconds
managers = {} managers = {}
@ -53,7 +44,7 @@ class IntervalModule(Module):
if self.interval in IntervalModule.managers: if self.interval in IntervalModule.managers:
IntervalModule.managers[self.interval].append(self) IntervalModule.managers[self.interval].append(self)
else: else:
am = AutomagicManager(self.interval) am = Manager(self.interval)
am.append(self) am.append(self)
IntervalModule.managers[self.interval] = am IntervalModule.managers[self.interval] = am

View File

@ -0,0 +1,2 @@
from .manager import Manager

View File

@ -0,0 +1,49 @@
from ..util import partition
from . import threads, wrapper
class Manager:
def __init__(self, target_interval):
self.target_interval = target_interval
self.upper_bound = target_interval * 1.1
self.lower_bound = target_interval * 0.7
initial_thread = threads.Thread(target_interval, [self.wrap(self)])
self.threads = [initial_thread]
def __call__(self):
separate = []
for thread in self.threads:
separate.extend(self.branch(thread, thread.time))
self.create_threads(self.partition(separate))
def __repr__(self):
return "Manager"
def wrap(self, workload):
return wrapper.WorkloadWrapper(wrapper.ExceptionWrapper(workload))
def branch(self, thread, vtime):
if len(thread) > 1 and vtime > self.upper_bound:
remove = thread.pop()
return [remove] + self.branch(thread, vtime - remove.time)
return []
def partition(self, workloads):
return partition(workloads, self.lower_bound, lambda workload: workload.time)
def create_threads(self, threads):
for workloads in threads:
self.create_thread(workloads)
def create_thread(self, workloads):
thread = threads.Thread(self.target_interval, workloads, start_barrier=0)
thread.start()
self.threads.append(thread)
def append(self, workload):
self.threads[0].append(self.wrap(workload))
def start(self):
for thread in self.threads:
thread.start()

View File

@ -0,0 +1,53 @@
import time
import threading
try:
from setproctitle import setproctitle
except ImportError:
def setproctitle(title):
pass
class Thread(threading.Thread):
def __init__(self, target_interval, workloads=None, start_barrier=1):
super().__init__()
self.workloads = workloads or []
self.target_interval = target_interval
self.start_barrier = start_barrier
self.daemon = True
def __iter__(self):
return iter(self.workloads)
def __len__(self):
return len(self.workloads)
def pop(self):
return self.workloads.pop()
def append(self, workload):
self.workloads.append(workload)
@property
def time(self):
return sum(map(lambda workload: workload.time, self))
def wait_for_start_barrier(self):
while len(self) <= self.start_barrier:
time.sleep(0.4)
def setproctitle(self):
setproctitle("i3pystatus {name}: {workloads}".format(name=self.name, workloads=list(map(repr, self.workloads))))
def execute_workloads(self):
for workload in self:
workload()
self.workloads.sort(key=lambda workload: workload.time)
def run(self):
self.setproctitle()
while self:
self.execute_workloads()
filltime = self.target_interval - self.time
if filltime > 0:
time.sleep(filltime)

View File

@ -0,0 +1,30 @@
import sys
import time
import traceback
timer = time.perf_counter if hasattr(time, "perf_counter") else time.clock
class Wrapper:
def __init__(self, workload):
self.workload = workload
def __repr__(self):
return repr(self.workload)
class ExceptionWrapper(Wrapper):
def __call__(self):
try:
self.workload()
except Exception as exc:
sys.stderr.write("Exception in {thread}".format(thread=threading.current_thread().name))
traceback.print_exception(*sys.exc_info(), file=sys.stderr)
sys.stderr.flush()
class WorkloadWrapper(Wrapper):
time = 0.0
def __call__(self):
tp1 = timer()
self.workload()
self.time = timer() - tp1

View File

@ -1,131 +0,0 @@
import sys
import threading
import time
import traceback
from .util import partition
try:
from setproctitle import setproctitle
except ImportError:
def setproctitle(title):
pass
timer = time.perf_counter if hasattr(time, "perf_counter") else time.clock
class Wrapper:
def __init__(self, workload):
self.workload = workload
def __repr__(self):
return repr(self.workload)
class ExceptionWrapper(Wrapper):
def __call__(self):
try:
self.workload()
except Exception as exc:
sys.stderr.write("Exception in {thread}".format(thread=threading.current_thread().name))
traceback.print_exception(*sys.exc_info(), file=sys.stderr)
sys.stderr.flush()
class WorkloadWrapper(Wrapper):
time = 0.0
def __call__(self):
tp1 = timer()
self.workload()
self.time = timer() - tp1
class Thread(threading.Thread):
def __init__(self, target_interval, workloads=None, start_barrier=1):
super().__init__()
self.workloads = workloads or []
self.target_interval = target_interval
self.start_barrier = start_barrier
self.daemon = True
def __iter__(self):
return iter(self.workloads)
def __len__(self):
return len(self.workloads)
def pop(self):
return self.workloads.pop()
def append(self, workload):
self.workloads.append(workload)
@property
def time(self):
return sum(map(lambda workload: workload.time, self))
def wait_for_start_barrier(self):
while len(self) <= self.start_barrier:
time.sleep(0.4)
def setproctitle(self):
setproctitle("i3pystatus {name}: {workloads}".format(name=self.name, workloads=list(map(repr, self.workloads))))
def execute_workloads(self):
for workload in self:
workload()
self.workloads.sort(key=lambda workload: workload.time)
def run(self):
self.setproctitle()
while self:
self.execute_workloads()
filltime = self.target_interval - self.time
if filltime > 0:
time.sleep(filltime)
class AutomagicManager:
def __init__(self, target_interval):
self.target_interval = target_interval
self.upper_bound = target_interval * 1.1
self.lower_bound = target_interval * 0.7
initial_thread = Thread(target_interval, [self.wrap(self)])
self.threads = [initial_thread]
def __call__(self):
separate = []
for thread in self.threads:
separate.extend(self.branch(thread, thread.time))
self.create_threads(self.partition(separate))
def __repr__(self):
return "Manager"
def wrap(self, workload):
return WorkloadWrapper(ExceptionWrapper(workload))
# def calculate_sparse_times():
# return ((self.lower_bound - thread.time, thread) for thread in self.threads)
def branch(self, thread, vtime):
if len(thread) > 1 and vtime > self.upper_bound:
remove = thread.pop()
return [remove] + self.branch(thread, vtime - remove.time)
return []
def partition(self, workloads):
return partition(workloads, self.lower_bound, lambda workload: workload.time)
def create_threads(self, threads):
for workloads in threads:
self.create_thread(workloads)
def create_thread(self, workloads):
thread = Thread(self.target_interval, workloads, start_barrier=0)
thread.start()
self.threads.append(thread)
def append(self, workload):
self.threads[0].append(self.wrap(workload))
def start(self):
for thread in self.threads:
thread.start()

View File

@ -5,10 +5,6 @@ import itertools
from .exceptions import * from .exceptions import *
from .imputil import ClassFinder from .imputil import ClassFinder
__all__ = [
"ModuleList", "KeyConstraintDict", "PrefixedKeyDict",
]
def lchop(string, prefix): def lchop(string, prefix):
if string.startswith(prefix): if string.startswith(prefix):
return string[len(prefix):] return string[len(prefix):]

View File

@ -5,9 +5,11 @@ from i3pystatus import IntervalModule
class RunWatch(IntervalModule): class RunWatch(IntervalModule):
""" """
Expands the given path using glob to a pidfile and checks if the process ID found inside is valid Expands the given path using glob to a pidfile and checks
if the process ID found inside is valid
(that is, if the process is running). (that is, if the process is running).
You can use this to check if a specific application, such as a VPN client or your DHCP client is running. You can use this to check if a specific application,
such as a VPN client or your DHCP client is running.
Available formatters are {pid} and {name}. Available formatters are {pid} and {name}.
""" """

View File

@ -16,7 +16,12 @@ setup(name="i3pystatus",
"Topic :: Desktop Environment :: Window Managers", "Topic :: Desktop Environment :: Window Managers",
], ],
packages=["i3pystatus", "i3pystatus.core", "i3pystatus.mail"], packages=[
"i3pystatus",
"i3pystatus.core",
"i3pystatus.core.threading",
"i3pystatus.mail"
],
entry_points={ entry_points={
"console_scripts": ["i3pystatus = i3pystatus:main"], "console_scripts": ["i3pystatus = i3pystatus:main"],
}, },