diff --git a/pyproject.toml b/pyproject.toml index 81e45d2..a29066e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -115,9 +115,13 @@ convention = "google" python_version = "3.10" warn_return_any = true warn_unused_configs = true -files = ["src", "tests"] +files = ["src", "tests", "scripts"] exclude = [ '(^|.*/)__pycache__/', # matches __pycache__ at any depth '(^|.*/).ruff_cache/', '(^|.*/).mypy_cache/', ] + +[[tool.mypy.overrides]] +module = ["bpython"] +ignore_missing_imports = true diff --git a/scripts/auto/__init__.py b/scripts/auto/__init__.py new file mode 100644 index 0000000..e2fcbee --- /dev/null +++ b/scripts/auto/__init__.py @@ -0,0 +1 @@ +"""__init__.py: nothing to see here...""" diff --git a/scripts/auto/anchor.py b/scripts/auto/anchor.py new file mode 100644 index 0000000..e4b21d6 --- /dev/null +++ b/scripts/auto/anchor.py @@ -0,0 +1 @@ +"""anchor.py: creates and starts an anchor node for testing.""" diff --git a/scripts/auto/joiner.py b/scripts/auto/joiner.py new file mode 100644 index 0000000..da61010 --- /dev/null +++ b/scripts/auto/joiner.py @@ -0,0 +1 @@ +"""joiner.py: creates a joining node for debugging.""" diff --git a/scripts/manual/__init__.py b/scripts/manual/__init__.py new file mode 100644 index 0000000..e2fcbee --- /dev/null +++ b/scripts/manual/__init__.py @@ -0,0 +1 @@ +"""__init__.py: nothing to see here...""" diff --git a/scripts/manual/anchor.py b/scripts/manual/anchor.py new file mode 100644 index 0000000..e22a25a --- /dev/null +++ b/scripts/manual/anchor.py @@ -0,0 +1,33 @@ +"""anchor.py: creates and starts an anchor node for testing.""" +import sys + +import bpython +from step import step #type: ignore + +from chordnet import Node as ChordNode + + +def main() -> None: + """Creates a new ring with this computer as the only node.""" + if len(sys.argv) != 3: + print("usage: [uv run] python anchor.py ip_addr port_no") + exit(1) + + ip = sys.argv[1] + port = int(sys.argv[2]) + + node = ChordNode(ip, port) + # create (start) the ring + node.create() + print(f"Node created as \"node\": {node.address}", file=sys.stderr) + repl_locals = { + 'node': node, + 'step': step, + } + print("starting repl. access `node`, advance with `step(node)`") + bpython.embed(locals_=repl_locals) + node.stop() + + +if __name__ == '__main__': + main() diff --git a/scripts/manual/joiner.py b/scripts/manual/joiner.py new file mode 100644 index 0000000..037f9cb --- /dev/null +++ b/scripts/manual/joiner.py @@ -0,0 +1,36 @@ +"""joiner.py: creates a joining node for debugging.""" +import sys + +import bpython +from step import step #type: ignore + +from chordnet import Node as ChordNode + + +def main() -> None: + """Creates a new ring with this computer as the only node.""" + if len(sys.argv) != 5: + print("usage: [uv run] python " \ + "joiner.py this_ip this_port target_ip target_port") + exit(1) + + # Get IP and port from command line arguments + ip = sys.argv[1] + port = int(sys.argv[2]) + target_ip = sys.argv[3] + target_port = int(sys.argv[4]) + + # Create and join node + node = ChordNode(ip, port) + node.join(target_ip, target_port) + repl_locals = { + 'node': node, + 'step': step, + } + print("starting repl. access `node`, advance with `step(node)`") + bpython.embed(locals_=repl_locals) + node.stop() + + +if __name__ == '__main__': + main() diff --git a/scripts/manual/step.py b/scripts/manual/step.py new file mode 100644 index 0000000..f716674 --- /dev/null +++ b/scripts/manual/step.py @@ -0,0 +1,12 @@ +"""step.py: helper for manual scripts.""" + +from chordnet import Node as ChordNode + + +def step(node: ChordNode) -> None: + """Runs the periodic tasks for the node once.""" + node.stabilize() + node.fix_fingers() + + print(f"pred: {node.predecessor} succ: {node.successor()}") + print(node.finger_table) diff --git a/src/chordnet/address.py b/src/chordnet/address.py index 7540daf..a6d642e 100644 --- a/src/chordnet/address.py +++ b/src/chordnet/address.py @@ -58,6 +58,7 @@ def __eq__(self, other: object) -> bool: """ if not isinstance(other, Address): return NotImplemented + return (self.ip == other.ip and self.port == other.port and self.key == other.key)