Files
colony/colony/core/network/core.py
T
2026-03-22 20:29:19 +01:00

92 lines
3.0 KiB
Python

import json
from enum import Enum
from typing import Optional
from colony.core.network.nodes import LocalNode, Node
from colony.core.network.requests import CommandRequest
from colony.core.logger.logging import get_logger
from colony.settings import configuration
from colony.transport.whisperer import Whisperer
from colony.utils.network import get_local_ip, get_hostname
class Network:
def __init__(self):
self.logger = get_logger(self.__class__.__name__)
self.self_node = LocalNode(
hostname=get_hostname(),
ip=get_local_ip(),
roles=[],
port=configuration.listener.port
)
self.logger.info(f"Self node created: {self.self_node.id}")
self.nodes = self.load_network_from_snapshot()
if not self.nodes:
self.nodes.append(self.self_node)
def get_self(self):
return self.self_node
def get_all_nodes(self):
return self.nodes
def get_node_of_role(self, role_name: str) -> Optional[Node]:
for node in self.nodes:
for role in node.roles:
if role == role_name:
return node
self.logger.warning(f"No node found with role: {role_name}")
return None
def execute(self, command: Enum, *args, **kwargs):
request = CommandRequest.form(command, *args, **kwargs)
self.logger.info(f"Executing command {request.id} on role {request.role}")
node = self.get_node_of_role(request.role)
if node is None:
raise ValueError(f"No node found with role {request.role}")
result = node.execute(command, *args, **kwargs)
self.logger.debug(f"Command {request.id} executed")
return result
@staticmethod
def execute_to_unregistered_node(ip, port, command: Enum, *args, **kwargs):
request = CommandRequest.form(command, *args, **kwargs)
return Whisperer(ip, port).send(request.collapse())
def load_network_from_snapshot(self, file_path: str = "storage/colony_snapshot.json"):
self.logger.info(f"Loading network snapshot from {file_path}")
nodes = []
try:
with open(file_path, "r", encoding="utf-8") as f:
snapshot = json.load(f)
except FileNotFoundError:
self.logger.warning(f"Snapshot file {file_path} not found. Starting with empty network")
snapshot = {"nodes": []}
for node_ip, node_data in snapshot.items():
result = node_data.get('result')
if not isinstance(result, dict):
self.logger.warning(f"Skipping node {node_ip}: result is not a dict")
continue
node = Node(
hostname=result["hostname"],
ip=result["ip"],
port=result["port"],
roles=result.get("roles", [])
)
self.logger.info(f"Loaded node from snapshot: {node.id}")
nodes.append(node)
return nodes