aboutsummaryrefslogtreecommitdiffstats
path: root/bitbake/lib/bb/server
diff options
context:
space:
mode:
authorRichard Purdie <richard.purdie@linuxfoundation.org>2013-08-31 23:40:55 +0100
committerRichard Purdie <richard.purdie@linuxfoundation.org>2013-09-01 15:51:10 +0100
commitb306d7d9a4dd5dec0ed1ca91b50569f078ac103e (patch)
tree7c76ce19c1a731316ae58f1c2b270389673f2a55 /bitbake/lib/bb/server
parentd63e6a925a78f0f5fb7e7329b5cc2993f1ec9b14 (diff)
downloadopenembedded-core-contrib-b306d7d9a4dd5dec0ed1ca91b50569f078ac103e.tar.gz
bitbake: server/process, server/xmlrpc, runqueue: Use select.select() on fds, not time.sleep()
The existing backend server implementations were inefficient since they were sleeping for the full length of the timeouts rather than being woken when there was data ready for them. It was assumed they would wake and perhaps did when we forked processes directory but that is no longer the case. This updates both the process and xmlrpc backends to wait using select(). This does mean we need to pass the file descriptors to wait on from the internals who know which these file descriptors are but this is a logical improvement. Tests of a pathaolgical load on the process server of ~420 rapid tasks executed on a server with BB_NUMBER_THREAD=48 went from a wall clock measurement of the overall command execution time of 75s to a much more reasonable 24s. (Bitbake rev: 9bee497960889d9baa0a4284d79a384b18a8e826) Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'bitbake/lib/bb/server')
-rw-r--r--bitbake/lib/bb/server/process.py11
-rw-r--r--bitbake/lib/bb/server/xmlrpc.py26
2 files changed, 18 insertions, 19 deletions
diff --git a/bitbake/lib/bb/server/process.py b/bitbake/lib/bb/server/process.py
index e2cec49b74..c0af052ebd 100644
--- a/bitbake/lib/bb/server/process.py
+++ b/bitbake/lib/bb/server/process.py
@@ -29,6 +29,7 @@ import os
import signal
import sys
import time
+import select
from Queue import Empty
from multiprocessing import Event, Process, util, Queue, Pipe, queues
@@ -105,7 +106,7 @@ class ProcessServer(Process, BaseImplServer):
command = self.command_channel.recv()
self.runCommand(command)
- self.idle_commands(.1)
+ self.idle_commands(.1, [self.event_queue._reader, self.command_channel])
except Exception:
logger.exception('Running command %s', command)
@@ -115,7 +116,7 @@ class ProcessServer(Process, BaseImplServer):
self.cooker.stop()
self.idle_commands(.1)
- def idle_commands(self, delay):
+ def idle_commands(self, delay, fds = []):
nextsleep = delay
for function, data in self._idlefuns.items():
@@ -127,15 +128,15 @@ class ProcessServer(Process, BaseImplServer):
nextsleep = None
elif nextsleep is None:
continue
- elif retval < nextsleep:
- nextsleep = retval
+ else:
+ fds = fds + retval
except SystemExit:
raise
except Exception:
logger.exception('Running idle function')
if nextsleep is not None:
- time.sleep(nextsleep)
+ select.select(fds,[],[],nextsleep)
def runCommand(self, command):
"""
diff --git a/bitbake/lib/bb/server/xmlrpc.py b/bitbake/lib/bb/server/xmlrpc.py
index 641e15e833..cca569d0e9 100644
--- a/bitbake/lib/bb/server/xmlrpc.py
+++ b/bitbake/lib/bb/server/xmlrpc.py
@@ -264,12 +264,9 @@ class XMLRPCServer(SimpleXMLRPCServer, BaseImplServer):
Serve Requests. Overloaded to honor a quit command
"""
self.quit = False
- self.timeout = 0 # Run Idle calls for our first callback
while not self.quit:
- #print "Idle queue length %s" % len(self._idlefuns)
- self.handle_request()
- #print "Idle timeout, running idle functions"
- nextsleep = None
+ fds = [self]
+ nextsleep = 0.1
for function, data in self._idlefuns.items():
try:
retval = function(self, data, False)
@@ -277,21 +274,22 @@ class XMLRPCServer(SimpleXMLRPCServer, BaseImplServer):
del self._idlefuns[function]
elif retval is True:
nextsleep = 0
- elif nextsleep is 0:
- continue
- elif nextsleep is None:
- nextsleep = retval
- elif retval < nextsleep:
- nextsleep = retval
+ else:
+ fds = fds + retval
except SystemExit:
raise
except:
import traceback
traceback.print_exc()
pass
- if nextsleep is None and len(self._idlefuns) > 0:
- nextsleep = 0
- self.timeout = nextsleep
+
+ socktimeout = self.socket.gettimeout() or nextsleep
+ socktimeout = min(socktimeout, nextsleep)
+ # Mirror what BaseServer handle_request would do
+ fd_sets = select.select(fds, [], [], socktimeout)
+ if fd_sets[0] and self in fd_sets[0]:
+ self._handle_request_noblock()
+
# Tell idle functions we're exiting
for function, data in self._idlefuns.items():
try: