Slightly cleaner semaphore fix

This commit is contained in:
Neil Booth 2017-01-02 16:12:36 +09:00
parent 62eded55bb
commit 67908b3541

View File

@ -1,4 +1,4 @@
# Copyright (c) 2016, Neil Booth # Copyright (c) 2016-2017, Neil Booth
# #
# All rights reserved. # All rights reserved.
# #
@ -88,9 +88,8 @@ class Prefetcher(LoggedClass):
while True: while True:
try: try:
with await self.semaphore: # Sleep a while if there is nothing to prefetch
fetched = await self._prefetch_blocks(caught_up_event.is_set()) if not await self._prefetch_blocks(caught_up_event.is_set()):
if not fetched:
await asyncio.sleep(5) await asyncio.sleep(5)
await self.refill_event.wait() await self.refill_event.wait()
except DaemonError as e: except DaemonError as e:
@ -106,39 +105,41 @@ class Prefetcher(LoggedClass):
sleep for a period of time before returning. sleep for a period of time before returning.
''' '''
daemon_height = await self.daemon.height(mempool) daemon_height = await self.daemon.height(mempool)
while self.cache_size < self.min_cache_size: with await self.semaphore:
# Try and catch up all blocks but limit to room in cache. while self.cache_size < self.min_cache_size:
# Constrain fetch count to between 0 and 2500 regardless. # Try and catch up all blocks but limit to room in cache.
cache_room = self.min_cache_size // self.ave_size # Constrain fetch count to between 0 and 2500 regardless.
count = min(daemon_height - self.fetched_height, cache_room) cache_room = self.min_cache_size // self.ave_size
count = min(2500, max(count, 0)) count = min(daemon_height - self.fetched_height, cache_room)
if not count: count = min(2500, max(count, 0))
self.cache.put_nowait(([], 0)) if not count:
self.caught_up = True self.cache.put_nowait(([], 0))
return False self.caught_up = True
return False
first = self.fetched_height + 1 first = self.fetched_height + 1
hex_hashes = await self.daemon.block_hex_hashes(first, count) hex_hashes = await self.daemon.block_hex_hashes(first, count)
if self.caught_up: if self.caught_up:
self.logger.info('new block height {:,d} hash {}' self.logger.info('new block height {:,d} hash {}'
.format(first + count - 1, hex_hashes[-1])) .format(first + count-1, hex_hashes[-1]))
blocks = await self.daemon.raw_blocks(hex_hashes) blocks = await self.daemon.raw_blocks(hex_hashes)
assert count == len(blocks)
# Strip the unspendable genesis coinbase assert count == len(blocks)
if first == 0:
blocks[0] = blocks[0][:self.coin.HEADER_LEN] + bytes(1)
# Update our recent average block size estimate # Strip the unspendable genesis coinbase
size = sum(len(block) for block in blocks) if first == 0:
if count >= 10: blocks[0] = blocks[0][:self.coin.HEADER_LEN] + bytes(1)
self.ave_size = size // count
else:
self.ave_size = (size + (10 - count) * self.ave_size) // 10
self.cache.put_nowait((blocks, size)) # Update our recent average block size estimate
self.cache_size += size size = sum(len(block) for block in blocks)
self.fetched_height += count if count >= 10:
self.ave_size = size // count
else:
self.ave_size = (size + (10 - count) * self.ave_size) // 10
self.cache.put_nowait((blocks, size))
self.cache_size += size
self.fetched_height += count
self.refill_event.clear() self.refill_event.clear()
return True return True