Example #1
0
 def test_slot_creation(self):
     session = m.get_session()
     s1 = m.Slot(sid='a',
                 name='test_slot',
                 keys='k1|k2',
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     s2 = m.Slot(sid='b',
                 name='implied_volatilty',
                 keys='k1|k2',
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.',
                 state=m.SlotStatesEnum.current)
     p1 = m.Producer(state=m.ProducerStatesEnum.completed,
                     pname='trs_fitter',
                     keys='k1|k2',
                     date=dt.datetime(2019, 6, 9).date(),
                     args='{}')
     s1.listeners.append(p1)
     p1.outputs.append(s2)
     session.add(s1)
     session.add(s2)
     session.add(p1)
     session.commit()
     session.query(m.Slot).filter_by(sid='a').one()
     session.query(m.Slot).filter_by(sid='b').one()
     session.query(m.Producer).one()
Example #2
0
def start_producers():
    session_ = get_session()
    pnames = [
        x[0] for x in session_.query(Producer.pname).filter(
            Producer.pending()).distinct()
    ]
    for pname in pnames:
        pobj = net.producers[pname].obj
        batch_size = pobj.batch_size
        min_delay = dt.timedelta(seconds=pobj.delay)
        threshold = dt.datetime.utcnow() - min_delay
        logger.debug("starting Producer '%s' (batch_size=%s, delay=%s" %
                     (pname, batch_size, min_delay))
        producers = (session_.query(Producer).filter(
            Producer.pending()).filter(Producer.pname == pname).filter(
                Producer.last_updated <= threshold)).all()
        logger.debug("%s task ready for execution" % len(producers))
        for idx in range(0, len(producers), batch_size):
            execute(producers[idx:(idx + batch_size)])
            # Need to set status on input slots to pending
            for producer in producers[idx:(idx + batch_size)]:
                for slot in producer.inputs:
                    logger.debug(
                        "slot '%s' with sid='%s' set to PENDING due to running producer"
                        % (slot.name, slot.sid))
                    slot.pending.set()
            session_.commit()
Example #3
0
 def test_slot_insertion(self):
     session = m.get_session()
     s1 = m.Slot(name='european_totem',
                 keys='k1|k2',
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     m.insert_slot(s1)
     s2 = m.Slot(name='varswap_totem',
                 keys='k1|k2',
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     m.insert_slot(s2, None)
     for item in session.query(m.InputSlot):
         print item
Example #4
0
 def test_start_producer(self):
     session = m.get_session()
     keys = '1|EUR|euro|equity|index'
     p1 = m.Producer(state=m.ProducerStatesEnum.completed,
                     pname='totem_daily',
                     keys=keys,
                     date=dt.datetime(2019, 6, 9).date(),
                     args='{}')
     s1 = m.Slot(name='european_totem',
                 keys=keys,
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     s2 = m.Slot(name='varswap_totem',
                 keys=keys,
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     s3 = m.Slot(name='implied_vol',
                 keys=keys,
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     s4 = m.Slot(name='dividends',
                 keys=keys,
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     s5 = m.Slot(name='product_rate',
                 keys=keys,
                 date=dt.datetime(2019, 6, 9).date(),
                 priority=1,
                 dbid='.')
     m.insert_slot(s1, p1)
     m.insert_slot(s2, p1)
     m.insert_slot(s3, p1)
     m.insert_slot(s4, p1)
     m.insert_slot(s5, p1)
     p.schedule_producers()
     for row in session.query(m.Producer):
         print row
     p.start_producers()
     time.sleep(5)
     p.start_producers()
     time.sleep(5)
     p.start_producers()
Example #5
0
def get_producer(pid):
    session = m.get_session()
    return session.query(m.Producer).filter_by(pid=pid).one()
Example #6
0
def get_producers():
    session = m.get_session()
    return session.query(m.Producer).all()
Example #7
0
def get_inputslot(id_):
    session = m.get_session()
    return session.query(m.InputSlot).filter_by(id_=id_).one()
Example #8
0
def get_inputslots():
    session = m.get_session()
    return session.query(m.InputSlot).all()
Example #9
0
def get_slot(sid):
    session = m.get_session()
    return session.query(m.Slot).filter_by(sid=sid).one()
Example #10
0
def get_slots():
    session = m.get_session()
    return session.query(m.Slot).all()
Example #11
0
 def run(self):
     logger.debug("autofit.app.Loop STARTED!")
     session_ = get_session()
     while not self._stop:
         if self.queue.empty():
             time.sleep(2)
         else:
             parcel = self.queue.get()
             if parcel['state'] != 'ok':
                 continue
             pname = parcel['pname']
             pid = parcel['pid']
             logger.debug("Receiver data from producer with pid '%s'" % pid)
             if pid:
                 query = session_.query(Producer).filter_by(pid=pid)
                 try:
                     p = query.one()
                     if p.halted():
                         logger.debug(
                             "Producer with pid='%s' was halted, update skipped"
                             % pid)
                         continue
                     if not p.running():
                         logger.error(
                             "Producer with pid='%s' in an inconsistent state '%s'"
                             % (pid, p.state))
                         continue
                 except NoResultFound:
                     logger.exception(
                         "producer with pid='%s' does not exist" % pid)
                     continue
                 except MultipleResultsFound:
                     logger.exception("multiple producer with pid='%s'" %
                                      pid)
                     continue
                 except Exception as e:
                     logger.exception(str(e))
             elif not isinstance(net.producers[pname].obj, Daemon):
                 logger.exception("non-daemon producer missing pid")
             else:  # the producer is a daemon, set p to None
                 p = None
             logger.debug("valid data received from pid='%s'" % pid)
             date = parcel['date']
             priority = parcel['priority']
             if p:
                 p.completed.set()
                 for slot in p.inputs:
                     is_completed = True
                     for producer in slot.listeners:
                         if not producer.completed():
                             is_completed = False
                             break
                     if is_completed:
                         slot.current.set()
             for slot in parcel['slots']:
                 oslot = Slot(name=slot['sname'],
                              keys=slot['keys'],
                              date=date,
                              priority=priority,
                              state=SlotStatesEnum.pending,
                              dbid=slot['dbid'])
                 insert_slot(oslot, p)
         schedule_producers()
         start_producers()
     logger.debug('mail loop halted')
Example #12
0
def schedule_producers():
    ids = set()
    session_ = get_session()
    potprods = session_.query(InputSlot.pname).filter(
        InputSlot.updated()).distinct()
    for producer in potprods:
        pname = producer.pname
        logger.debug("joining producer %s" % pname)
        oproducer = net.producers[pname].obj  # type: ptypes._ProducerBase
        skeys = net.slots[oproducer.provides[0]].obj.keys.split('|')
        spkeys = skeys + ['pname', 'date']
        fkeys = [InputSlot.__dict__[key]
                 for key in spkeys]  # keys mapped to the ORM attributes
        ukeys = session_.query(*fkeys).filter(
            and_(InputSlot.updated(), InputSlot.pname == pname))
        for fkey in fkeys:
            ukeys = ukeys.filter(
                fkey.isnot(None))  # TODO: do I really need this?
        ukeys = ukeys.group_by(*fkeys).distinct()
        for ukey in ukeys:
            date = ukey.date
            keys_dict = ukey._asdict()
            seed = alias(
                select([
                    cast(literal(val), String).label(key)
                    for key, val in keys_dict.items()
                ]), 'seed')
            joins = []
            columns = []
            ons = []
            counter = {}
            sids = set()
            for jslot in oproducer.requires:  # type: ptypes.JoinedSlot
                name = jslot.alias or jslot.name
                if name in counter:
                    name_ = jslot.alias or "%s_%s" % (name, counter[name])
                    counter[name] += 1
                else:
                    name_ = name
                    counter[name] = 1
                table = session_.query(aliased(
                    InputSlot, name=name_)).filter_by(sname=name,
                                                      pname=pname,
                                                      date=date).subquery()
                joins.append(table)
                this_column = table.c.sid.label(name_)
                columns.append(this_column)
                join_on = True
                slot_keys = jslot.slot_keys or skeys
                producer_keys = jslot.producer_keys or skeys
                for s, p in zip(slot_keys, producer_keys):
                    join_on = and_(join_on, seed.c[p] == table.c[s])
                for row in session_.query(table.c.sid).select_from(
                        seed.join(table, join_on)):
                    # need to keep track of this to link the producer to the slots it processes
                    #
                    sids.add(row.sid)
                for row in (session_.query(table.c.id_).select_from(
                        seed.join(table, join_on)).filter(
                            table.c.state == InputSlotStatesEnum.updated)):
                    ids.add(
                        row.id_
                    )  # need to keep track of this to set the 'processed' state to used InputSlot
                    logger.debug('added id_ %s' % row.id_)
                ons.append(join_on)
            seed = session_.query(seed, *columns)
            for table, on, jslot in zip(joins, ons, oproducer.requires):
                if jslot.exclusive:
                    seed = seed.outerjoin(table,
                                          on).filter(table.c.id_.is_(None))
                else:
                    seed = seed.join(table, on)
            if seed.count():
                args = [row._asdict() for row in seed]
                args = json.dumps(args)
                slots = session_.query(Slot).filter(Slot.sid.in_(sids)).all()
                logger.debug("producer '%s' is READY" % pname)
                this_keys = '|'.join([keys_dict[k] for k in skeys])
                this_producer = Producer(state=ProducerStatesEnum.void,
                                         pname=pname,
                                         keys=this_keys,
                                         date=date,
                                         args=args)
                try:
                    insert_producer(producer=this_producer, slots=slots)
                except (InconsistentProducerState,
                        MultipleProducerException) as e:
                    logger.exception(str(e))
                    continue  # some other action here
            else:
                logger.debug("producer '%s' is INCOMPLETE" % pname)
    for input_slot in session_.query(InputSlot).filter(InputSlot.id_.in_(ids)):
        logger.info("InputSlot.id_='%s', "
                    "pname='%s', sname='%s', sid='%s' was PROCESSED" %
                    (input_slot.id_, input_slot.pname, input_slot.sname,
                     input_slot.sid))
        input_slot.processed.set()
    session_.commit()