Beispiel #1
0
class Login(MappedClass):
    class __mongometa__:
        session = MingSession
        name = "logins"

    _id = s.ObjectId()
    id = s.Int()
    device_id = s.Int()
    datetime = s.DateTime()

    def __str__(self):
        return f"<Login(mongo) device_id={self.device_id} datetime={self.datetime}>"
Beispiel #2
0
class TPremium(MappedClass, EnhancingClass):
    class __mongometa__:
        session = session
        name = 'testpremiums'
        extensions = [ MyExtension ]
    
    _id = FieldProperty(schema.ObjectId)
    premium_id = ForeignIdProperty(TPremiumSize)
    worker_id = ForeignIdProperty(TWorker)
    earning_date = FieldProperty(schema.DateTime(required=True))
    premium_size = FieldProperty(schema.Int(required=True))
    note = FieldProperty(schema.String(if_missing = '')) 
    
    worker = RelationProperty(TWorker)
    premium = RelationProperty(TPremiumSize)
class TPremium(MappedClass, EnhancingClass):
    class __mongometa__:
        session = session
        name = 'testpremiums'
        extensions = [ MyExtension ]
    
    #primary key
    _id = FieldProperty(schema.ObjectId)
    
    #foreign keys
    premium_id = FieldProperty(schema.String(required = True))
    worker_id = FieldProperty(schema.String(required = True))
    
    #properties
    earning_date = FieldProperty(schema.DateTime(required=True))
    premium_size = FieldProperty(schema.Int(required=True))
    note = FieldProperty(schema.String(if_missing = ''))
Beispiel #4
0
class Premium(MappedClass, EnhancingClass):
    class __mongometa__:
        session = session
        name = collection_name
        extensions = [PremiumTriggers]
        custom_indexes = [
            dict(fields=('premium_id', ), unique=False),
            dict(fields=('worker_id', ), unique=False)
        ]

    _id = FieldProperty(schema.ObjectId)

    premium_id = StringSingleForeignKeyProperty(PremiumSize)
    worker_id = StringSingleForeignKeyProperty(Worker)
    earning_date = FieldProperty(schema.DateTime(required=True))
    size = FieldProperty(schema.Float(required=True))

    note = FieldProperty(schema.String(if_missing=""))
Beispiel #5
0
class HTTPMessage(Document):
    missing_client = '-' * 50
    channel = ChannelProxy('chapman.event')

    class __mongometa__:
        name = 'chapman.http_message'
        session = doc_session
        indexes = [[('s.status', 1), ('s.pri', -1), ('s.ts_enqueue', 1),
                    ('s.q', 1)],
                   [('s.q', 1), ('s.status', 1), ('s.pri', -1),
                    ('s.ts_enqueue', 1)], [('tags', 1)]]

    _id = Field(int, if_missing=lambda: getrandbits(63))
    _data = Field('data', S.Binary(if_missing=bson.Binary('{}')))
    tags = Field('tags', [str])
    schedule = Field(
        's',
        dict(status=S.String(if_missing='ready'),
             ts_enqueue=S.DateTime(if_missing=datetime.utcnow),
             ts_reserve=S.DateTime(if_missing=None),
             ts_timeout=S.DateTime(if_missing=None),
             timeout=S.Int(if_missing=300),
             after=S.DateTime(if_missing=datetime.fromtimestamp(0)),
             q=S.String(if_missing='chapman.http'),
             pri=S.Int(if_missing=10),
             cli=S.String(if_missing=missing_client)))

    def __json__(self, request):
        return {self.url(request): self.data}

    @property
    def data(self):
        return json.loads(self._data)

    @data.setter
    def data(self, value):
        self._data = bson.Binary(json.dumps(value, default=util.default_json))

    def url(self, request):
        scheme = request.registry.settings.get('chapman.message_url_scheme',
                                               None)
        args = dict(message_id=self._id)
        if scheme is not None:
            args['_scheme'] = scheme
        return request.route_url('chapman.1_0.message', **args)

    @classmethod
    def new(cls,
            data,
            timeout=300,
            after=None,
            q='chapman.http',
            pri=10,
            tags=None):
        if tags is None:
            tags = []
        _data = bson.Binary(json.dumps(data, default=util.default_json))
        if after is None:
            after = datetime.utcnow()
        self = cls.make(
            dict(data=_data,
                 tags=tags,
                 s=dict(timeout=timeout, after=after, q=q, pri=pri)))
        self.m.insert()
        self.channel.pub('enqueue', self._id)
        return self

    @classmethod
    def reserve(cls, cli, queues):
        return cls._reserve(cli, {'$in': queues})

    @classmethod
    def _reserve(cls, cli, qspec):
        now = datetime.utcnow()
        self = cls.m.find_and_modify(
            {
                's.status': 'ready',
                's.q': qspec,
                's.after': {
                    '$lte': now
                }
            },
            sort=[('s.pri', -1), ('s.ts_enqueue', 1)],
            update={
                '$set': {
                    's.cli': cli,
                    's.status': 'reserved',
                    's.ts_reserve': now
                }
            },
            new=True)
        if self is not None and self.s.timeout:
            self.m.set(
                {'s.ts_timeout': now + timedelta(seconds=self.s.timeout)})
        return self
Beispiel #6
0
 def __init__(self, worker_class, service_class):
     self.worker_class = worker_class
     self.service_class = service_class
     super(VisitDateTimeProperty,
           self).__init__(schema.DateTime(required=True))
Beispiel #7
0
class Message(Document):
    missing_worker = '-' * 10
    channel = ChannelProxy('chapman.event')

    class __mongometa__:
        name = 'chapman.message'
        session = doc_session
        indexes = [
            [('s.status', 1), ('s.pri', -1), ('s.ts', 1), ('s.q', 1)],
            [('s.q', 1), ('s.status', 1), ('s.sub_status', -1), ('s.pri', -1), ('s.ts', 1)],
            [('task_id', 1)],
        ]
    _id = Field(int, if_missing=lambda: getrandbits(63))
    task_id = Field(int, if_missing=None)
    task_repr = Field(str, if_missing=None)
    slot = Field(str)
    _args = Field('args', S.Binary)
    _kwargs = Field('kwargs', S.Binary)
    _send_args = Field('send_args', S.Binary)
    _send_kwargs = Field('send_kwargs', S.Binary)
    schedule = Field('s', dict(
        status=S.String(if_missing='pending'),
        sub_status=S.Int(if_missing=0),
        ts=S.DateTime(if_missing=datetime.utcnow),
        after=S.DateTime(if_missing=datetime.utcnow),
        q=S.String(if_missing='chapman'),
        pri=S.Int(if_missing=10),
        w=S.String(if_missing=missing_worker),
        semaphores=[str]))

    def __repr__(self):
        return '<msg (%s:%s) %s to %s %s on %s>' % (
            self.schedule.status, self.schedule.sub_status,
            self._id, self.slot, self.task_repr,
            self.schedule.w)

    @classmethod
    def n(cls, task, slot, *args, **kwargs):
        '''Convenience method for Message.new'''
        return cls.new(task, slot, args, kwargs)

    @classmethod
    def new(cls, task, slot, args, kwargs, after=None):
        if args is None:
            args = ()
        if kwargs is None:
            kwargs = {}
        self = cls.make(dict(
            task_id=task.id,
            task_repr=repr(task),
            slot=slot,
            s=task.schedule_options()))
        if after is not None:
            self.s.after = after
        self.args = args
        self.kwargs = kwargs
        self.m.insert()
        return self

    @classmethod
    def reserve(cls, worker, queues):
        '''Reserve a message & try to lock the task state.

        - If no message could be reserved, return (None, None)
        - If a message was reserved, but the resources could not be acquired,
          return (msg, None)
        - If a message was reserved, and the resources were acquired, return
          (msg, task)
        '''
        qspec = {'$in': queues}
        return cls._reserve(worker, qspec)

    @classmethod
    def reserve_qspec(cls, worker, qspec):
        '''Reserve according to a queue specification to allow for
        more interesting queue topologies
        '''
        return cls._reserve(worker, qspec)

    def retire(self):
        '''Retire the message.'''
        self._release_resources()
        self.m.delete()

    def unlock(self):
        '''Make a message ready for processing'''
        self._release_resources()
        # Re-dispatch this message
        self.__class__.m.update_partial(
            {'_id': self._id},
            {'$set': {
                's.status': 'ready',
                's.sub_status': 0,
                's.w': self.missing_worker}})
        self.channel.pub('send', self._id)

    def send(self, *args, **kwargs):
        self.m.set(
            {'s.status': 'ready',
             's.ts': datetime.utcnow(),
             'send_args': dumps(args),
             'send_kwargs': dumps(kwargs)})
        self.channel.pub('send', self._id)

    @property
    def args(self):
        result = []
        if self._send_args is not None:
            result += loads(self._send_args)
        if self._args is not None:
            result += loads(self._args)
        return tuple(result)

    @args.setter
    def args(self, value):
        self._args = dumps(value)

    @property
    def kwargs(self):
        result = {}
        if self._kwargs is not None:
            result.update(loads(self._kwargs))
        if self._send_kwargs is not None:
            result.update(loads(self._send_kwargs))
        return result

    @kwargs.setter
    def kwargs(self, value):
        self._kwargs = dumps(value)

    @property
    def resources(self):
        for sem in self.s.semaphores:
            yield SemaphoreResource(sem)
        yield TaskStateResource(self.task_id)

    @classmethod
    def _reserve(cls, worker, qspec):
        '''Reserves a message.'''
        now = datetime.utcnow()
        # Begin acquisition of resources
        self = cls.m.find_and_modify(
            {'s.q': qspec, 's.status': 'ready', 's.after': {'$lte': now}},
            sort=[('s.sub_status', -1), ('s.pri', -1), ('s.ts', 1)],
            update={'$set': {'s.w': worker, 's.status': 'acquire'}},
            new=True)
        if self is None:
            return None, None

        # Acquire any resources necessary
        for i, res in enumerate(self.resources):
            if i < self.s.sub_status:  # already acquired
                continue
            if not res.acquire(self._id):
                self.m.set({'s.status': 'queued'})
                return self, None
            else:
                res = cls.m.update_partial(
                    {'_id': self._id},
                    {'$set': {'s.sub_status': i + 1}})
        self.m.set({'s.status': 'busy'})
        return self, TaskState.m.get(_id=self.task_id)

    def _release_resources(self):
        msg_id = None
        for res in reversed(list(self.resources)):
            to_release = res.release(self._id)
            res = Message.m.update_partial(
                {'_id': {'$in': to_release}, 's.status': 'queued'},
                {'$set': {'s.status': 'ready'}},
                multi=True)
            if to_release and res['updatedExisting']:
                msg_id = to_release[0]
        if msg_id is not None:
            self.channel.pub('send', msg_id)