# Buggy code
async def _announce(self, batch_size: typing.Optional[int] = 10):
    if not self.node.joined.is_set():
        await self.node.joined.wait()
    blob_hashes = await self.storage.get_blobs_to_announce()
    if blob_hashes:
        self.announce_queue.extend(blob_hashes)
        log.info("%i blobs to announce", len(blob_hashes))
    batch = []
    while len(self.announce_queue):
        cnt = 0
        announced = []
        while self.announce_queue and cnt < batch_size:
            blob_hash = self.announce_queue.pop()
            announced.append(blob_hash)
            batch.append(self.node.announce_blob(blob_hash))
            cnt += 1
        to_await = []
        while batch:
            to_await.append(batch.pop())
        if to_await:
            await asyncio.gather(*tuple(to_await), loop=self.loop)
            await self.storage.update_last_announced_blobs(announced, self.loop.time())
            log.info("announced %i blobs", len(announced))
    if self.running:
        self.pending_call = self.loop.call_later(60, self.announce, batch_size)


# Traceback (ValueError)
2018-07-10 15:35:31,165 INFO     lbrynet.daemon.Daemon:242: Starting lbrynet-daemon
2018-07-10 15:35:31,187 INFO     lbrynet.daemon.ExchangeRateManager:217: Starting exchange rate manager
2018-07-10 15:35:31,313 INFO     lbrynet.daemon.Daemon:284: Platform: {"lbrynet_version": "0.20.3", "platform": "Windows-10-10.0.15063", "os_system": "Windows", "python_version": "2.7.15", "os_release": "10", "lbryum_version": "3.2.3", "ip": "47.17.162.103", "lbryschema_version": "0.0.16", "processor": "Intel64 Family 6 Model 60 Stepping 3, GenuineIntel", "build": "release"}
2018-07-10 15:35:31,315 INFO     lbrynet.daemon.Daemon:487: Loading databases
2018-07-10 15:35:31,319 INFO     lbrynet.daemon.Daemon:542: Using lbryum wallet
2018-07-10 15:35:31,334 WARNING  lbrynet.core.Session:210: UPnP failed. Reason: ConflictInMappingEntry
2018-07-10 15:35:31,335 ERROR    lbrynet.daemon.DaemonControl:118: Failed to start lbrynet-daemon
Traceback (most recent call last):
File "site-packages\lbrynet\daemon\DaemonControl.py", line 115, in start_server_and_listen
File "site-packages\twisted\internet\defer.py", line 1297, in _inlineCallbacks
File "site-packages\twisted\python\failure.py", line 389, in throwExceptionIntoGenerator
File "site-packages\lbrynet\daemon\DaemonServer.py", line 52, in start
File "site-packages\twisted\internet\defer.py", line 1297, in _inlineCallbacks
File "site-packages\twisted\python\failure.py", line 389, in throwExceptionIntoGenerator
File "site-packages\lbrynet\daemon\Daemon.py", line 252, in setup
File "site-packages\twisted\internet\defer.py", line 651, in _runCallbacks
File "site-packages\lbrynet\core\Session.py", line 135, in <lambda>
File "site-packages\lbrynet\core\Session.py", line 227, in _setup_dht
File "site-packages\lbrynet\dht\hashannouncer.py", line 21, in __init__
File "site-packages\twisted\internet\defer.py", line 1576, in __init__
ValueError: DeferredSemaphore requires tokens >= 1
2018-07-10 15:35:31,358 INFO     lbrynet.daemon.DaemonServer:56: Stopping the reactor
2018-07-10 15:35:31,358 INFO     lbrynet.daemon.Daemon:420: Closing lbrynet session
2018-07-10 15:35:31,358 INFO     lbrynet.daemon.Daemon:421: Status at time of shutdown: loading_wallet
2018-07-10 15:35:31,359 INFO     lbrynet.core.Session:141: Stopping session.
2018-07-10 15:35:31,359 INFO     lbrynet.core.Wallet:208: Stopping wallet.

# Fixed code
async def _announce(self, batch_size: typing.Optional[int] = 10):
    if not batch_size:
        return
    if not self.node.joined.is_set():
        await self.node.joined.wait()
    blob_hashes = await self.storage.get_blobs_to_announce()
    if blob_hashes:
        self.announce_queue.extend(blob_hashes)
        log.info("%i blobs to announce", len(blob_hashes))
    batch = []
    while len(self.announce_queue):
        cnt = 0
        announced = []
        while self.announce_queue and cnt < batch_size:
            blob_hash = self.announce_queue.pop()
            announced.append(blob_hash)
            batch.append(self.node.announce_blob(blob_hash))
            cnt += 1
        to_await = []
        while batch:
            to_await.append(batch.pop())
        if to_await:
            await asyncio.gather(*tuple(to_await), loop=self.loop)
            await self.storage.update_last_announced_blobs(announced, self.loop.time())
            log.info("announced %i blobs", len(announced))
    if self.running:
        self.pending_call = self.loop.call_later(60, self.announce, batch_size)