Beispiel #1
0
    def send(self, name, args, kwargs, sync=True, bot_id=None, botname=None):
        #print('send:', name, args, kwargs, sync, bot_id)
        if not bot_id:
            bot_id = self.bot_id
        if '.http' == name:
            #if len(args[1]) > 1400 and b'\x1f\x8b\x08\x00' != args[1][:4]:
            #    data = b''.join([b'HTTP', json.dumps(args[0], ensure_ascii=False, separators=(',', ':')).encode('utf8'),  b'\r\n', gzip_encode(args[1])])
            #else:
            data = b''.join([
                b'HTTP',
                json.dumps(args[0], ensure_ascii=False,
                           separators=(',', ':')).encode('utf8'), b'\r\n',
                args[1]
            ])
        else:
            data = {'method': name, 'args': args, 'kwargs': kwargs}
            data = json.dumps(data, ensure_ascii=False,
                              cls=ExtJSONEncoder).encode('utf8')
            if len(data) > 1400:
                data = gzip_encode(data)

        if not self._online.wait(10):
            raise RuntimeError('[ %s ] connect timeout' % str(self._address))
        """
        c = 0
        while not self._fg_serve_forever:
            c += 1
            if c > 10000:
                raise RuntimeError('[ %s ] connect timeout' % str(self._address))
            time.sleep(0.001)
        """

        r = Event()
        r.ask = False
        r.result = None
        r.error = None
        i = id(r)

        #cli, sid = 'cli.%s.%x' % (uuid.uuid4().hex, i), '1.%x' % i
        #cmd = ('SUB %(cli)s %(sid)s\r\nUNSUB %(sid)s 2\r\nPUB %(bot)s %(cli)s %(l)s\r\n%%s\r\n' % {'cli': cli, 'sid': sid, 'l': len(data), 'bot': bot_id}).encode()
        #print(cmd)
        #data = cmd % data

        data = ('PUB %s %s.%x %s\r\n' % (bot_id, self.cli_id, i, len(data))
                ).encode('utf8') + data + b'\r\n'

        self._sync[i] = r
        err = None
        with self._w_lck:
            #self._send_count += 1
            try:
                #if 0 == self._send_count % 10:
                #    self._sock.close()
                #    raise ValueError('self._send_count: %s' % self._send_count)
                self._sock.sendall(data)
            except Exception as e:
                err = e
                #self.cli_id = 'cli.%s' % uuid.uuid4().hex
                self._sock.close()
                self._online.clear()
                log(None)
        if err:
            log('[ %s ] reconnect' % str(self._address))
            if not self._online.wait(5):
                raise RuntimeError('[ %s ] connect timeout' %
                                   str(self._address))
            with self._w_lck:
                self._sock.sendall(data)

        #print('self._send_count:', self._send_count, flush=True)
        if type(sync) in (list, tuple):
            _wait1, _wait2 = sync[:2]
        else:
            _wait1, _wait2 = 5, 40
        if r.wait(_wait1):
            r.clear()
        else:
            r.error = ServiceError('Service <%s> not found' %
                                   (botname if botname else self._botname))
            #with self._w_lck:
            #    self._sock.sendall(('UNSUB %s\r\n' % sid).encode())
            if sync:
                del self._sync[i]
                raise r.error
        if sync:
            if not _wait2:
                return r
            if r.wait(_wait2) != True:
                r.error = MethodError('Method <%s> timeout' % name)
                #with self._w_lck:
                #    self._sock.sendall(('UNSUB %s\r\n' % sid).encode())
            del self._sync[i]
            if r.error:
                if isinstance(r.error, (str, unicode)):
                    raise RuntimeError(r.error)
                raise r.error
            return r.result
        else:
            return r