def changePassword(self, oldPassword, newPassword): account = self._account() if account.password is not None and account.password != oldPassword: raise InvalidPassword() else: account.password = newPassword self.lastCredentialsChange = extime.Time()
def itemAdded(self): """ Called to indicate that a new item of the type monitored by this batch processor is being added to the database. If this processor is not already scheduled to run, this will schedule it. It will also start the batch process if it is not yet running and there are any registered remote listeners. """ localCount = self.store.query( _ReliableListener, attributes.AND(_ReliableListener.processor == self, _ReliableListener.style == iaxiom.LOCAL), limit=1).count() remoteCount = self.store.query( _ReliableListener, attributes.AND(_ReliableListener.processor == self, _ReliableListener.style == iaxiom.REMOTE), limit=1).count() if localCount and self.scheduled is None: self.scheduled = extime.Time() iaxiom.IScheduler(self.store).schedule(self, self.scheduled) if remoteCount: batchService = iaxiom.IBatchService(self.store, None) if batchService is not None: batchService.start()
def upgradeProcessor1to2(oldProcessor): """ Batch processors stopped polling at version 2, so they no longer needed the idleInterval attribute. They also gained a scheduled attribute which tracks their interaction with the scheduler. Since they stopped polling, we also set them up as a timed event here to make sure that they don't silently disappear, never to be seen again: running them with the scheduler gives them a chance to figure out what's up and set up whatever other state they need to continue to run. Since this introduces a new dependency of all batch processors on a powerup for the IScheduler, install a Scheduler or a SubScheduler if one is not already present. """ newProcessor = oldProcessor.upgradeVersion( oldProcessor.typeName, 1, 2, busyInterval=oldProcessor.busyInterval) newProcessor.scheduled = extime.Time() s = newProcessor.store sch = iaxiom.IScheduler(s, None) if sch is None: if s.parent is None: # Only site stores have no parents. sch = Scheduler(store=s) else: # Substores get subschedulers. sch = SubScheduler(store=s) installOn(sch, s) # And set it up to run. sch.schedule(newProcessor, newProcessor.scheduled) return newProcessor
def step(self, style=iaxiom.LOCAL, skip=()): now = extime.Time() first = True for listener in self.store.query(_ReliableListener, attributes.AND(_ReliableListener.processor == self, _ReliableListener.style == style, _ReliableListener.listener.notOneOf(skip)), sort=_ReliableListener.lastRun.ascending): if not first: if VERBOSE: log.msg("Found more work to do, returning True from %r.step()" % (self,)) return True listener.lastRun = now try: if listener.step(): if VERBOSE: log.msg("%r.step() reported more work to do, returning True from %r.step()" % (listener, self)) return True except _NoWorkUnits: if VERBOSE: log.msg("%r.step() reported no work units" % (listener,)) else: first = False if VERBOSE: log.msg("No listeners left with work, returning False from %r.step()" % (self,)) return False
def timedEventErrorHandler(self, timedEvent, failureObj): failureObj.trap(_ProcessingFailure) log.msg("Batch processing failure") log.err(failureObj.value.failure) failureObj.value.mark() return extime.Time() + datetime.timedelta( milliseconds=self.busyInterval)
def __init__(self, store, collector, failure): when = extime.Time() traceback = failure.getTraceback() super(Traceback, self).__init__( store=store, traceback=traceback, when=when, collector=collector)
def stoppedRunning(self): if self.grabber is None: return self.grabber.running = False if self._transient: iaxiom.IScheduler(self.grabber.store).reschedule( self.grabber, self.grabber.scheduled, extime.Time()) self.grabber = None
def test_asHumanlyInvalidPrecision(self): """ L{Time.asHumanly} should raise an L{InvalidPrecision} exception if passed a value for precision other than L{Time.Precision.MINUTES} or L{Time.Precision.SECONDS}. """ self.assertRaises(extime.InvalidPrecision, extime.Time().asHumanly, **{'precision': '%H:%M'})
def setStatus(self, message, success=True): self.when = extime.Time() self.message = message self.success = success for L in self.changeObservers: try: L(message) except: log.err(None, "Failure in status update")
class StubMessage: sentWhen = extime.Time() _wasArchived = False def archive(self): """ Emulate L{Message.archive}. """ self._wasArchived = True
def stoppedRunning(self): if self.grabber is None: return self.grabber.running = False if self._transient: self.grabber.config.scheduler.reschedule(self.grabber, self.grabber.scheduled, extime.Time()) self.grabber = None
def fetchLastHour(self, name): t = extime.Time() return ([ unicode((t + datetime.timedelta(minutes=i)).asHumanly()) for i in range(60) ], [ 24, 28, 41, 37, 39, 25, 44, 32, 41, 45, 44, 47, 24, 28, 29, 49, 43, 56, 28, 35, 66, 43, 72, 65, 62, 56, 84, 52, 74, 73, 74, 77, 71, 46, 70, 55, 65, 51, 42, 55, 19, 30, 25, 24, 20, 16, 39, 22, 39, 29, 29, 18, 39, 19, 21, 12, 25, 25, 25, 29 ])
def mark(self): """ Mark the unit of work as failed in the database and update the listener so as to skip it next time. """ self.reliableListener.lastRun = extime.Time() BatchProcessingError(store=self.reliableListener.store, processor=self.reliableListener.processor, listener=self.reliableListener.listener, item=self.workUnit, error=self.failure.getErrorMessage())
def newAttemptForUser(self, user): """ Create an L{_PasswordResetAttempt} for the user whose username is C{user} @param user: C{unicode} username """ # we could query for other attempts by the same # user within some timeframe and raise an exception, # if we wanted return _PasswordResetAttempt(store=self.store, username=user, timestamp=extime.Time(), key=self._makeKey(user))
def test_delete(self): """ L{POP3Grabber.delete} unschedules the grabber. """ store = self.grabber.store iaxiom.IScheduler(store).schedule(self.grabber, extime.Time()) self.grabber.delete() # Can't query for the TimedEvent directly, but we know nothing *else* # was scheduled either. self.assertEqual( [], list(store.query(scheduler.TimedEvent)))
def brokenFunction(): item2 = TestItem(store=self.store, foo=42, bar=u'mooZ', baz=extime.Time.fromISO8601TimeAndDate( '1970-03-12T05:05:11.5921')) item1.foo = 823 item1.bar = u'this is the wrong answer' item1.baz = extime.Time() raise RevertException(item2.storeID)
def testBatchInsertReference(self): """ Test that reference args are handled okay by batchInsert. """ itemA = AttributefulItem(store=self.store) itemB = AttributefulItem(store=self.store) dataRows = [ (1, u"hello", extime.Time(), itemA, True, False, self.store), (2, u"hoorj", extime.Time(), itemB, False, True, self.store) ] self.store.batchInsert(TestItem, [ TestItem.foo, TestItem.bar, TestItem.baz, TestItem.other, TestItem.booleanT, TestItem.booleanF, TestItem.myStore ], dataRows) items = list(self.store.query(TestItem)) self.assertEquals(items[0].other, itemA) self.assertEquals(items[1].other, itemB) self.assertEquals(items[0].store, self.store) self.assertEquals(items[1].store, self.store)
def test_stoppedRunningWithGrabber(self): """ When L{ControlledPOP3GrabberProtocol.stoppedRunning} is called after a transient failure, and the protocol instance has an associated grabber, that grabber is rescheduled to run immediately. """ factory = grabber.POP3GrabberFactory(self.grabberItem, False) protocol = factory.buildProtocol(None) protocol.transientFailure(None) protocol.stoppedRunning() self.assertEqual(False, self.grabberItem.running) scheduled = list(self.scheduler.scheduledTimes(self.grabberItem)) self.assertEqual(1, len(scheduled)) self.assertTrue(scheduled[0] <= extime.Time())
def setUp(self): """ Create a grabber in a user store. """ self.siteStore = store.Store() self.subStore = substore.SubStore.createNew(self.siteStore, ['grabber']) self.userStore = self.subStore.open() self.scheduler = iaxiom.IScheduler(self.userStore) self.grabberItem = grabber.POP3Grabber( store=self.userStore, username=u"alice", domain=u"example.com", password=u"secret", running=True, config=grabber.GrabberConfiguration(store=self.userStore)) self.grabberItem.scheduled = extime.Time() self.scheduler.schedule(self.grabberItem, self.grabberItem.scheduled)
def run(self): """ Retrieve some messages from the account associated with this grabber. """ try: if not self.paused: try: self.grab() except: log.err(None, "Failure in scheduled event") finally: # XXX This is not a good way for things to work. Different, later. delay = datetime.timedelta(seconds=300) self.scheduled = extime.Time() + delay return self.scheduled
def run(self): """ Try to run one unit of work through one listener. If there are more listeners or more work, reschedule this item to be run again in C{self.busyInterval} milliseconds, otherwise unschedule it. @rtype: L{extime.Time} or C{None} @return: The next time at which to run this item, used by the scheduler for automatically rescheduling, or None if there is no more work to do. """ now = extime.Time() if self.step(): self.scheduled = now + datetime.timedelta(milliseconds=self.busyInterval) else: self.scheduled = None return self.scheduled
def addGrabber(self, username, password, domain, ssl): # DO IT if ssl: port = 995 else: port = 110 pg = POP3Grabber(store=self.store, username=username, password=password, domain=domain, port=port, config=self, ssl=ssl) # DO IT *NOW* self.scheduler.schedule(pg, extime.Time())
def main(): s, userStore = initializeStore() g = grabber.POP3Grabber(store=userStore, username=u"testuser", password=u"password", domain=u"127.0.0.1", port=12345) scheduler.IScheduler(userStore).schedule(g, extime.Time()) StoppingMessageFilter(store=userStore, totalMessages=TOTAL_MESSAGES).installOn(userStore) pop3server = filepath.FilePath(__file__).sibling("pop3server.tac") os.system("twistd -y " + pop3server.path) benchmark.start() os.system("axiomatic -d wholesystem.axiom start -n") benchmark.stop() os.system("kill `cat twistd.pid`")
def test_addGrabber(self): """ L{GrabberConfiguration.addGrabber} creates a new L{POP3Grabber} item scheduled to run immediately. """ siteStore = store.Store() subStore = substore.SubStore.createNew(siteStore, ['grabber']) userStore = subStore.open() scheduler = iaxiom.IScheduler(userStore) config = grabber.GrabberConfiguration(store=userStore) config.addGrabber(u"alice", u"secret", u"example.com", False) grabberItems = list(userStore.query(grabber.POP3Grabber)) self.assertEqual(1, len(grabberItems)) scheduled = list(scheduler.scheduledTimes(grabberItems[0])) self.assertEqual(1, len(scheduled)) self.assertTrue(scheduled[0] <= extime.Time())
def createSignup(self, creator, signupClass, signupConf, product, emailTemplate, prompt): """ Create a new signup facility in the site store's database. @param creator: a unicode string describing the creator of the new signup mechanism, for auditing purposes. @param signupClass: the item type of the signup mechanism to create. @param signupConf: a dictionary of keyword arguments for L{signupClass}'s constructor. @param product: A Product instance, describing the powerups to be installed with this signup. @param emailTemplate: a unicode string which contains some text that will be sent in confirmation emails generated by this signup mechanism (if any) @param prompt: a short unicode string describing this signup mechanism, as distinct from others. For example: "Student Sign Up", or "Faculty Sign Up" @return: a newly-created, database-resident instance of signupClass. """ siteStore = self.store.parent booth = siteStore.findOrCreate( TicketBooth, lambda booth: installOn(booth, siteStore)) signupItem = signupClass(store=siteStore, booth=booth, product=product, emailTemplate=emailTemplate, prompt=prompt, **signupConf) siteStore.powerUp(signupItem) _SignupTracker(store=siteStore, signupItem=signupItem, createdOn=extime.Time(), createdBy=creator) return signupItem
def addReliableListener(self, listener, style=iaxiom.LOCAL): """ Add the given Item to the set which will be notified of Items available for processing. Note: Each Item is processed synchronously. Adding too many listeners to a single batch processor will cause the L{step} method to block while it sends notification to each listener. @param listener: An Item instance which provides a C{processItem} method. @return: An Item representing L{listener}'s persistent tracking state. """ existing = self.store.findUnique( _ReliableListener, attributes.AND(_ReliableListener.processor == self, _ReliableListener.listener == listener), default=None) if existing is not None: return existing for work in self.store.query(self.workUnitType, sort=self.workUnitType.storeID.descending, limit=1): forwardMark = work.storeID backwardMark = work.storeID + 1 break else: forwardMark = 0 backwardMark = 0 if self.scheduled is None: self.scheduled = extime.Time() iaxiom.IScheduler(self.store).schedule(self, self.scheduled) return _ReliableListener(store=self.store, processor=self, listener=listener, forwardMark=forwardMark, backwardMark=backwardMark, style=style)
def run(self): """ Try to reliably deliver this message. If errors are encountered, try harder. """ sch = iaxiom.IScheduler(self.store) if self.tries < len(self.RETRANS_TIMES): # Set things up to try again, if this attempt fails nextTry = datetime.timedelta( seconds=self.RETRANS_TIMES[self.tries]) sch.schedule(self, extime.Time() + nextTry) if not self.running: self.running = True self.tries += 1 d = self.sendmail() d.addCallback(self.mailSent, sch) d.addErrback(self.failureSending, sch) d.addErrback(log.err)
def renew(self): """Renew the lifetime of this object. Call this when the user logs in so this session does not expire. """ self.lastUsed = extime.Time()
def __init__(self, **kw): assert kw.get( 'sessionKey' ) is not None, "None cookie propogated to PersistentSession" kw['lastUsed'] = extime.Time() super(PersistentSession, self).__init__(**kw)
def __init__(self, **kw): if 'created' not in kw: kw['created'] = extime.Time() return super(POP3Grabber, self).__init__(**kw)