[CalendarServer-changes] [7548] CalendarServer/trunk/contrib/performance

source_changes at macosforge.org source_changes at macosforge.org
Thu Jun 2 14:07:45 PDT 2011


Revision: 7548
          http://trac.macosforge.org/projects/calendarserver/changeset/7548
Author:   exarkun at twistedmatrix.com
Date:     2011-06-02 14:07:44 -0700 (Thu, 02 Jun 2011)
Log Message:
-----------
Implement a workday-centric normal distribution and use it for event creation.  incremental step towards more realistic event distribution.

Modified Paths:
--------------
    CalendarServer/trunk/contrib/performance/loadtest/config.plist
    CalendarServer/trunk/contrib/performance/loadtest/profiles.py
    CalendarServer/trunk/contrib/performance/stats.py
    CalendarServer/trunk/contrib/performance/test_stats.py

Modified: CalendarServer/trunk/contrib/performance/loadtest/config.plist
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/config.plist	2011-06-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/loadtest/config.plist	2011-06-02 21:07:44 UTC (rev 7548)
@@ -72,7 +72,27 @@
 	    <key>params</key>
 	    <dict>
 	      <key>interval</key>
-	      <integer>25</integer>
+	      <integer>60</integer>
+	      <key>eventStartDistribution</key>
+	      <dict>
+		<key>type</key>
+		<string>stats.WorkDistribution</string>
+		<key>params</key>
+		<dict>
+		  <key>daysOfWeek</key>
+		  <array>
+		    <string>mon</string>
+		    <string>tue</string>
+		    <string>wed</string>
+		    <string>thu</string>
+		    <string>fri</string>
+		  </array>
+		  <key>beginHour</key>
+		  <integer>8</integer>
+		  <key>endHour</key>
+		  <integer>17</integer>
+		</dict>
+	      </dict>
 	    </dict>
 	  </dict>
 

Modified: CalendarServer/trunk/contrib/performance/loadtest/profiles.py
===================================================================
--- CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2011-06-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/loadtest/profiles.py	2011-06-02 21:07:44 UTC (rev 7548)
@@ -379,8 +379,6 @@
             vevent.contents[u'dtend'][0].value = dtend
             vevent.contents[u'uid'][0].value = unicode(uuid4())
 
-            print 'Creating event from', dtstart, 'to', dtend
-
             href = '%s%s.ics' % (
                 calendar.url, vevent.contents[u'uid'][0].value)
             d = self._client.addEvent(href, vcalendar)

Modified: CalendarServer/trunk/contrib/performance/stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/stats.py	2011-06-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/stats.py	2011-06-02 21:07:44 UTC (rev 7548)
@@ -14,7 +14,7 @@
 # limitations under the License.
 ##
 
-import random, time
+import random, time, datetime
 
 from zope.interface import Interface, implements
 
@@ -287,3 +287,61 @@
 
     def sample(self):
         return random.normalvariate(self._mu, self._sigma)
+
+
+NUM_WEEKDAYS = 7
+
+class WorkDistribution(object, FancyEqMixin):
+    compareAttributes = ["_daysOfWeek", "_beginHour", "_endHour"]
+
+    _weekdayNames = ["mon", "tue", "wed", "thu", "fri", "sat", "sun"]
+
+    now = staticmethod(datetime.datetime.now)
+
+    def __init__(self, daysOfWeek=["mon", "tue", "wed", "thu", "fri"], beginHour=8, endHour=17):
+        self._daysOfWeek = [self._weekdayNames.index(day) for day in daysOfWeek]
+        self._beginHour = beginHour
+        self._endHour = endHour
+        self._helperDistribution = NormalDistribution(
+            # Mean 6 workdays in the future
+            60 * 60 * 8 * 6,
+            # Standard deviation of 4 workdays
+            60 * 60 * 8 * 4)
+    
+    def astimestamp(self, dt):
+        return time.mktime(dt.timetuple())
+
+
+    def _findWorkAfter(self, when):
+        """
+        Return a two-tuple of the start and end of work hours following
+        C{when}.  If C{when} falls within work hours, then the start time will
+        be equal to when.
+        """
+        # Find a workday that follows the timestamp
+        weekday = when.weekday()
+        for i in range(NUM_WEEKDAYS):
+            day = when + datetime.timedelta(days=i)
+            if (weekday + i) % NUM_WEEKDAYS in self._daysOfWeek:
+                # Joy, a day on which work might occur.  Find the first hour on
+                # this day when work may start.
+                begin = day.replace(
+                    hour=self._beginHour, minute=0, second=0, microsecond=0)
+                end = begin.replace(hour=self._endHour)
+                if end > when:
+                    return begin, end
+
+
+    def sample(self):
+        offset = datetime.timedelta(seconds=self._helperDistribution.sample())
+        beginning = self.now()
+        while offset:
+            start, end = self._findWorkAfter(beginning)
+            if end - start > offset:
+                result = start + offset
+                return self.astimestamp(
+                    result.replace(
+                        minute=result.minute // 15 * 15,
+                        second=0, microsecond=0))
+            offset -= (end - start)
+            beginning = end

Modified: CalendarServer/trunk/contrib/performance/test_stats.py
===================================================================
--- CalendarServer/trunk/contrib/performance/test_stats.py	2011-06-02 15:51:45 UTC (rev 7547)
+++ CalendarServer/trunk/contrib/performance/test_stats.py	2011-06-02 21:07:44 UTC (rev 7548)
@@ -14,9 +14,11 @@
 # limitations under the License.
 ##
 
+from datetime import datetime
+
 from twisted.trial.unittest import TestCase
 
-from stats import SQLDuration, LogNormalDistribution, UniformDiscreteDistribution, quantize
+from stats import SQLDuration, LogNormalDistribution, UniformDiscreteDistribution, WorkDistribution, quantize
 
 class SQLDurationTests(TestCase):
     def setUp(self):
@@ -61,7 +63,20 @@
         self.assertEqual(dict.fromkeys(population, 10), counts)
 
 
+    def test_workdistribution(self):
+        dist = WorkDistribution(["mon", "wed", "thu", "sat"], 10, 20)
+        dist._helperDistribution = UniformDiscreteDistribution([35 * 60 * 60 + 30 * 60])
+        dist.now = lambda: datetime(2011, 5, 29, 18, 5, 36)
+        value = dist.sample()
+        self.assertEqual(
+            # Move past three workdays - monday, wednesday, thursday - using 30
+            # of the hours, and then five and a half hours into the fourth
+            # workday, saturday.  Workday starts at 10am, so the sample value
+            # is 3:30pm, ie 1530 hours.
+            datetime(2011, 6, 4, 15, 30, 0), datetime.fromtimestamp(value)) 
 
+
+
 class QuantizationTests(TestCase):
     """
     Tests for L{quantize} which constructs discrete datasets of
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20110602/3e34d66c/attachment.html>


More information about the calendarserver-changes mailing list