[CalendarServer-changes] [6091] CalendarServer/trunk/contrib/performance
source_changes at macosforge.org
source_changes at macosforge.org
Tue Aug 17 11:09:12 PDT 2010
Revision: 6091
http://trac.macosforge.org/projects/calendarserver/changeset/6091
Author: exarkun at twistedmatrix.com
Date: 2010-08-17 11:09:11 -0700 (Tue, 17 Aug 2010)
Log Message:
-----------
Replace the cute context manager with something that actually works
This waits for dtrace processes to start successfully before doing the benchmark tasks, requiring
async both before and after.
Modified Paths:
--------------
CalendarServer/trunk/contrib/performance/io_measure.d
CalendarServer/trunk/contrib/performance/mkcal.py
Modified: CalendarServer/trunk/contrib/performance/io_measure.d
===================================================================
--- CalendarServer/trunk/contrib/performance/io_measure.d 2010-08-17 00:44:00 UTC (rev 6090)
+++ CalendarServer/trunk/contrib/performance/io_measure.d 2010-08-17 18:09:11 UTC (rev 6091)
@@ -4,7 +4,15 @@
*/
#pragma D option switchrate=10hz
+#pragma D option strsize=1024
+dtrace:::BEGIN
+{
+ /* Let the watcher know things are alright.
+ */
+ printf("READY\n");
+}
+
/*
* Low-level I/O stuff
*/
Modified: CalendarServer/trunk/contrib/performance/mkcal.py
===================================================================
--- CalendarServer/trunk/contrib/performance/mkcal.py 2010-08-17 00:44:00 UTC (rev 6090)
+++ CalendarServer/trunk/contrib/performance/mkcal.py 2010-08-17 18:09:11 UTC (rev 6091)
@@ -177,16 +177,17 @@
# Now sample it a bunch of times
data = []
- with DTraceCollector(pids) as dtrace:
- for i in range(samples):
- before = time()
- response = yield agent.request(
- method, uri, headers, body)
- yield readBody(response)
- after = time()
- data.append(after - before)
- stats = {Duration('urlopen time'): data}
- stats.update((yield dtrace))
+ dtrace = DTraceCollector(pids)
+ yield dtrace.start()
+ for i in range(samples):
+ before = time()
+ response = yield agent.request(
+ method, uri, headers, body)
+ yield readBody(response)
+ after = time()
+ data.append(after - before)
+ stats = yield dtrace.stop()
+ stats[Duration('urlopen time')] = data
returnValue(stats)
@@ -229,6 +230,15 @@
pass
+
+class DTraceBug(Exception):
+ """
+ Represents some kind of problem related to a shortcoming in dtrace
+ itself.
+ """
+
+
+
class DTraceCollector(object):
def __init__(self, pids):
self.pids = pids
@@ -298,46 +308,78 @@
self._write.append(int(rest))
- def __enter__(self):
- finished = []
+ def start(self):
+ ready = []
+ self.finished = []
self.dtraces = {}
for p in self.pids:
- d = Deferred()
- self.dtraces[p] = reactor.spawnProcess(
- IOMeasureConsumer(d),
- "/usr/sbin/dtrace",
- ["/usr/sbin/dtrace", "-q", "-p", str(p), "-s", "io_measure.d"])
- d.addCallback(self._cleanup, p)
- d.addCallback(self._parse)
- finished.append(d)
- return gatherResults(finished).addCallback(lambda ign: self.stats())
+ started, stopped = self._startDTrace(p)
+ ready.append(started)
+ self.finished.append(stopped)
+ return gatherResults(ready)
+ def _startDTrace(self, pid):
+ started = Deferred()
+ stopped = Deferred()
+ self.dtraces[pid] = reactor.spawnProcess(
+ IOMeasureConsumer(started, stopped),
+ "/usr/sbin/dtrace",
+ ["/usr/sbin/dtrace", "-q", "-p", str(pid), "-s",
+ "io_measure.d"])
+ def eintr(reason):
+ reason.trap(DTraceBug)
+ print 'Dtrace startup failed (', reason.getErrorMessage(), '), retrying.'
+ return self._startDTrace(pid)
+ started.addErrback(eintr)
+ stopped.addCallback(self._cleanup, pid)
+ stopped.addCallback(self._parse)
+ return started, stopped
+
+
def _cleanup(self, passthrough, pid):
del self.dtraces[pid]
return passthrough
- def __exit__(self, type, value, traceback):
+ def stop(self):
for proc in self.dtraces.itervalues():
proc.signalProcess(SIGINT)
+ d = gatherResults(self.finished)
+ d.addCallback(lambda ign: self.stats())
+ return d
class IOMeasureConsumer(ProcessProtocol):
- def __init__(self, done):
+ def __init__(self, started, done):
+ self.started = started
self.done = done
def connectionMade(self):
self.out = StringIO()
+ self._out = ''
+ self._err = ''
def errReceived(self, bytes):
- print bytes
+ self._err += bytes
+ if 'Interrupted system call' in self._err:
+ started = self.started
+ self.started = None
+ started.errback(DTraceBug(self._err))
+
def outReceived(self, bytes):
- self.out.write(bytes)
+ if self.started is None:
+ self.out.write(bytes)
+ else:
+ self._out += bytes
+ if self._out == 'READY\n':
+ started = self.started
+ self.started = None
+ started.callback(None)
def processEnded(self, reason):
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20100817/225b349e/attachment.html>
More information about the calendarserver-changes
mailing list