better error handling
This commit is contained in:
@@ -0,0 +1,350 @@
|
||||
from typing import Self, Optional
|
||||
from enum import StrEnum
|
||||
|
||||
from .types import *
|
||||
from .config import *
|
||||
|
||||
class AttachmentState(StrEnum):
|
||||
DETACHED = 'Detached'
|
||||
ATTACHING = 'Attaching'
|
||||
ATTACHED_WEAK = 'AttachedWeak'
|
||||
ATTACHED_GOOD = 'AttachedGood'
|
||||
ATTACHED_STRONG = 'AttachedStrong'
|
||||
FULLY_ATTACHED = 'FullyAttached'
|
||||
OVER_ATTACHED = 'OverAttached'
|
||||
DETACHING = 'Detaching'
|
||||
|
||||
class VeilidStateAttachment:
|
||||
state: AttachmentState
|
||||
public_internet_ready: bool
|
||||
local_network_ready: bool
|
||||
|
||||
def __init__(self, state: AttachmentState, public_internet_ready: bool, local_network_ready: bool):
|
||||
self.state = state
|
||||
self.public_internet_ready = public_internet_ready
|
||||
self.local_network_ready = local_network_ready
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidStateAttachment(
|
||||
AttachmentState(j['state']),
|
||||
j['public_internet_ready'],
|
||||
j['local_network_ready'])
|
||||
|
||||
class RPCStats:
|
||||
messages_sent: int
|
||||
messages_rcvd: int
|
||||
questions_in_flight: int
|
||||
last_question_ts: Optional[Timestamp]
|
||||
last_seen_ts: Optional[Timestamp]
|
||||
first_consecutive_seen_ts: Optional[Timestamp]
|
||||
recent_lost_answers: int
|
||||
failed_to_send: int
|
||||
|
||||
def __init__(self, messages_sent: int, messages_rcvd: int, questions_in_flight: int,
|
||||
last_question_ts: Optional[Timestamp], last_seen_ts: Optional[Timestamp],
|
||||
first_consecutive_seen_ts: Optional[Timestamp], recent_lost_answers: int, failed_to_send: int):
|
||||
self.messages_sent = messages_sent
|
||||
self.messages_rcvd = messages_rcvd
|
||||
self.questions_in_flight = questions_in_flight
|
||||
self.last_question_ts = last_question_ts
|
||||
self.last_seen_ts = last_seen_ts
|
||||
self.first_consecutive_seen_ts = first_consecutive_seen_ts
|
||||
self.recent_lost_answers = recent_lost_answers
|
||||
self.failed_to_send = failed_to_send
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return RPCStats(
|
||||
j['messages_sent'],
|
||||
j['messages_rcvd'],
|
||||
j['questions_in_flight'],
|
||||
None if j['last_question_ts'] is None else Timestamp(j['last_question_ts']),
|
||||
None if j['last_seen_ts'] is None else Timestamp(j['last_seen_ts']),
|
||||
None if j['first_consecutive_seen_ts'] is None else Timestamp(j['first_consecutive_seen_ts']),
|
||||
j['recent_lost_answers'],
|
||||
j['failed_to_send'])
|
||||
|
||||
class LatencyStats:
|
||||
fastest: TimestampDuration
|
||||
average: TimestampDuration
|
||||
slowest: TimestampDuration
|
||||
|
||||
def __init__(self, fastest: TimestampDuration, average: TimestampDuration, slowest: TimestampDuration):
|
||||
self.fastest = fastest
|
||||
self.average = average
|
||||
self.slowest = slowest
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return LatencyStats(
|
||||
TimestampDuration(j['fastest']),
|
||||
TimestampDuration(j['average']),
|
||||
TimestampDuration(j['slowest']))
|
||||
|
||||
|
||||
class TransferStats:
|
||||
total: ByteCount
|
||||
maximum: ByteCount
|
||||
average: ByteCount
|
||||
minimum: ByteCount
|
||||
|
||||
def __init__(self, total: ByteCount, maximum: ByteCount, average: ByteCount, minimum: ByteCount):
|
||||
self.total = total
|
||||
self.maximum = maximum
|
||||
self.average = average
|
||||
self.minimum = minimum
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return TransferStats(
|
||||
ByteCount(j['total']),
|
||||
ByteCount(j['maximum']),
|
||||
ByteCount(j['average']),
|
||||
ByteCount(j['minimum']))
|
||||
|
||||
|
||||
class TransferStatsDownUp:
|
||||
down: TransferStats
|
||||
up: TransferStats
|
||||
|
||||
def __init__(self, down: TransferStats, up: TransferStats):
|
||||
self.down = down
|
||||
self.up = up
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return TransferStatsDownUp(
|
||||
TransferStats.from_json(j['down']),
|
||||
TransferStats.from_json(j['up']))
|
||||
|
||||
class PeerStats:
|
||||
time_added: Timestamp
|
||||
rpc_stats: RPCStats
|
||||
latency: Optional[LatencyStats]
|
||||
transfer: TransferStatsDownUp
|
||||
|
||||
def __init__(self, time_added: Timestamp, rpc_stats: RPCStats, latency: Optional[LatencyStats], transfer: TransferStatsDownUp):
|
||||
self.time_added = time_added
|
||||
self.rpc_stats = rpc_stats
|
||||
self.latency = latency
|
||||
self.transfer = transfer
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return PeerStats(
|
||||
j['time_added'],
|
||||
RPCStats.from_json(j['rpc_stats']),
|
||||
None if j['latency'] is None else LatencyStats.from_json(j['latency']),
|
||||
TransferStatsDownUp.from_json(j['transfer']))
|
||||
|
||||
class PeerTableData:
|
||||
node_ids: list[str]
|
||||
peer_address: str
|
||||
peer_stats: PeerStats
|
||||
|
||||
def __init__(self, node_ids: list[str], peer_address: str, peer_stats: PeerStats):
|
||||
self.node_ids = node_ids
|
||||
self.peer_address = peer_address
|
||||
self.peer_stats = peer_stats
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return PeerTableData(
|
||||
j['node_ids'],
|
||||
j['peer_address'],
|
||||
PeerStats.from_json(j['peer_stats']))
|
||||
|
||||
class VeilidStateNetwork:
|
||||
started: bool
|
||||
bps_down: ByteCount
|
||||
bps_up: ByteCount
|
||||
peers: list[PeerTableData]
|
||||
|
||||
def __init__(self, started: bool, bps_down: ByteCount, bps_up: ByteCount, peers: list[PeerTableData]):
|
||||
self.started = started
|
||||
self.bps_down = bps_down
|
||||
self.bps_up = bps_up
|
||||
self.peers = peers
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidStateNetwork(
|
||||
j['started'],
|
||||
ByteCount(j['bps_down']),
|
||||
ByteCount(j['bps_up']),
|
||||
list(map(lambda x: PeerTableData.from_json(x), j['peers'])))
|
||||
|
||||
class VeilidStateConfig:
|
||||
config: VeilidConfig
|
||||
|
||||
def __init__(self, config: VeilidConfig):
|
||||
self.config = config
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidStateConfig(
|
||||
VeilidConfig.from_json(j['config'])
|
||||
)
|
||||
|
||||
class VeilidState:
|
||||
attachment: VeilidStateAttachment
|
||||
network: VeilidStateNetwork
|
||||
config: VeilidStateConfig
|
||||
|
||||
def __init__(self, attachment: VeilidStateAttachment, network: VeilidStateNetwork, config: VeilidStateConfig):
|
||||
self.attachment = attachment
|
||||
self.network = network
|
||||
self.config = config
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidState(
|
||||
VeilidStateAttachment.from_json(j['attachment']),
|
||||
VeilidStateNetwork.from_json(j['network']),
|
||||
VeilidStateConfig.from_json(j['config']))
|
||||
|
||||
class VeilidLog:
|
||||
log_level: VeilidLogLevel
|
||||
message: str
|
||||
backtrace: Optional[str]
|
||||
|
||||
def __init__(self, log_level: VeilidLogLevel, message: str, backtrace: Optional[str]):
|
||||
self.log_level = log_level
|
||||
self.message = message
|
||||
self.backtrace = backtrace
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidLog(
|
||||
VeilidLogLevel(j['log_level']),
|
||||
j['message'],
|
||||
j['backtrace'])
|
||||
|
||||
class VeilidAppMessage:
|
||||
sender: Optional[TypedKey]
|
||||
message: bytes
|
||||
|
||||
def __init__(self, sender: Optional[TypedKey], message: bytes):
|
||||
self.sender = sender
|
||||
self.message = message
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidAppMessage(
|
||||
None if j['sender'] is None else TypedKey(j['sender']),
|
||||
urlsafe_b64decode_no_pad(j['message']))
|
||||
|
||||
class VeilidAppCall:
|
||||
sender: Optional[TypedKey]
|
||||
message: bytes
|
||||
operation_id: str
|
||||
|
||||
def __init__(self, sender: Optional[TypedKey], message: bytes, operation_id: str):
|
||||
self.sender = sender
|
||||
self.message = message
|
||||
self.operation_id = operation_id
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidAppCall(
|
||||
None if j['sender'] is None else TypedKey(j['sender']),
|
||||
urlsafe_b64decode_no_pad(j['message']),
|
||||
j['operation_id'])
|
||||
|
||||
class VeilidRouteChange:
|
||||
dead_routes: list[RouteId]
|
||||
dead_remote_routes: list[RouteId]
|
||||
|
||||
def __init__(self, dead_routes: list[RouteId], dead_remote_routes: list[RouteId]):
|
||||
self.dead_routes = dead_routes
|
||||
self.dead_remote_routes = dead_remote_routes
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidRouteChange(
|
||||
list(map(lambda x: RouteId(x), j['dead_routes'])),
|
||||
list(map(lambda x: RouteId(x), j['dead_remote_routes'])))
|
||||
|
||||
class VeilidValueChange:
|
||||
key: TypedKey
|
||||
subkeys: list[ValueSubkey]
|
||||
count: int
|
||||
value: ValueData
|
||||
|
||||
def __init__(self, key: TypedKey, subkeys: list[ValueSubkey], count: int, value: ValueData):
|
||||
self.key = key
|
||||
self.subkeys = subkeys
|
||||
self.count = count
|
||||
self.value = value
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
return VeilidValueChange(
|
||||
TypedKey(j['key']),
|
||||
list(map(lambda x: ValueSubkey(x), j['subkeys'])),
|
||||
j['count'],
|
||||
ValueData.from_json(j['value']))
|
||||
|
||||
|
||||
class VeilidUpdateKind(StrEnum):
|
||||
LOG = "Log"
|
||||
APP_MESSAGE = "AppMessage"
|
||||
APP_CALL = "AppCall"
|
||||
ATTACHMENT = "Attachment"
|
||||
NETWORK = "Network"
|
||||
CONFIG = "Config"
|
||||
ROUTE_CHANGE = "RouteChange"
|
||||
VALUE_CHANGE = "ValueChange"
|
||||
SHUTDOWN = "Shutdown"
|
||||
|
||||
class VeilidUpdate:
|
||||
kind: VeilidUpdateKind
|
||||
detail: Optional[VeilidLog | VeilidAppMessage | VeilidAppCall | VeilidStateAttachment | VeilidStateNetwork | VeilidStateConfig | VeilidRouteChange | VeilidValueChange]
|
||||
|
||||
def __init__(self, kind: VeilidUpdateKind, detail: Optional[VeilidLog | VeilidAppMessage | VeilidAppCall | VeilidStateAttachment | VeilidStateNetwork | VeilidStateConfig | VeilidRouteChange | VeilidValueChange]):
|
||||
self.kind = kind
|
||||
self.detail = detail
|
||||
|
||||
@staticmethod
|
||||
def from_json(j: dict) -> Self:
|
||||
'''JSON object hook'''
|
||||
kind = VeilidUpdateKind(j['kind'])
|
||||
detail = None
|
||||
match kind:
|
||||
case VeilidUpdateKind.LOG:
|
||||
detail = VeilidLog.from_json(j)
|
||||
case VeilidUpdateKind.APP_MESSAGE:
|
||||
detail = VeilidAppMessage.from_json(j)
|
||||
case VeilidUpdateKind.APP_CALL:
|
||||
detail = VeilidAppCall.from_json(j)
|
||||
case VeilidUpdateKind.ATTACHMENT:
|
||||
detail = VeilidStateAttachment.from_json(j)
|
||||
case VeilidUpdateKind.NETWORK:
|
||||
detail = VeilidStateNetwork.from_json(j)
|
||||
case VeilidUpdateKind.CONFIG:
|
||||
detail = VeilidStateConfig.from_json(j)
|
||||
case VeilidUpdateKind.ROUTE_CHANGE:
|
||||
detail = VeilidRouteChange.from_json(j)
|
||||
case VeilidUpdateKind.VALUE_CHANGE:
|
||||
detail = VeilidValueChange.from_json(j)
|
||||
case VeilidUpdateKind.SHUTDOWN:
|
||||
detail = None
|
||||
case _:
|
||||
raise ValueError("Unknown VeilidUpdateKind")
|
||||
return VeilidUpdate(kind, detail)
|
||||
Reference in New Issue
Block a user