def execute(self): # we periodically clear any locks that have exceeded lock time # this will be messages that were locked but never sent for some reason if self.next_lock_timeout_check is None or datetime.datetime.now( ) >= self.next_lock_timeout_check: saq.db.execute( MessageRouting.__table__.update().values(lock=None).where( and_( MessageRouting.lock == None, func.TIMESTAMPDIFF(text('SECOND'), MessageRouting.lock_time, func.NOW())))) saq.db.commit() self.next_lock_timeout_check = datetime.datetime.now() + \ datetime.timedelta(seconds=saq.CONFIG['messaging'].getint('lock_timeout')) # get the next message to send message_route = saq.db.query(MessageRouting).options( joinedload('message')).filter( MessageRouting.lock == self.lock_uuid).order_by( asc(MessageRouting.message_id)).first() if message_route is None: # if we didn't get one then go ahead and lock the next batch of messages target_ids = saq.db.query(MessageRouting.id).filter(and_( MessageRouting.lock == None, MessageRouting.route == self.route))\ .order_by(asc(MessageRouting.id))\ .limit(self.batch_size)\ .all() target_ids = [_[0] for _ in target_ids] # did we not find anything? if not target_ids: if self.controlled_stop: raise ControlledStop() else: return 5 saq.db.execute(MessageRouting.__table__.update().values( lock=self.lock_uuid, lock_time=func.NOW()).where( and_(MessageRouting.id.in_(target_ids), MessageRouting.lock == None, MessageRouting.route == self.route))) saq.db.commit() # try again to get the next message to send message_route = saq.db.query(MessageRouting).options( joinedload('message')).filter( MessageRouting.lock == self.lock_uuid).order_by( asc(MessageRouting.message_id)).first() # if we still didn't get a message then we wait for a while if message_route is None: if self.controlled_stop: raise ControlledStop() else: return 5 # TODO make configurable? # dispatch the message logging.debug( f"dispatching message {message_route.message_id} to route {message_route.route} destination {message_route.destination}" ) self.dispatch(message_route.message, message_route.destination) # clear this message out saq.db.execute(MessageRouting.__table__.delete().where( MessageRouting.id == message_route.id)) # and finally clear the message if all the routes have completed saq.db.execute(Message.__table__.delete().where( Message.id.notin_(saq.db.query(MessageRouting.message_id)))) saq.db.commit() return 0
def test_func_now(stub_redshift_dialect): dialect = stub_redshift_dialect s = select([func.NOW().label("time")]) compiled = s.compile(dialect=dialect) assert str(compiled) == "SELECT SYSDATE AS time"
def test_uppercase(self): # for now, we need to keep case insensitivity self.assert_compile(func.NOW(), "NOW()")