Package: consensual
consensualSummaryconsensualis a pure-Python library for defining network of nodes
running in a consistent fault-tolerant manner by implementing state-of-the-artRaftconsensus algorithm.Currently, next features are implemented & property-based testedleader election & log replication
(described in section 5 ofthe article),cluster membership changes
(described in section 6 ofthe article),
namely consensual addition & removal of nodes,"solo mode": non-consensual separation of a node
resulting in running as a cluster-by-itself,separate node state resetting with history deletion.Next crucial features to implement will bepersistence,log compaction
(described in section 7 ofthe article).In what followspythonis an alias forpython3.7or any later version (python3.8and so on).InstallationInstall the latestpip&setuptoolspackages versionspython-mpipinstall--upgradepipsetuptoolsUserDownload and install the latest stable version fromPyPIrepositorypython-mpipinstall--upgradeconsensualDeveloperDownload the latest version fromGitHubrepositorygitclonehttps://github.com/lycantropos/consensual.gitcdconsensualInstall dependenciespython-mpipinstall-rrequirements.txtInstallpythonsetup.pyinstallUsage>>>fromconsensual.raftimportNode,communication>>>fromyarlimportURL>>>node_url=URL.build(scheme='http',...host='localhost',...port=6000)>>>other_node_url=URL.build(scheme='http',...host='localhost',...port=6001)>>>heartbeat=0.1>>>fromtypingimportAny,List,Optional>>>processed_parameters=[]>>>defdummy_processor(parameters:Any)->None:...processed_parameters.append(parameters)>>>processors={'dummy':dummy_processor}>>>nodes={}>>>sender=communication.Sender([node_url],nodes)>>>other_sender=communication.Sender([other_node_url],nodes)>>>node=Node.from_url(node_url,...heartbeat=heartbeat,...processors=processors,...sender=sender)>>>other_node=Node.from_url(other_node_url,...heartbeat=heartbeat,...processors=processors,...sender=other_sender)>>>receiver=communication.Receiver(node,nodes)>>>other_receiver=communication.Receiver(other_node,nodes)>>>receiver.start()>>>other_receiver.start()>>>fromasyncioimportget_event_loop>>>loop=get_event_loop()>>>asyncdefrun()->List[Optional[str]]:...return[awaitnode.solo(),...awaitnode.enqueue('dummy',42),...awaitnode.attach_nodes([other_node.url]),...awaitnode.enqueue('dummy',42),...awaitother_node.detach_nodes([node.url]),...awaitother_node.solo(),...awaitother_node.detach(),...awaitother_node.detach()]>>>error_messages=loop.run_until_complete(run())>>>receiver.stop()>>>other_receiver.stop()>>>all(error_messageisNoneorisinstance(error_message,str)...forerror_messageinerror_messages)True>>>all(parameters==42forparametersinprocessed_parameters)TrueWe can also replace builtinconsensual.raft.communicationcommunication layer
with another one (likeconsensual_httpwhich is built on top of HTTP), usage patterns may change as a result.DevelopmentBumping versionPreparationInstallbump2version.Pre-releaseChoose which version number category to bump followingsemver
specification.Test bumping versionbump2version--dry-run--verbose$CATEGORYwhere$CATEGORYis the target version number category name, possible
values arepatch/minor/major.Bump versionbump2version--verbose$CATEGORYThis will set version tomajor.minor.patch-alpha.ReleaseTest bumping versionbump2version--dry-run--verbosereleaseBump versionbump2version--verbosereleaseThis will set version tomajor.minor.patch.Running testsInstall dependenciespython-mpipinstall-rrequirements-tests.txtPlainpytestInsideDockercontainer:docker-compose--filedocker-compose.ymlupBashscript:./run-tests.shPowerShellscript:.\run-tests.ps1