diff --git a/pyproject.toml b/pyproject.toml index 201f416..5c15fbf 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -61,7 +61,9 @@ classifiers = [ ] requires-python = ">=3.10" -dependencies = [] +dependencies = [ + "loguru>=0.7.3", +] [build-system] requires = ["uv_build>=0.7.19,<0.8"] diff --git a/src/chordnet/net.py b/src/chordnet/net.py index 8e2f1a1..18af16c 100644 --- a/src/chordnet/net.py +++ b/src/chordnet/net.py @@ -4,6 +4,8 @@ import threading from typing import Callable, Tuple +from loguru import logger as log + from .address import Address callback = Callable[[str, list[str]], str| Address | None] @@ -86,7 +88,7 @@ def send_request( request_args = ':'.join(str(arg) for arg in args) request = f"{method}:{request_args}" if (method == "TRACE_SUCCESSOR"): - print ('[SENDING TRACE REQ]', request) + log.debug("[SENDING TRACE REQ]", request) # Send the request sock.send(request.encode()) @@ -96,13 +98,13 @@ def send_request( return response except socket.timeout: - print("Request timed out", file=sys.stderr) + log.info("Request timed out") return None except ConnectionRefusedError: - print("Connection refused", file=sys.stderr) + log.info("Connection refused") return None except Exception as e: - print(f"Network request error: {e}", file=sys.stderr) + log.info(f"Network request error: {e}") return None @@ -129,7 +131,7 @@ def _listen_for_connections(self) -> None: ).start() except Exception as e: if self._running: - print(f"Error accepting connection: {e}\n") + log.info(f"Error accepting connection: {e}\n") sys.stderr.write(f"Error accepting connection: {e}\n") sys.stderr.flush() @@ -149,13 +151,13 @@ def _handle_connection(self, client_socket: socket.socket) -> None: method, *args = request.split(':') if method == 'TRACE_SUCCESSOR': - print(f"[NET]Received request: {request}", file=sys.stderr) + log.debug(f"[NET]Received request: {request}") # Dispatch to appropriate method response = self._request_handler(method, args) if method == 'TRACE_SUCCESSOR': - print(f"[NET]Sent response: {response}", file=sys.stderr) + log.debug(f"[NET]Sent response: {response}") # Send response client_socket.send(str(response).encode()) diff --git a/src/chordnet/node.py b/src/chordnet/node.py index 9ff889c..27d9b4c 100644 --- a/src/chordnet/node.py +++ b/src/chordnet/node.py @@ -1,7 +1,8 @@ """node.py: Represents a node on a ring.""" -import sys from typing import Callable, Tuple +from loguru import logger as log + from .address import Address from .net import _Net @@ -95,7 +96,7 @@ def join(self, known_ip: str, known_port: int) -> None: self.finger_table[0] = self._parse_address(response) msg = f"Node {self.address.key} joined the ring. " \ "Successor: {self.successor().key}" - print(msg, file=sys.stderr) + log.info(msg) else: raise ValueError("Failed to find successor. Join failed") @@ -104,7 +105,7 @@ def join(self, known_ip: str, known_port: int) -> None: except Exception as e: - print(f"Join failed: {e}") + log.info(f"Join failed: {e}") raise @@ -118,7 +119,7 @@ def fix_fingers(self) -> None: gap = (2 ** self._next) % (2 ** Address._M) start = self.address.key + gap - #print(f"fixing finger {self._next}. gap is {gap}, " \ + #log.info(f"fixing finger {self._next}. gap is {gap}, " \ #"start of interval is: {start}") try: @@ -126,7 +127,7 @@ def fix_fingers(self) -> None: responsible_node = self.find_successor(start) self.finger_table[self._next] = responsible_node except Exception as e: - print(f"fix_fingers failed for finger {self._next}: {e}") + log.debug(f"fix_fingers failed for finger {self._next}: {e}") # Move to the next finger table entry, wrapping around if necessary self._next = (self._next + 1) % Address._M @@ -153,7 +154,7 @@ def start_periodic_tasks(self, interval=1.0): """ if self._fix_fingers_timer and self._fix_fingers_timer.is_alive(): # Timer is already running, no need to start again - print("Periodic tasks are already running.", file=sys.stderr) + log.info("Periodic tasks are already running.") return self.is_running = True self._run_fix_fingers(interval) @@ -173,7 +174,7 @@ def log_finger_table(self) -> None: for i, finger in enumerate(self.finger_table): message += f" Finger[{i}] -> {finger}\n" - print(message, file=sys.stderr) + log.info(message) def find_successor(self, id: int) -> Address: """Finds the successor node for a given identifier. @@ -210,7 +211,7 @@ def find_successor(self, id: int) -> Address: return successor if successor else self.address except Exception as e: - print(f"Find successor failed: {e}") + log.info(f"Find successor failed: {e}") # Fallback to local successor if network request fails return curr_successor if curr_successor else self.address @@ -278,12 +279,12 @@ def stabilize(self) -> None: try: # Get the predecessor of the current successor - #print(f"stabilize: checking successor {self.successor().key}" \ - #for predecessor", file=sys.stderr) + #log.info(f"stabilize: checking successor {self.successor().key}" \ + #for predecessor") x_response = self._net.send_request( curr_successor, 'GET_PREDECESSOR') - #print(f"stabilize: predecessor found: {x_response}", + #log.info(f"stabilize: predecessor found: {x_response}", #file=sys.stderr) x = self._parse_address(x_response) @@ -291,18 +292,18 @@ def stabilize(self) -> None: self.address.key, curr_successor.key, x.key ): self.finger_table[0] = x - #print( + #log.info( #f"stabilize: updated successor to {self.successor().key}", #file=sys.stderr) # otherwise, we just notify them that we exist. # This is usually for the first joiner to a ring. - #print(f"Node {self.address} - Updated Successor:" \ + #log.info(f"Node {self.address} - Updated Successor:" \ #"{self.successor()}, Predecessor: {self.predecessor}", #file=sys.stderr) except Exception as e: - print(f"Stabilize failed: {e}", file=sys.stderr) + log.info(f"Stabilize failed: {e}") finally: self.notify(self.successor()) @@ -332,7 +333,7 @@ def notify(self, potential_successor: Address | None)-> bool: else: return False except Exception as e: - print(f"Notify failed: {e}", file=sys.stderr) + log.info(f"Notify failed: {e}") return False @@ -449,7 +450,7 @@ def trace_successor( id, curr_hops ) - print(f"Raw response: {response}", file=sys.stderr) # Debugging line + log.debug(f"Raw response: {response}") # Debugging line assert response is not None parts = response.split(":") if len(parts) != 4: @@ -459,14 +460,14 @@ def trace_successor( # resolved_node.key = int(node_key) response_split = response.split(":") address = ':'.join(response_split[:-1]) - print ("[trace]Joined Address :", address) + log.info("[trace]Joined Address :", address) # address = '':'.join(response[:2]) return address, int(hops)+1 # return self._parse_address(response), hops except Exception as e: - print(f"trace successor failed: {e}") + log.info(f"trace successor failed: {e}") # Fallback to local successor if network request fails return str(self.successor()), -1 @@ -490,14 +491,14 @@ def _process_request( elif method == "TRACE_SUCCESSOR": try: id, hops = int(args[0]), int(args[1]) - print ("[NODE] Current ID ", id, "Current hops ", hops) + log.info("[NODE] Current ID ", id, "Current hops ", hops) successor, hops = self.trace_successor(id, hops) - print ("SUCCESSSOR NODE :", successor, "HOPS :", hops) + log.info("SUCCESSSOR NODE :", successor, "HOPS :", hops) returnString = f"{successor}:{hops}" return returnString except Exception as e: - print(f"TRACE_SUCCESSOR error: {e}", file=sys.stderr) + log.info(f"TRACE_SUCCESSOR error: {e}") return "ERROR:Invalid TRACE_SUCCESSOR Request" elif method == 'GET_PREDECESSOR': diff --git a/uv.lock b/uv.lock index 10c5eb3..395d9b3 100644 --- a/uv.lock +++ b/uv.lock @@ -128,6 +128,9 @@ wheels = [ name = "chordnet" version = "1.0.0" source = { editable = "." } +dependencies = [ + { name = "loguru" }, +] [package.dev-dependencies] dev = [ @@ -141,6 +144,7 @@ dev = [ ] [package.metadata] +requires-dist = [{ name = "loguru", specifier = ">=0.7.3" }] [package.metadata.requires-dev] dev = [ @@ -447,6 +451,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/27/e3/0e0014d6ab159d48189e92044ace13b1e1fe9aa3024ba9f4e8cf172aa7c2/jinxed-1.3.0-py2.py3-none-any.whl", hash = "sha256:b993189f39dc2d7504d802152671535b06d380b26d78070559551cbf92df4fc5", size = 33085, upload-time = "2024-07-31T22:39:17.426Z" }, ] +[[package]] +name = "loguru" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "win32-setctime", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3a/05/a1dae3dffd1116099471c643b8924f5aa6524411dc6c63fdae648c4f1aca/loguru-0.7.3.tar.gz", hash = "sha256:19480589e77d47b8d85b2c827ad95d49bf31b0dcde16593892eb51dd18706eb6", size = 63559, upload-time = "2024-12-06T11:20:56.608Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/29/0348de65b8cc732daa3e33e67806420b2ae89bdce2b04af740289c5c6c8c/loguru-0.7.3-py3-none-any.whl", hash = "sha256:31a33c10c8e1e10422bfd431aeb5d351c7cf7fa671e3c4df004162264b28220c", size = 61595, upload-time = "2024-12-06T11:20:54.538Z" }, +] + [[package]] name = "markupsafe" version = "3.0.3" @@ -875,3 +892,12 @@ sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc wheels = [ { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166, upload-time = "2024-01-06T02:10:55.763Z" }, ] + +[[package]] +name = "win32-setctime" +version = "1.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b663af0e9bb3d4de6578d08f46b1b101c2442fd9aecaa2/win32_setctime-1.2.0.tar.gz", hash = "sha256:ae1fdf948f5640aae05c511ade119313fb6a30d7eabe25fef9764dca5873c4c0", size = 4867, upload-time = "2024-12-07T15:28:28.314Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, +]