Port stream_quotes to tractor ipc protocol
parent
37eb8a8552
commit
fa8418f97f
|
@ -75,6 +75,7 @@ async def stream_quotes(
|
||||||
tickers2chans: {str: Channel},
|
tickers2chans: {str: Channel},
|
||||||
rate: int = 5, # delay between quote requests
|
rate: int = 5, # delay between quote requests
|
||||||
diff_cached: bool = True, # only deliver "new" quotes to the queue
|
diff_cached: bool = True, # only deliver "new" quotes to the queue
|
||||||
|
cid: str = None,
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Stream quotes for a sequence of tickers at the given ``rate``
|
"""Stream quotes for a sequence of tickers at the given ``rate``
|
||||||
per second.
|
per second.
|
||||||
|
@ -82,6 +83,7 @@ async def stream_quotes(
|
||||||
A broker-client ``quoter`` async context manager must be provided which
|
A broker-client ``quoter`` async context manager must be provided which
|
||||||
returns an async quote function.
|
returns an async quote function.
|
||||||
"""
|
"""
|
||||||
|
packet = {'yield': {}, 'cid': cid}
|
||||||
broker_limit = getattr(brokermod, '_rate_limit', float('inf'))
|
broker_limit = getattr(brokermod, '_rate_limit', float('inf'))
|
||||||
if broker_limit < rate:
|
if broker_limit < rate:
|
||||||
rate = broker_limit
|
rate = broker_limit
|
||||||
|
@ -108,7 +110,7 @@ async def stream_quotes(
|
||||||
quotes = await wait_for_network(partial(get_quotes, tickers))
|
quotes = await wait_for_network(partial(get_quotes, tickers))
|
||||||
|
|
||||||
postquote_start = time.time()
|
postquote_start = time.time()
|
||||||
q_payloads = {}
|
chan_payloads = {}
|
||||||
for symbol, quote in quotes.items():
|
for symbol, quote in quotes.items():
|
||||||
if diff_cached:
|
if diff_cached:
|
||||||
# if cache is enabled then only deliver "new" changes
|
# if cache is enabled then only deliver "new" changes
|
||||||
|
@ -119,14 +121,15 @@ async def stream_quotes(
|
||||||
f"New quote {quote['symbol']}:\n{new}")
|
f"New quote {quote['symbol']}:\n{new}")
|
||||||
_cache[symbol] = quote
|
_cache[symbol] = quote
|
||||||
for chan in tickers2chans[symbol]:
|
for chan in tickers2chans[symbol]:
|
||||||
q_payloads.setdefault(chan, {})[symbol] = quote
|
chan_payloads.setdefault(
|
||||||
|
chan, packet.copy())['yield'][symbol] = quote
|
||||||
else:
|
else:
|
||||||
for chan in tickers2chans[symbol]:
|
for chan in tickers2chans[symbol]:
|
||||||
q_payloads.setdefault(chan, {})[symbol] = quote
|
chan_payloads.setdefault(
|
||||||
|
chan, packet.copy())['yield'][symbol] = quote
|
||||||
# deliver to each subscriber
|
# deliver to each subscriber
|
||||||
if q_payloads:
|
if chan_payloads:
|
||||||
for chan, payload in q_payloads.items():
|
for chan, payload in chan_payloads.items():
|
||||||
try:
|
try:
|
||||||
await chan.send(payload)
|
await chan.send(payload)
|
||||||
except (
|
except (
|
||||||
|
@ -134,7 +137,7 @@ async def stream_quotes(
|
||||||
trio.ClosedStreamError, ConnectionResetError,
|
trio.ClosedStreamError, ConnectionResetError,
|
||||||
ConnectionRefusedError,
|
ConnectionRefusedError,
|
||||||
):
|
):
|
||||||
log.warn(f"{chan.addr} went down?")
|
log.warn(f"{chan.raddr} went down?")
|
||||||
for qset in tickers2chans.values():
|
for qset in tickers2chans.values():
|
||||||
qset.discard(chan)
|
qset.discard(chan)
|
||||||
|
|
||||||
|
@ -275,13 +278,13 @@ async def _brokerd_main(host) -> None:
|
||||||
start_quoter, broker2tickersubs, clients,
|
start_quoter, broker2tickersubs, clients,
|
||||||
dtasks, nursery
|
dtasks, nursery
|
||||||
),
|
),
|
||||||
1616, host=host,
|
1617, host=host,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
log.debug(f"Spawned {listeners}")
|
log.debug(f"Spawned {listeners}")
|
||||||
|
|
||||||
|
|
||||||
async def _test_price_stream(broker, symbols, *, chan=None):
|
async def _test_price_stream(broker, symbols, *, chan=None, cid=None):
|
||||||
"""Test function for initial tractor draft.
|
"""Test function for initial tractor draft.
|
||||||
"""
|
"""
|
||||||
brokermod = get_brokermod(broker)
|
brokermod = get_brokermod(broker)
|
||||||
|
@ -292,14 +295,8 @@ async def _test_price_stream(broker, symbols, *, chan=None):
|
||||||
assert chan
|
assert chan
|
||||||
tickers2chans = {}.fromkeys(symbols, {chan, })
|
tickers2chans = {}.fromkeys(symbols, {chan, })
|
||||||
|
|
||||||
async def terminate_on_None(chan, nursery):
|
|
||||||
val = await chan.recv()
|
|
||||||
if val is None:
|
|
||||||
log.info("Got terminate sentinel!")
|
|
||||||
nursery.cancel_scope.cancel()
|
|
||||||
|
|
||||||
async with trio.open_nursery() as nursery:
|
async with trio.open_nursery() as nursery:
|
||||||
nursery.start_soon(
|
nursery.start_soon(
|
||||||
stream_quotes, brokermod, get_quotes, tickers2chans)
|
partial(
|
||||||
# nursery.start_soon(
|
stream_quotes, brokermod, get_quotes, tickers2chans, cid=cid)
|
||||||
# terminate_on_None, chan, nursery)
|
)
|
||||||
|
|
Loading…
Reference in New Issue