Exemplo n.º 1
0
    async def request(self,
                      srv,
                      method,
                      *params,
                      req_id=None,
                      timeout=DEFAULT_TIMEOUT_SECS):
        if not self.connected:
            raise ConnectionError('websocket closed')

        method = srv + '::' + method
        if not req_id:
            req_id = uuid.uuid4().hex
        payload = {
            'jsonrpc': '2.0',
            'id': req_id,
            'method': method,
            'params': params
        }

        channel = Channel(1)
        self.waiters[req_id] = channel
        try:
            await self.ws.send_json(payload)
            r = await asyncio.wait_for(channel.get(), timeout=timeout)
            return r
        except ChannelClosed:
            raise ConnectionError('websocket closed on sending req')
        finally:
            channel.close()
Exemplo n.º 2
0
 def test_double_close(self):
     channel = Channel(1, loop=self.loop)
     self.assertFalse(channel.closed())
     channel.close()
     self.assertTrue(channel.closed())
     channel.close()
     self.assertTrue(channel.closed())
Exemplo n.º 3
0
 def test_double_close(self):
     channel = Channel(1, loop=self.loop)
     self.assertFalse(channel.closed())
     channel.close()
     self.assertTrue(channel.closed())
     channel.close()
     self.assertTrue(channel.closed())
Exemplo n.º 4
0
    def test_get_nowait_raises_closed(self):
        channel = Channel(1, loop=self.loop)
        channel.put_nowait("foo")
        channel.close()

        item = channel.get_nowait()
        self.assertEqual(item, "foo")

        self.assertRaises(ChannelClosed, lambda: channel.get_nowait())
Exemplo n.º 5
0
    def test_get_nowait_raises_closed(self):
        channel = Channel(1, loop=self.loop)
        channel.put_nowait("foo")
        channel.close()

        item = channel.get_nowait()
        self.assertEqual(item, "foo")

        self.assertRaises(ChannelClosed, lambda: channel.get_nowait())
Exemplo n.º 6
0
    def test_async_iterator(self):
        """
            Test that we can even construct a Channel
        """
        channel = Channel(loop=self.loop)
        [channel.put_nowait(i) for i in range(10)]
        channel.close()

        async def test():
            s = 0
            async for item in channel:
                s += item
            return s

        result = self.ruc(test())
        self.assertEqual(result, sum(range(10)))
Exemplo n.º 7
0
    async def request(self, srv, method, *params, req_id=None):
        if not self.connected:
            raise ConnectionError('websocket closed')

        url = urljoin(self.url_prefix, '/jsonrpc/2.0/api')

        method = srv + '::' + method
        if not req_id:
            req_id = uuid.uuid4().hex
        payload = {'id': req_id, 'method': method, 'params': params}

        channel = Channel(1)
        self.waiters[req_id] = channel
        try:
            await self.ws.send_json(payload)
            r = await channel.get()
            #del self.waiters[req_id]
            return r
        except ChannelClosed:
            raise ConnectionError('websocket closed on sending req')
        finally:
            channel.close()
Exemplo n.º 8
0
class Worker():

    HEALTH_CHECK_INTERVAL = datetime.timedelta(seconds=60)

    def __init__(self, conn, tm):

        self.conn = conn
        self.logger = logging.getLogger('universe')
        self.last_health_check = now()
        self.ticks = 0
        self.queue = Channel(128)
        self.tm = tm
        self.health = []

    async def run(self):

        async with self.conn.acquire() as conn:
            self.logger.info('Clock fast-forward')
            await conn.execute('UPDATE objects SET refreshed_at = NOW()')

        for i in range(min(multiprocessing.cpu_count(), 4)):
            asyncio.ensure_future(self._dequeue())

        try:
            while True:
                await self._calc_stats()
                await self._tick()

        except asyncio.CancelledError:
            self.logger.info("Terminating gravity worker")
            self.queue.close()
            await self.queue.join()
            return

    async def _calc_stats(self):
        dt = now() - self.last_health_check
        if dt > Worker.HEALTH_CHECK_INTERVAL:
            tps = int(self.ticks /
                      Worker.HEALTH_CHECK_INTERVAL.total_seconds())
            self.logger.debug('Current TPS: {} ({} ticks)'.format(
                tps,
                self.ticks,
            ))
            self.health = [tps, self.ticks]
            self.last_health_check = now()
            self.ticks = 0

            if tps <= Universe.LAG_TPS:
                await self._solar_flare()

    async def _solar_flare(self):
        async with self.conn.acquire() as conn:
            await conn.execute('''
            DELETE FROM objects
            WHERE id IN
            (SELECT id FROM objects
             WHERE created_at < now() - interval '15 minutes'
             ORDER BY created_at asc)''')

    async def _dequeue(self):

        async with self.conn.acquire() as conn:
            async for obj in self.queue:
                await conn.execute(
                    '''
                    UPDATE objects SET
                        position = $2,
                        velocity = $3,
                        mass = $4,
                        refreshed_at = $5
                    WHERE
                        id = $1
                ''', obj.idx, obj.position, obj.velocity, obj.mass,
                    obj.refreshed_at)

    async def _tick(self):

        async with self.conn.acquire() as conn:
            rows = await conn.fetch('''
            SELECT * FROM objects
            ORDER BY refreshed_at asc
            LIMIT 1024
            ''')

            if len(rows) == 0:
                await asyncio.sleep(1 / Universe.GOOD_TPS)

            for row in rows:
                obj = object_from_row(row)
                tc = await self.tm.pop(obj.idx)
                obj.update(tc)
                await self.queue.put(obj)

            # avoid dupes in queue
            while not self.queue.empty():
                await asyncio.sleep(1 / Universe.GOOD_TPS)

            self.ticks += 1
Exemplo n.º 9
0
 def test_put_when_closed(self):
     channel = Channel(1, loop=self.loop)
     channel.close()
     self.assertRaises(ChannelClosed, lambda: self.ruc(channel.put("foo")))
Exemplo n.º 10
0
 def test_put_when_closed(self):
     channel = Channel(1, loop=self.loop)
     channel.close()
     self.assertRaises(ChannelClosed, lambda: self.ruc(channel.put("foo")))