[CalendarServer-changes] [9657] CalendarServer/branches/users/glyph/q
source_changes at macosforge.org
source_changes at macosforge.org
Sat Aug 11 01:55:28 PDT 2012
Revision: 9657
http://trac.macosforge.org/projects/calendarserver/changeset/9657
Author: glyph at apple.com
Date: 2012-08-11 01:55:28 -0700 (Sat, 11 Aug 2012)
Log Message:
-----------
copyright, docstring, and start turing sketch into documentation
Modified Paths:
--------------
CalendarServer/branches/users/glyph/q/twext/enterprise/queue.py
Property Changed:
----------------
CalendarServer/branches/users/glyph/q/
Modified: CalendarServer/branches/users/glyph/q/twext/enterprise/queue.py
===================================================================
--- CalendarServer/branches/users/glyph/q/twext/enterprise/queue.py 2012-08-11 08:55:28 UTC (rev 9656)
+++ CalendarServer/branches/users/glyph/q/twext/enterprise/queue.py 2012-08-11 08:55:28 UTC (rev 9657)
@@ -1,6 +1,78 @@
+# -*- test-case-name: twext.enterprise.test.test_adbapi2 -*-
+##
+# Copyright (c) 2012 Apple Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+##
"""
-This is the logic associated with queueing.
+L{twext.enterprise.queue} is a task-queueing system for use by applications
+with multiple front-end servers talking to a single database instance, that
+want to defer and parallelize work that involves storing the results of
+computation.
+
+To pick a hypothetical example, let's say that you have a store which wants to
+issue a promotional coupon based on a customer loyalty program, in response to
+an administrator clicking on a button. Determining the list of customers to
+send the coupon to is quick: a simple query will get you all their names.
+However, analyzing each user's historical purchase data is (A) time consuming
+and (B) relatively isolated, so it would be good to do that in parallel, and it
+would also be acceptable to have that happen at a later time, outside the
+critical path.
+
+Such an application might be implemented with this queueing system like so::
+
+ from twext.enterprise.queue import WorkItem, queueFromTransaction
+ from twext.enterprise.dal.parseschema import addSQLToSchema
+ from twext.enterprise.dal.syntax import SchemaSyntax
+
+ schemaModel = Schema()
+ addSQLToSchema('''
+ create table CUSTOMER (NAME varchar(255), ID integer primary key);
+ create table PRODUCT (NAME varchar(255), ID integer primary key);
+ create table PURCHASE (NAME varchar(255), WHEN timestamp,
+ CUSTOMER_ID integer references CUSTOMER,
+ PRODUCT_ID integer references PRODUCT;
+ create table COUPON_WORK (WORK_ID integer primary key,
+ CUSTOMER_ID integer references CUSTOMER);
+ create table COUPON (ID integer primary key,
+ CUSTOMER_ID integer references customer,
+ AMOUNT integer);
+ ''')
+ schema = SchemaSyntax(schemaModel)
+
+ class Coupon(Record, fromTable(schema.COUPON_WORK)):
+ pass
+
+ class CouponWork(WorkItem, fromTable(schema.COUPON_WORK)):
+ @inlineCallbacks
+ def doWork(self):
+ purchases = yield Select(schema.PURCHASE,
+ Where=schema.PURCHASE.CUSTOMER_ID
+ == self.customerID).on(self.__txn__)
+ couponAmount = yield doSomeMathThatTakesAWhile(purchases)
+ yield Coupon.create(customerID=self.customerID,
+ amount=couponAmount)
+
+ @inlineCallbacks
+ def makeSomeCoupons(txn):
+ # Note, txn was started before, will be committed later...
+ q = queueFromTransaction(txn)
+ for customerID in (yield Select([schema.CUSTOMER.CUSTOMER_ID],
+ From=schema.CUSTOMER).on(txn)):
+ q.enqueueWork(CouponWork, customerID=customerID)
+
+
"""
from socket import getfqdn
@@ -909,30 +981,3 @@
def createPeerConnection(self, addr):
return ConnectionFromPeerNode(self)
-
-
-
-def sketch():
- """
- Example demonstrating how an application would normally talk to the queue.
- """
- # XXX in real life, MyWorkItem would also need to inherit from
- # fromTable(...), would need to be declared at the top level...
- class MyWorkItem(WorkItem):
- @inlineCallbacks
- def doWork(self):
- txn = self.__txn__
- yield self.doSomethingDeferred(txn)
- returnValue(None)
-
-
- @inlineCallbacks
- def sampleFunction(txn):
- for x in range(10):
- # Note: no yield here. Yielding for this to be completed would
- # generate unnecessary lock contention, potentially a deadlock (we
- # just created the item in this transaction, the next transaction is
- # going to want to delete it).
- txn.enqueueWork(MyWorkItem, someInt=x, someUnicode=u'4321')
- yield txn.commit()
-
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.macosforge.org/pipermail/calendarserver-changes/attachments/20120811/6116eadc/attachment-0001.html>
More information about the calendarserver-changes
mailing list