{"id":5592,"library":"clandestined","title":"Clandestined Rendezvous Hashing","description":"Clandestined is a Python library that implements rendezvous hashing, also known as highest random weight (HRW) hashing. It provides a distributed algorithm for choosing a node from a set of available nodes, ensuring that a minimal number of mappings change when nodes are added or removed. It's built upon the murmur3 hash function. The current version is 1.1.0, and the project's release cadence has been infrequent since its last update in 2016.","status":"maintenance","version":"1.1.0","language":"en","source_language":"en","source_url":"https://github.com/ewdurbin/clandestined-python","tags":["hashing","consistent hashing","rendezvous hashing","distributed systems","murmur3"],"install":[{"cmd":"pip install clandestined","lang":"bash","label":"Install latest version"}],"dependencies":[],"imports":[{"symbol":"RendezvousHash","correct":"from clandestined import RendezvousHash"},{"symbol":"Cluster","correct":"from clandestined import Cluster"}],"quickstart":{"code":"from clandestined import RendezvousHash\n\n# Initialize with a list of node IDs\nrh = RendezvousHash(['node-a', 'node-b', 'node-c'])\n\n# Find the appropriate node for a given key\nkey_to_hash = 'user_session_123'\nassigned_node = rh.find_node(key_to_hash)\nprint(f\"Key '{key_to_hash}' assigned to: {assigned_node}\")\n\n# Add a new node\nrh.add_node('node-d')\nnew_assigned_node = rh.find_node(key_to_hash)\nprint(f\"After adding node-d, key '{key_to_hash}' assigned to: {new_assigned_node}\")\n\n# Remove a node\nrh.remove_node('node-a')\nfinal_assigned_node = rh.find_node(key_to_hash)\nprint(f\"After removing node-a, key '{key_to_hash}' assigned to: {final_assigned_node}\")","lang":"python","description":"This quickstart demonstrates how to initialize `RendezvousHash` with a set of nodes, find the responsible node for a given key, and dynamically add or remove nodes while maintaining consistent hashing properties."},"warnings":[{"fix":"Update constructor calls to use `seed=` instead of `murmur_seed=`.","message":"The `murmur_seed` keyword argument for `Cluster` and `RendezvousHash` constructors was renamed to `seed`.","severity":"breaking","affected_versions":"<1.0.0b"},{"fix":"Ensure that the node or zone ID exists before attempting to remove it, or wrap calls in a `try...except ValueError` block.","message":"Calling `Cluster.remove_zone`, `Cluster.remove_node`, or `RendezvousHash.remove_node` with a non-existent ID now raises a `ValueError` instead of silently failing.","severity":"breaking","affected_versions":"<1.0.0b"},{"fix":"If custom hashing is required, consider forking the project or implementing rendezvous hashing manually, as the library no longer supports this feature directly.","message":"Support for custom hash functions (passing a callable to `__init__`) was retracted for the 1.0.0 milestone.","severity":"breaking","affected_versions":"<1.0.0b"},{"fix":"Be aware of this deterministic tie-breaking when upgrading from pre-1.0.0rc1 versions, as it might slightly alter node assignments in rare collision scenarios.","message":"Behavior for hash collisions was updated in 1.0.0rc1. In the event of a hash collision between node IDs, the winner is now chosen by `max(str(node_id_1), str(node_id_2))`, providing a deterministic tie-breaking mechanism.","severity":"gotcha","affected_versions":"<1.0.0rc1"},{"fix":"Thoroughly test in your target Python environment. Consider reviewing the source code for C extension compilation issues or Python 2-isms if encountering problems.","message":"The library's `requires_python` field is `UNKNOWN` on PyPI, and its last significant update was in 2016. While some Python 3 compatibility was added in 1.0.1, its compatibility with very modern Python versions (e.g., Python 3.9+) or complex environments might be limited due to the age of the codebase and its C extension (`_murmur3`).","severity":"gotcha","affected_versions":"All versions on newer Python interpreters"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}