mirror of
https://github.com/meshcore-dev/meshcore_py.git
synced 2026-06-14 05:06:53 +00:00
req_neighbours
This commit is contained in:
@@ -163,7 +163,7 @@ class CommandHandlerBase:
|
||||
return Event(EventType.OK, {})
|
||||
|
||||
# attached at base because its a common method
|
||||
async def send_binary_req(self, dst: DestinationType, request_type: BinaryReqType, data: Optional[bytes] = None, timeout=None, min_timeout=0) -> Event:
|
||||
async def send_binary_req(self, dst: DestinationType, request_type: BinaryReqType, data: Optional[bytes] = None, context={}, timeout=None, min_timeout=0) -> Event:
|
||||
dst_bytes = _validate_destination(dst, prefix_length=32)
|
||||
pubkey_prefix = _validate_destination(dst, prefix_length=6)
|
||||
logger.debug(f"Binary request to {dst_bytes.hex()}")
|
||||
@@ -180,6 +180,6 @@ class CommandHandlerBase:
|
||||
# Use provided timeout or fallback to suggested timeout (with 5s default)
|
||||
actual_timeout = timeout if timeout is not None and timeout > 0 else result.payload.get("suggested_timeout", 4000) / 800.0
|
||||
actual_timeout = min_timeout if actual_timeout < min_timeout else actual_timeout
|
||||
self._reader.register_binary_request(pubkey_prefix.hex(), exp_tag, request_type, actual_timeout)
|
||||
self._reader.register_binary_request(pubkey_prefix.hex(), exp_tag, request_type, actual_timeout, context=context)
|
||||
|
||||
return result
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import asyncio
|
||||
import logging
|
||||
import random
|
||||
|
||||
from .base import CommandHandlerBase
|
||||
from ..events import EventType
|
||||
@@ -131,3 +133,112 @@ class BinaryCommandHandler(CommandHandlerBase):
|
||||
)
|
||||
|
||||
return acl_event.payload["acl_data"] if acl_event else None
|
||||
|
||||
async def req_neighbours_async(self,
|
||||
contact,
|
||||
count=255,
|
||||
offset=0,
|
||||
order_by=0,
|
||||
pubkey_prefix_length=4,
|
||||
timeout=0,
|
||||
min_timeout=0
|
||||
):
|
||||
req = (b"\x00" # version : 0
|
||||
+ count.to_bytes(1, "little", signed=False)
|
||||
+ offset.to_bytes(2, "little", signed=False)
|
||||
+ order_by.to_bytes(1, "little", signed=False)
|
||||
+ pubkey_prefix_length.to_bytes(1, "little", signed=False)
|
||||
+ random.randint(1, 0xFFFFFFFF).to_bytes(4, "little", signed=False)
|
||||
)
|
||||
|
||||
logger.debug(f"Sending binary neighbours req, count: {count}, offset: {offset} {req.hex()}")
|
||||
|
||||
return await self.send_binary_req (
|
||||
contact,
|
||||
BinaryReqType.NEIGHBOURS,
|
||||
data=req,
|
||||
timeout=timeout,
|
||||
context={"pubkey_prefix_length": pubkey_prefix_length}
|
||||
)
|
||||
|
||||
async def req_neighbours_sync(self,
|
||||
contact,
|
||||
count=255,
|
||||
offset=0,
|
||||
order_by=0,
|
||||
pubkey_prefix_length=4,
|
||||
timeout=0,
|
||||
min_timeout=0
|
||||
):
|
||||
|
||||
res = await self.req_neighbours_async(contact,
|
||||
count=count,
|
||||
offset=offset,
|
||||
order_by=order_by,
|
||||
pubkey_prefix_length=pubkey_prefix_length,
|
||||
timeout=timeout,
|
||||
min_timeout=min_timeout)
|
||||
|
||||
if res is None or res.type == EventType.ERROR:
|
||||
return None
|
||||
|
||||
timeout = res.payload["suggested_timeout"] / 800 if timeout == 0 else timeout
|
||||
timeout = timeout if min_timeout < timeout else min_timeout
|
||||
|
||||
if self.dispatcher is None:
|
||||
return None
|
||||
|
||||
# Listen for NEIGHBOUR_RESPONSE
|
||||
neighbours_event = await self.dispatcher.wait_for_event(
|
||||
EventType.NEIGHBOURS_RESPONSE,
|
||||
attribute_filters={"tag": res.payload["expected_ack"].hex()},
|
||||
timeout=timeout,
|
||||
)
|
||||
|
||||
return neighbours_event.payload if neighbours_event else None
|
||||
|
||||
# do several queries if not all neighbours have been obtained
|
||||
async def fetch_all_neighbours(self,
|
||||
contact,
|
||||
order_by=0,
|
||||
pubkey_prefix_length=4,
|
||||
timeout=0,
|
||||
min_timeout=0
|
||||
):
|
||||
|
||||
# Initial request
|
||||
res = await self.req_neighbours_sync(contact,
|
||||
count=255,
|
||||
offset=0,
|
||||
order_by=order_by,
|
||||
pubkey_prefix_length=pubkey_prefix_length,
|
||||
timeout=timeout,
|
||||
min_timeout=min_timeout)
|
||||
|
||||
if res is None:
|
||||
return None
|
||||
|
||||
neighbours_count = res["neighbours_count"] # total neighbours
|
||||
results_count = res["results_count"] # obtained neighbours
|
||||
|
||||
del res["tag"]
|
||||
|
||||
while results_count < neighbours_count:
|
||||
#await asyncio.sleep(2) # wait 2s before next fetch
|
||||
next_res = await self.req_neighbours_sync(contact,
|
||||
count=255,
|
||||
offset=results_count,
|
||||
order_by=order_by,
|
||||
pubkey_prefix_length=pubkey_prefix_length,
|
||||
timeout=timeout,
|
||||
min_timeout=min_timeout+5) # requests are close, so let's have some more timeout
|
||||
|
||||
if next_res is None :
|
||||
return res # caller should check it has everything
|
||||
|
||||
results_count = results_count + next_res["results_count"]
|
||||
|
||||
res["results_count"] = results_count
|
||||
res["neighbours"] += next_res["neighbours"]
|
||||
|
||||
return res
|
||||
|
||||
Reference in New Issue
Block a user