Merge lp:~chipaca/ubuntuone-client/holy-reactionary-reactors-batman into lp:ubuntuone-client

Proposed by John Lenton
Status: Merged
Approved by: Guillermo Gonzalez
Approved revision: 148
Merged at revision: not available
Proposed branch: lp:~chipaca/ubuntuone-client/holy-reactionary-reactors-batman
Merge into: lp:ubuntuone-client
Diff against target: None lines
To merge this branch: bzr merge lp:~chipaca/ubuntuone-client/holy-reactionary-reactors-batman
Reviewer Review Type Date Requested Status
Guillermo Gonzalez Approve
Elliot Murphy (community) Approve
Review via email: mp+10185@code.launchpad.net

Commit message

Use a subclass of Gtk2Reactor that uses low-res timers, for lower power consumption.

To post a comment you must log in.
Revision history for this message
John Lenton (chipaca) wrote :

This subclasses twisted.internet.gtk2reactor.Gtk2Reactor so we use timeout_add_seconds instead of timeout_add. This lowers the wakeups-per-second of both ubuntuone-syncdaemon and the applet by ONE MILLION THREE HUNDRED THOUSAND AND THIRTY EIGHT PERCENT.

Dobey quite rightly points out that for the applet, the right fix would be to fix oauthdesktop to use SimpleHTTPServer instead of the twisted server. He's right, as is usually the case, but he gets this for free, today.

Revision history for this message
Elliot Murphy (statik) wrote :

the percentage convinced me.

review: Approve
Revision history for this message
Guillermo Gonzalez (verterok) wrote :

+1
I want to run syncdaemon on my smartphone (once I buy it :p )

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'bin/ubuntuone-client-applet'
2--- bin/ubuntuone-client-applet 2009-08-12 20:50:32 +0000
3+++ bin/ubuntuone-client-applet 2009-08-14 19:05:13 +0000
4@@ -69,8 +69,8 @@
5
6 def __init__(self, *args, **kw):
7 """Initializes the child threads and dbus monitor."""
8- from twisted.internet import gtk2reactor
9- gtk2reactor.install()
10+ from ubuntuone.syncdaemon import sdreactor
11+ sdreactor.install(use_gtk=True)
12 login = Login(dbus.service.BusName(DBUS_IFACE_AUTH_NAME,
13 bus=dbus.SessionBus()))
14
15
16=== modified file 'bin/ubuntuone-syncdaemon'
17--- bin/ubuntuone-syncdaemon 2009-08-13 02:46:53 +0000
18+++ bin/ubuntuone-syncdaemon 2009-08-14 19:05:13 +0000
19@@ -18,8 +18,8 @@
20 # You should have received a copy of the GNU General Public License along
21 # with this program. If not, see <http://www.gnu.org/licenses/>.
22
23-from twisted.internet import glib2reactor
24-glib2reactor.install()
25+from ubuntuone.syncdaemon import sdreactor
26+sdreactor.install(use_gtk=False)
27
28 import atexit
29 import dbus
30
31=== added file 'ubuntuone/syncdaemon/sdreactor.py'
32--- ubuntuone/syncdaemon/sdreactor.py 1970-01-01 00:00:00 +0000
33+++ ubuntuone/syncdaemon/sdreactor.py 2009-08-14 19:52:25 +0000
34@@ -0,0 +1,79 @@
35+"""
36+The SyncDaemon reactor -- a less power-hungry version of twisted's gtk2reactor
37+"""
38+#
39+# This is the quickest way to make twisted's Gtk2Reactor use
40+# timeout_add_seconds instead of timeout_add; the former uses high-resolution
41+# timers, which are more power-intensive.
42+# It's pretty much verbatim from their source.
43+
44+from twisted.python import log
45+from twisted.internet.main import installReactor
46+from twisted.internet.gtk2reactor import Gtk2Reactor
47+import gobject
48+
49+class SyncDaemonReactor(Gtk2Reactor):
50+ """
51+ This is twisted.internet.Gtk2Reactor, but using timeout_add_seconds
52+ instead of timeout_add.
53+ """
54+ def __init__(self, use_gtk):
55+ Gtk2Reactor.__init__(self, use_gtk)
56+ # ugh... why would somebody make these private?
57+ self.__iteration = self._Gtk2Reactor__iteration
58+ self.__pending = self._Gtk2Reactor__pending
59+ self.__run = self._Gtk2Reactor__run
60+
61+ def doIteration(self, delay):
62+ """
63+ Process some events
64+ """
65+ log.msg(channel='system', event='iteration', reactor=self)
66+ if self.__pending():
67+ self.__iteration(0)
68+ return
69+ # nothing to do, must delay
70+ if delay == 0:
71+ return # shouldn't delay, so just return
72+ self.doIterationTimer = gobject.timeout_add_seconds(
73+ int(delay), self.doIterationTimeout)
74+ # This will either wake up from IO or from a timeout.
75+ self.__iteration(1) # block
76+ # note: with the .simulate timer below, delays > 0.1 will always be
77+ # woken up by the .simulate timer
78+ if self.doIterationTimer:
79+ # if woken by IO, need to cancel the timer
80+ gobject.source_remove(self.doIterationTimer)
81+ self.doIterationTimer = None
82+
83+ def run(self, installSignalHandlers=1):
84+ """
85+ See IReactorCore.run
86+ """
87+ self.startRunning(installSignalHandlers=installSignalHandlers)
88+ gobject.timeout_add_seconds(0, self.simulate)
89+ if self._started:
90+ self.__run()
91+
92+
93+ def simulate(self):
94+ """
95+ Run simulation loops and reschedule callbacks.
96+ """
97+ if self._simtag is not None:
98+ gobject.source_remove(self._simtag)
99+ self.runUntilCurrent()
100+ timeout = min(self.timeout(), 0.1)
101+ if timeout is None:
102+ timeout = 0.1
103+ # grumble
104+ self._simtag = gobject.timeout_add_seconds(int(timeout * 1010/1000),
105+ self.simulate)
106+
107+
108+def install(use_gtk):
109+ """
110+ Configure the twisted mainloop to be run inside the glib mainloop.
111+ If use_gtk, then use the gtk mainloop instead.
112+ """
113+ installReactor(SyncDaemonReactor(use_gtk))

Subscribers

People subscribed via source and target branches