Skip to content

Commit

Permalink
Merge pull request #230 from Datura-ai/fix/metagraph-client
Browse files Browse the repository at this point in the history
fix: update getting axon infos from bittensor sdk
  • Loading branch information
talentwebdev authored Feb 4, 2025
2 parents d77b386 + 0077fa2 commit 1a2464e
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 87 deletions.
9 changes: 7 additions & 2 deletions neurons/validators/src/clients/compute_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ async def miner_driver_awaiter(self):
_m(
"Error occurred during driving a miner client",
extra={**self.logging_extra, "error": str(exc)},
)
),
exc_info=True,
)

async def __aenter__(self):
Expand Down Expand Up @@ -339,7 +340,8 @@ async def wait_for_log_streams(self, channel: aioredis.client.PubSub):
"error": str(exc),
"msg": str(msg),
},
)
),
exc_info=True,
)
continue

Expand Down Expand Up @@ -502,6 +504,9 @@ async def miner_driver(
| ContainerStartRequest,
):
"""drive a miner client from job start to completion, then close miner connection"""
logger.info(
_m(f"Getting miner axon info for {job_request.miner_hotkey}", extra=self.logging_extra)
)
miner_axon_info = await self.get_miner_axon_info(job_request.miner_hotkey)
logging_extra = {
**self.logging_extra,
Expand Down
171 changes: 87 additions & 84 deletions neurons/validators/src/clients/metagraph_client.py
Original file line number Diff line number Diff line change
@@ -1,84 +1,87 @@
import asyncio
import datetime as dt
import logging

import bittensor
from asgiref.sync import sync_to_async

from core.config import settings

logger = logging.getLogger(__name__)


class AsyncMetagraphClient:
def __init__(self, cache_time=dt.timedelta(minutes=5)):
self.cache_time = cache_time
self._metagraph_future = None
self._future_lock = asyncio.Lock()
self._cached_metagraph = None
self._cache_timestamp = None
self.config = settings.get_bittensor_config()

async def get_metagraph(self, ignore_cache=False):
future = None
set_result = False
if self._cached_metagraph is not None:
if not ignore_cache and dt.datetime.now() - self._cache_timestamp < self.cache_time:
return self._cached_metagraph
async with self._future_lock:
if self._metagraph_future is None:
loop = asyncio.get_running_loop()
future = self._metagraph_future = loop.create_future()
set_result = True
else:
future = self._metagraph_future
if set_result:
try:
result = await self._get_metagraph()
except Exception as exc:
future.set_exception(exc)
raise
else:
future.set_result(result)
self._cache_timestamp = dt.datetime.now()
self._cached_metagraph = result
return result
finally:
async with self._future_lock:
self._metagraph_future = None
else:
return await future

def _get_subtensor(self):
return bittensor.subtensor(config=self.config)

@sync_to_async(thread_sensitive=False)
def _get_metagraph(self):
return self._get_subtensor().metagraph(netuid=settings.BITTENSOR_NETUID)

async def periodic_refresh(self, period=None):
if period is None:
period = self.cache_time.total_seconds()
while True:
try:
await self.get_metagraph(ignore_cache=True)
except Exception as exc:
msg = f"Failed to refresh metagraph: {exc}"
logger.warning(msg)

await asyncio.sleep(period)


async_metagraph_client = AsyncMetagraphClient()


async def get_miner_axon_info(hotkey: str) -> bittensor.AxonInfo:
metagraph = await async_metagraph_client.get_metagraph()
neurons = [n for n in metagraph.neurons if n.hotkey == hotkey]
if not neurons:
raise ValueError(f"Miner with {hotkey=} not present in this subnetwork")
return neurons[0].axon_info


def create_metagraph_refresh_task(period=None):
return asyncio.create_task(async_metagraph_client.periodic_refresh(period=period))
import asyncio
import datetime as dt
import logging

import bittensor
from asgiref.sync import sync_to_async

from core.config import settings

logger = logging.getLogger(__name__)


class AsyncMetagraphClient:
def __init__(self, cache_time=dt.timedelta(minutes=5)):
self.cache_time = cache_time
self._metagraph_future = None
self._future_lock = asyncio.Lock()
self._cached_metagraph = None
self._cache_timestamp = None
self.config = settings.get_bittensor_config()

async def get_metagraph(self, ignore_cache=False):
future = None
set_result = False
if self._cached_metagraph is not None:
if not ignore_cache and dt.datetime.now() - self._cache_timestamp < self.cache_time:
return self._cached_metagraph
async with self._future_lock:
if self._metagraph_future is None:
loop = asyncio.get_running_loop()
future = self._metagraph_future = loop.create_future()
set_result = True
else:
future = self._metagraph_future
if set_result:
try:
result = await self._get_metagraph()
except Exception as exc:
future.set_exception(exc)
raise
else:
future.set_result(result)
self._cache_timestamp = dt.datetime.now()
self._cached_metagraph = result
return result
finally:
async with self._future_lock:
self._metagraph_future = None
else:
return await future

@sync_to_async(thread_sensitive=False)
def _get_metagraph(self):
try:
return bittensor.metagraph(
netuid=settings.BITTENSOR_NETUID, network=settings.BITTENSOR_NETWORK
)
except Exception as exc:
logger.error(f"Failed to get metagraph: {exc}", exc_info=True)
raise

async def periodic_refresh(self, period=None):
if period is None:
period = self.cache_time.total_seconds()
while True:
try:
await self.get_metagraph(ignore_cache=True)
except Exception as exc:
msg = f"Failed to refresh metagraph: {exc}"
logger.warning(msg, exc_info=True)

await asyncio.sleep(period)


async_metagraph_client = AsyncMetagraphClient()


async def get_miner_axon_info(hotkey: str) -> bittensor.AxonInfo:
metagraph = await async_metagraph_client.get_metagraph()
neurons = [n for n in metagraph.neurons if n.hotkey == hotkey]
if not neurons:
raise ValueError(f"Miner with {hotkey=} not present in this subnetwork")
return neurons[0].axon_info


def create_metagraph_refresh_task(period=None):
return asyncio.create_task(async_metagraph_client.periodic_refresh(period=period))
2 changes: 1 addition & 1 deletion neurons/validators/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.4.20
3.4.21

0 comments on commit 1a2464e

Please sign in to comment.