Merge lp:~ken-vandine/gwibber/lp_906916 into lp:gwibber

Proposed by Ken VanDine
Status: Merged
Merged at revision: 1235
Proposed branch: lp:~ken-vandine/gwibber/lp_906916
Merge into: lp:gwibber
Diff against target: 77 lines (+12/-25)
1 file modified
gwibber/microblog/dispatcher.py (+12/-25)
To merge this branch: bzr merge lp:~ken-vandine/gwibber/lp_906916
Reviewer Review Type Date Requested Status
Michael Terry (community) Approve
Review via email: mp+88455@code.launchpad.net

Description of the change

Drop the use of threading.Thread just to create a multiprocessing pool and ensure the pool gets closed after operations are done. This prevents the constant polling between workers which caused frequent wakeups and excessive power use.

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote :

Looks great!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'gwibber/microblog/dispatcher.py'
--- gwibber/microblog/dispatcher.py 2011-11-01 13:54:37 +0000
+++ gwibber/microblog/dispatcher.py 2012-01-13 08:25:41 +0000
@@ -1,7 +1,7 @@
1#!/usr/bin/env python1#!/usr/bin/env python
2# -*- coding: utf-8 -*-2# -*- coding: utf-8 -*-
33
4import multiprocessing, threading, traceback, json4import multiprocessing, traceback, json
5import gobject, dbus, dbus.service5import gobject, dbus, dbus.service
6import sqlite3, mx.DateTime, re, uuid6import sqlite3, mx.DateTime, re, uuid
7import urlshorter, storage, network, util, uploader7import urlshorter, storage, network, util, uploader
@@ -165,11 +165,11 @@
165 def validate_operation(self, acct, opname, enabled="receive_enabled"):165 def validate_operation(self, acct, opname, enabled="receive_enabled"):
166 # if account doesn't have the required feature or is disabled, return166 # if account doesn't have the required feature or is disabled, return
167 if enabled in acct:167 if enabled in acct:
168 if not acct[enabled]: return168 if not acct[enabled]: return False
169 else: 169 else:
170 return170 return False
171 # if there is an account for a service that gwibber doesn't no about, return171 # if there is an account for a service that gwibber doesn't no about, return
172 if not acct["service"] in SERVICES: return172 if not acct["service"] in SERVICES: return False
173 service = SERVICES[acct["service"]]173 service = SERVICES[acct["service"]]
174 return acct["service"] in PROTOCOLS and \174 return acct["service"] in PROTOCOLS and \
175 opname in service["features"] and \175 opname in service["features"] and \
@@ -230,23 +230,6 @@
230 for o in self.search_to_operations(search):230 for o in self.search_to_operations(search):
231 yield o231 yield o
232232
233class MapAsync(threading.Thread):
234 def __init__(self, func, iterable, cbsuccess, cbfailure, pool):
235 threading.Thread.__init__(self)
236 self.iterable = iterable
237 self.callback = cbsuccess
238 self.failure = cbfailure
239 self.daemon = True
240 self.func = func
241 self.pool = pool
242 self.start()
243
244 def run(self):
245 try:
246 self.pool.map_async(self.func, self.iterable, callback = self.callback)
247 except Exception as e:
248 self.failure(e, traceback.format_exc())
249
250class Dispatcher(dbus.service.Object):233class Dispatcher(dbus.service.Object):
251 """234 """
252 The Gwibber Dispatcher handles all the backend operations.235 The Gwibber Dispatcher handles all the backend operations.
@@ -340,7 +323,6 @@
340 self.launcher.set_property("count_visible", False)323 self.launcher.set_property("count_visible", False)
341324
342 self.refresh_count = 0325 self.refresh_count = 0
343 self.workerpool = multiprocessing.Pool()
344326
345 self.refresh_timer_id = None327 self.refresh_timer_id = None
346328
@@ -664,9 +646,14 @@
664 util.notify(error["account"]["service"], error["message"], icon, 2000)646 util.notify(error["account"]["service"], error["message"], icon, 2000)
665 self.notified_errors[error["account"]["service"]] = error["message"]647 self.notified_errors[error["account"]["service"]] = error["message"]
666648
667 def perform_async_operation(self, iterable):649 def perform_async_operation (self, iterable):
668 t = MapAsync(perform_operation, iterable, self.loading_complete, self.loading_failed, self.workerpool)650 pool = multiprocessing.Pool ()
669 t.join()651 try:
652 pool.map_async (perform_operation, iterable, callback = self.loading_complete)
653 except Exception as e:
654 self.loading_failed (e, traceback.format_exc())
655 pool.close ()
656 pool.join ()
670 657
671 def loading_complete(self, output):658 def loading_complete(self, output):
672 self.refresh_count += 1659 self.refresh_count += 1