{ "info": { "author": "Deniz Altinbuken, Emin Gun Sirer", "author_email": "deniz@systems.cs.cornell.edu, egs@systems.cs.cornell.edu", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta" ], "description": ".. -*-restructuredtext-*-\r\n\r\n========\r\nConCoord\r\n========\r\n\r\nOverview\r\n========\r\n\r\nConCoord is a novel coordination service that provides replication and\r\nsynchronization support for large-scale distributed systems. ConCoord\r\nemploys an object-oriented approach, in which the system creates\r\nand maintains live replicas for Python objects written by the user.\r\nConCoord converts these Python objects into Paxos Replicated State\r\nMachines (RSM) and enables clients to do method invocations on them\r\ntransparently as if they are local objects. ConCoord uses these\r\nreplicated objects to implement coordination and synchronization\r\nconstructs in large-scale distributed systems, in effect establishing\r\na transparent way of providing a coordination service.\r\n\r\n:Authors:\r\n - Deniz Altinbuken (deniz@systems.cs.cornell.edu)\r\n - Emin Gun Sirer (egs@systems.cs.cornell.edu)\r\n:Version: 1.1.0\r\n:Date: 2014-04-03\r\n\r\nRequirements\r\n============\r\n\r\nThe minimum requirements for ConCoord are::\r\n\r\n - python 2.7.2 or later\r\n - dnspython-1.9.4\r\n - msgpack-python\r\n\r\nInstallation\r\n============\r\n\r\nConCoord can be installed from source with::\r\n\r\n $ python setup.py install\r\n\r\nConCoord is also available for install through PyPI::\r\n\r\n $ pip install concoord\r\n\r\nTutorial\r\n========\r\n\r\nGetting Started\r\n---------------\r\n\r\nTo use ConCoord you need a Python object that can be used for the\r\ncoordination of your distributed system. In the ConCoord distribution,\r\nwe offer ready-to-use objects that cover the most common coordination\r\nneeds. So first, let's start a ConCoord instance with an object in\r\nthe distribution, namely Counter under concoord/object/counter.py.\r\n\r\nStarting Nodes\r\n--------------\r\n\r\nTo distribute the local object you should start at least one replica.\r\n\r\nStarting Replicas\r\n~~~~~~~~~~~~~~~~~\r\n\r\nTo start a bootstrap replica node that doesn't need to be connected to\r\nanother replica, use the following command::\r\n\r\n $ concoord replica -o concoord.object.counter.Counter -a 127.0.0.1 -p 14000\r\n\r\nTo start replica nodes to join an active ConCoord instance, use the\r\nfollowing command to connect to another replica::\r\n\r\n $ concoord replica -o concoord.object.counter.Counter -b 127.0.0.1:14000 -a 127.0.0.1 -p 14001\r\n\r\nYou can specify the port and the address of any replica with options -p and -a\r\nrespectively. The replicas can also be run in the debug mode or with a logger\r\nwith the commands shown below::\r\n\r\n Usage: concoord replica [-h] [-a ADDR] [-p PORT] [-b BOOTSTRAP]\r\n \t \t [-o OBJECTNAME] [-l LOGGER] [-n DOMAIN]\r\n\t\t\t [-r] [-w] [-d]\r\n\r\nwhere,\r\n -h, --help show this help message and exit\r\n -a ADDR, --addr ADDR address for the node\r\n -p PORT, --port PORT port for the node\r\n -b BOOTSTRAP, --boot BOOTSTRAP\r\n address:port tuple for the bootstrap peer\r\n -o OBJECTNAME, --objectname OBJECTNAME\r\n client object dotted name\r\n -l LOGGER, --logger LOGGER\r\n logger address\r\n -n DOMAIN, --domainname DOMAIN\r\n domain name that the name server will accept queries for\r\n -r, --route53 use Route53\r\n -w, --writetodisk writing to disk on/off\r\n -d, --debug debug on/off\r\n\r\nStarting Replicas as Name Servers\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nYou can dynamically locate nodes in a given ConCoord instance using\r\nDNS queries if the instance includes replicas that can act as name\r\nservers. There are two ways you can run a ConCoord Replica as a name\r\nserver.\r\n\r\n* **Master Name Server:** Keeps track of the view and responds to DNS\r\n queries itself. Requires su privileges to bind to Port 53.\r\n\r\n* **Route53 Name Server:** Keeps track of the view and updates an Amazon\r\n Route53 account. Amazon Route53 answers to DNS queries on behalf of\r\n the slave name server. Requires a ready-to-use Amazon Route53\r\n account.\r\n\r\nMaster Name Server\r\n+++++++++++++++++++\r\n\r\nTo use a replica node as a master name server first you have to setup\r\nthe name server delegations (you can do this by updating the domain\r\nname server information of any domain name you own from the domain\r\nregistrar you use (godaddy, namecheap etc.)). Once all the delegations\r\nare setup for the ip address the replica uses, you can start a replica\r\nnode as a name server for counterdomain.com as follows::\r\n\r\n $ sudo concoord replica -o concoord.object.counter.Counter -a 127.0.0.1 -n counterdomain.com\r\n\r\nAnd to start the replica to join an already running ConCoord instance,\r\nprovide the bootstrap::\r\n\r\n $ sudo concoord replica -o concoord.object.counter.Counter -a 127.0.0.1 -b 127.0.0.1:14000 -n counterdomain.com\r\n\r\nWhen the replica starts running, you can send queries for\r\ncounterdomain.com and see the most current set of nodes as follows::\r\n\r\n $ dig -t a counterdomain.com # returns set of Replicas\r\n\r\n $ dig -t srv _concoord._tcp.counterdomain.com # returns set of Replicas with ports\r\n\r\n $ dig -t txt counterdomain.com # returns set of all nodes\r\n\r\n $ dig -t ns counterdomain.com # returns set of name servers\r\n\r\nIf you want to run the name server without proper delegation setup, you\r\ncan query the name server bound to 127.0.0.1 specifically as follows::\r\n\r\n $ dig -t txt counterdomain.com @127.0.0.1 # returns set of all nodes\r\n\r\nNote that this would only work for a, srv and txt queries, since ns\r\nqueries require absolute dns names or origins, not an ip address.\r\n\r\nAmazon Route53 Name Server\r\n++++++++++++++++++++++++++\r\n\r\nFirst make sure that boto is installed on the machine you want to run\r\nthe Route53 name server. You can easily install boto as follows::\r\n\r\n $ pip install boto\r\n\r\nBefore starting a name server connected to Amazon Route 53, you should\r\nhave a Route53 account set up and ready to receive requests. This is\r\ndone through the AWS Console (http://console.aws.amazon.com/route53), by\r\ncreating a new Hosted Zone to host your domain name.\r\n\r\nAfter your Route53 account is set up, the name server can update\r\nRoute53 records every time the view of the system changes.\r\n\r\nTo use the Name Server to update Amazon Route53, you should provide\r\nyour AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. You can retrieve\r\nthese from the AWS Console (http://console.aws.amazon.com/iam), by\r\nlooking under the security credentials of the username that you used\r\nwhile creating the Hosted Zone for your domain name. Once you have the\r\ninformation, you can set up ConCoord configuration easily as follows::\r\n\r\n $ concoord route53id [AWS_ACCESS_KEY_ID]\r\n $ concoord route53key [AWS_SECRET_ACCESS_KEY]\r\n\r\nOnce you make sure that your Route53 account is set up and the\r\nconfiguration file includes your AWS credentials, you can start the\r\nreplica with a name server as follows::\r\n\r\n $ concoord replica -o concoord.object.counter.Counter -n counterdomain.com -r\r\n\r\nWhen the replica starts running, you can send queries for\r\ncounterdomain.com and see the most current set of nodes as follows::\r\n\r\n $ dig -t a counterdomain.com # returns set of Replicas\r\n\r\n $ dig -t srv _concoord._tcp.counterdomain.com # returns set of Replicas with ports\r\n\r\n $ dig -t txt counterdomain.com # returns set of all nodes\r\n\r\n $ dig -t ns counterdomain.com # returns set of name servers\r\n\r\nConnecting to ConCoord Objects\r\n------------------------------\r\n\r\nOnce you have a ConCoord instance running with your object, it is easy\r\nto access your object.\r\n\r\nThe proxy for the Counter object is also included in the distribution.\r\nYou can import and use this proxy object in your code. Depending on\r\nhow you set your name server up, you can access your object with the\r\nipaddr:port pair or the domainname. In the example below, the\r\nipaddr:port of both replica nodes are used. As a result, the client\r\nwill be able to do method invocations on the object as long as one of\r\nthe replicas is alive::\r\n\r\n >>> from concoord.proxy.counter import Counter\r\n >>> c = Counter(\"127.0.0.1:14000, 127.0.0.1:14001\")\r\n >>> c.increment()\r\n >>> c.increment()\r\n >>> c.getvalue()\r\n 2\r\n\r\nAt any point to reinitialize an object after it is deployed on\r\nreplicas, you should call __concoordinit__ function::\r\n\r\n >>> from concoord.proxy.counter import Counter\r\n >>> c = Counter(\"127.0.0.1:14000, 127.0.0.1:14001\")\r\n >>> c.increment()\r\n >>> c.__concoordinit__()\r\n >>> c.increment()\r\n >>> c.getvalue()\r\n 1\r\n\r\nOpenReplica\r\n===========\r\n\r\nOpenReplica provides easily launch for concoord on remote machines,\r\nand it is especially built to launch concoord instances on Amazon EC2\r\nservers easily. In this section we cover how you can setup a set of\r\nmachines and launch concoord remotely using OpenReplica.\r\n\r\nHow to start using Amazon EC2\r\n-----------------------------\r\n\r\nYou can easily launch your EC2 instances using the web interface\r\nprovided by Amazon AWS. In this example we launch an instance running\r\n64-bit Amazon Linux. Before you launch your instance, you will have to\r\ncreate a keypair to login to your instances, make sure to keep your\r\nprivate key safe. The best way is to move your key-pair to the .ssh\r\ndirectory once you download the [my-key-pair].pem file::\r\n\r\n $ mv [my-key-pair].pem ~/.ssh/\r\n $ ssh-add ~/.ssh/[my-key-pair].pem\r\n\r\nOnce you did these, now is the time to connect to your instance::\r\n\r\n $ ssh -i [my-key-pair].pem ec2-user@[public_dns_name]\r\n\r\nAfter this point on, you should be able to connect to your instance\r\nwithout explicitly passing the key as a parameter, as follows::\r\n\r\n $ ssh ec2-user@[public_dns_name]\r\n\r\nTo enable execution of remote sudo commands SSH into your instance and\r\nrun::\r\n\r\n $ sudo visudo\r\n\r\nIn the file that opens find the line 'Defaults requiretty' and add\r\nline 'Defaults:ec2-user !requiretty' below it. Save the file and\r\nexit. The file opens with the vi editor. If you are not familiar with\r\nvi commands, to insert new text press i to go into insert mode and add\r\nthe new line. After you are done, press ESC and ZZ to save and exit.\r\n\r\nAt this point, your EC2 instance should be easily accessible.\r\n\r\nUsing OpenReplica\r\n-----------------\r\n\r\nUsing OpenReplica developers can configure and remotely launch\r\nConCoord instances on remote machines easily. Firstly, OpenReplica\r\nkeeps the configuration information of machines that will be running\r\nthe ConCoord instance. Secondly, using ConCoord developers can easily\r\nstart replica and nameserver nodes on the machines that are added to\r\nthe configuration. And lastly, using OpenReplica developers can\r\neasily manage EC2 instances.\r\n\r\nLike ConCoord, OpenReplica can be used as a commandline script. It\r\nsupports the following commands:\r\n\r\nopenreplica config - prints config file\r\nopenreplica addsshkey [sshkeyfilename] - adds sshkey filename to config\r\nopenreplica addusername [ssh username] - adds ssh username to config\r\nopenreplica addnode [publicdns] - adds public dns for node to config\r\nopenreplica setup [publicdns] - downloads and sets up concoord on the given node\r\nopenreplica replica [concoord arguments] - starts a replica node on EC2\r\nopenreplica nameserver [concoord arguments] - starts a nameserver node on EC2\r\n\r\nSetting up the Configuration\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nTo use OpenReplica, you should first register the nodes you want to\r\nuse. To register nodes, you will need the filename of the sshkey you\r\nuse to ssh into these nodes, as well as the username.\r\n\r\nTo add the sshkey::\r\n\r\n $ openreplica addsshkey [my-key-pair].pem\r\n\r\nTo add the username::\r\n\r\n $ openreplica addusername ec2-user\r\n\r\nTo add a node::\r\n\r\n $ openreplica addnode [public_dns_name]\r\n\r\nWhen adding nodes to OpenReplica, it automatically checks the nodes\r\nfor eligibility to run ConCoord and warns the user if an update or\r\nchange is required. Similarly, if ConCoord cannot connect to the node,\r\nit lets the user know::\r\n\r\n $ openreplica addsshkey concoord.pem\r\n Adding SSHKEY to CONFIG: concoord.pem\r\n $ openreplica addusername ec2-user\r\n Adding USERNAME to CONFIG: ec2-user\r\n $ openreplica addnode ec2-54-186-26-155.us-west-2.compute.amazonaws.com\r\n Adding NODE to CONFIG: ec2-54-186-26-155.us-west-2.compute.amazonaws.com\r\n Cannot connect to node, check if it is up and running.\r\n\r\nStarting ConCoord Instances\r\n~~~~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nOnce OpenReplica is set up, nodes can be started as if they are being\r\nstarted on the local machine.\r\n\r\nStarting Replica Nodes\r\n++++++++++++++++++++++\r\n\r\nTo start a bootstrap replica node that doesn't need to be connected to\r\nanother replica::\r\n\r\n $ openreplica replica -o concoord.object.counter.Counter -a 127.0.0.1 -p 14000\r\n\r\nTo start replica nodes to join an active ConCoord instance::\r\n\r\n $ openreplica replica -o concoord.object.counter.Counter -b 127.0.0.1:14000 -a 127.0.0.1 -p 14001\r\n\r\nThe nodes can also be run in the debug mode or with a logger with the\r\ncommands shown below::\r\n\r\n Usage: openreplica replica [-h] [-a ADDR] [-p PORT] [-b BOOTSTRAP]\r\n\t [-o OBJECTNAME] [-l LOGGER] [-n DOMAIN]\r\n\t\t\t [-r] [-w] [-d]\r\n\r\nwhere,\r\n -h, --help show this help message and exit\r\n -a ADDR, --addr ADDR address for the node\r\n -p PORT, --port PORT port for the node\r\n -b BOOTSTRAP, --boot BOOTSTRAP\r\n address:port tuple for the bootstrap peer\r\n -o OBJECTNAME, --objectname OBJECTNAME\r\n client object dotted name\r\n -l LOGGER, --logger LOGGER\r\n logger address\r\n -n DOMAIN, --domainname DOMAIN\r\n domain name that the name server will accept queries for\r\n -r, --route53 use Route53\r\n -w, --writetodisk writing to disk on/off\r\n -d, --debug debug on/off\r\n\r\nStarting Replicas as Name Servers\r\n+++++++++++++++++++++++++++++++++\r\n\r\nYou can dynamically locate nodes in a given ConCoord instance using\r\nDNS queries if the instance includes replicas that can act as name\r\nservers. There are two ways you can run a ConCoord Replica as a name\r\nserver.\r\n\r\n* **Master Name Server:** Keeps track of the view and responds to DNS\r\n queries itself. Requires su privileges to bind to port 53.\r\n\r\n* **Route53 Name Server:** Keeps track of the view and updates an Amazon\r\n Route53 account. Amazon Route53 answers to DNS queries on behalf of\r\n the slave name server. Requires a ready-to-use Amazon Route53\r\n account.\r\n\r\nMaster Name Server\r\n++++++++++++++++++\r\n\r\nTo use a replica node as a master name server first you have to setup\r\nthe name server delegations (you can do this by updating the domain\r\nname server information of any domain name you own from the domain\r\nregistrar you use (godaddy, namecheap etc.)). Once all the delegations\r\nare setup for the ip address the replica uses, you can start a replica\r\nnode as a name server for counterdomain.com as follows::\r\n\r\n $ openreplica replica -o concoord.object.counter.Counter -a 127.0.0.1 -n counterdomain.com\r\n\r\nAnd to start the replica to join an already running ConCoord instance,\r\nprovide the bootstrap::\r\n\r\n $ openreplica replica -o concoord.object.counter.Counter -a 127.0.0.1 -b 127.0.0.1:14000 -n counterdomain.com\r\n\r\nWhen the replica starts running, you can send queries for\r\ncounterdomain.com and see the most current set of nodes as\r\nfollows::\r\n\r\n $ dig -t a counterdomain.com # returns set of Replicas\r\n\r\n $ dig -t srv _concoord._tcp.counterdomain.com # returns set of Replicas with ports\r\n\r\n $ dig -t txt counterdomain.com # returns set of all nodes\r\n\r\n $ dig -t ns counterdomain.com # returns set of name servers\r\n\r\nAmazon Route53 Name Server\r\n++++++++++++++++++++++++++\r\n\r\nFirst make sure that boto is installed on the machine you want to run\r\nthe Route53 name server. OpenReplica tries to do this automatically\r\nwhen a replica is run as a Route53 name server, but if it fails to do\r\nso, you can easily install boto on the machine you want as follows::\r\n\r\n $ pip install boto\r\n\r\nBefore starting a name server connected to Amazon Route53, you should\r\nhave a Route53 account set up and ready to receive requests. This is\r\ndone through the AWS Console (http://console.aws.amazon.com/route53), by\r\ncreating a new Hosted Zone to host your domain name.\r\n\r\nAfter your Route53 account is set up, the name server can update\r\nRoute53 records every time the view of the system changes.\r\n\r\nTo use the Name Server to update Amazon Route53, you should provide\r\nyour AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY. You can retrieve\r\nthese from the AWS Console (http://console.aws.amazon.com/iam/), by\r\nlooking under the security credentials of the username that you used\r\nwhile creating the Hosted Zone for your domain name. Once you have the\r\ninformation, you can set up Route53 configuration easily as follows::\r\n\r\n $ openreplica route53 [public_dns AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY]\r\n\r\nOnce you make sure that your Route53 account is set up and the\r\nconfiguration file includes your AWS credentials, you can start the\r\nreplica with a name server as follows::\r\n\r\n $ openreplica replica -o concoord.object.counter.Counter -n counterdomain.com -r\r\n\r\nWhen the replica starts running, you can send queries for\r\ncounterdomain.com and see the most current set of nodes as follows::\r\n\r\n $ dig -t a counterdomain.com # returns set of Replicas\r\n\r\n $ dig -t srv _concoord._tcp.counterdomain.com # returns set of Replicas with ports\r\n\r\n $ dig -t txt counterdomain.com # returns set of all nodes\r\n\r\n $ dig -t ns counterdomain.com # returns set of name servers\r\n\r\nADVANCED TUTORIAL\r\n=================\r\n\r\nConCoordifying Python Objects\r\n-----------------------------\r\nFor cases when the objects included in the ConCoord distribution do\r\nnot meet your coordination needs, ConCoord lets you convert your\r\nlocal Python objects into distributable objects very easily.\r\n\r\nTo walk through the ConCoord approach, you will use a different\r\nCounter object that increments and decrements by ten, namely\r\ntencounter.py. Once you install ConCoord, you can create coordination\r\nobjects and save them anywhere in your filesystem. After you create\r\ntencounter.py, you can save tencounter.py under /foo/tencounter.py::\r\n\r\n class TenCounter:\r\n def __init__(self, value=0):\r\n self.value = value\r\n\r\n def decrement(self):\r\n self.value -= 10\r\n\r\n def increment(self):\r\n self.value += 10\r\n\r\n def getvalue(self):\r\n return self.value\r\n\r\n def __str__(self):\r\n return \"The counter value is %d\" % self.value\r\n\r\nOnce you have created the object, update your PYTHONPATH accordingly,\r\nso that the objects can be found and imported::\r\n\r\n $ export PYTHONPATH=$PYTHONPATH:/foo/\r\n\r\nClients will use a proxy object to do method calls on the object.\r\nTo create the proxy object automatically, you can use the following\r\ncommand::\r\n\r\n $ concoord object -o tencounter.TenCounter\r\n\r\n\r\n Usage: concoord object [-h] [-o OBJECTNAME] [-t SECURITYTOKEN] [-p PROXYTYPE]\r\n [-s] [-v]\r\n\r\nwhere,\r\n -h, --help\t\t\t\t\tshow this help message and exit\r\n -o OBJECTNAME, --objectname OBJECTNAME\tclient object dotted name module.Class\r\n -t SECURITYTOKEN, --token SECURITYTOKEN\tsecurity token\r\n -p PROXYTYPE, --proxytype PROXYTYPE\t\t0:BASIC, 1:BLOCKING,\r\n \t\t\t \t\t\t2:CLIENT-SIDE BATCHING, 3:SERVER-SIDE BATCHING\r\n -s, --safe \t\t\tsafety checking on/off\r\n -v, --verbose \t\t\tverbose mode on/off\r\n\r\nThis script will create a proxy file under the directory that the\r\nobject resides (i.e. /foo/)::\r\n\r\n/foo/tencounterproxy.py := the proxy that can be used by the client\r\n\r\nIMPORTANT NOTE: ConCoord objects treat __init__ functions specially in\r\ntwo ways:\r\n\r\n1) When Replicas go live, the object is instantiated calling the\r\n__init__ without any arguments. Therefore, while implementing\r\ncoordination objects, the __init__ method should be implemented to be\r\nable to run without explicit arguments. You can use defaults to\r\nimplement an __init__ method that accepts arguments.\r\n\r\n2) In the proxy created, the __init__ function is used to initialize\r\nthe Client-Replica connection. This way, multiple clients can connect\r\nto a ConCoord instance without reinitializing the object. During proxy\r\ngeneration, the original __init__ function is renamed as\r\n__concoordinit__, to reinitialize the object the user can call\r\n__concoordinit__ at any point.\r\n\r\nAfter this point on, you can use TenCounter just like we use Counter before.\r\n\r\nCreating Source Bundles\r\n-----------------------\r\n\r\nYou can create bundles to use at the server and client sides using the\r\nMakefile provided. Remember to add the objects you have created in\r\nthese bundles.\r\n\r\nCreating A Server Bundle\r\n~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nTo create a bundle that can run replicas::\r\n\r\n $ make server\r\n\r\nCreating A Client Bundle\r\n~~~~~~~~~~~~~~~~~~~~~~~~\r\n\r\nTo create a bundle that can run a client and connect to an existing\r\nConCoord instance::\r\n\r\n $ make client\r\n\r\nLogging\r\n-------\r\n\r\nWe have two kinds of loggers for ConCoord::\r\n* Console Logger\r\n* Network Logger\r\n\r\nBoth of these loggers are included under utils.py. To start the\r\nNetworkLogger, use the logdaemon.py on the host you want to keep the\r\nLogger.\r\n\r\nSynchronization & Threading\r\n---------------------------\r\n\r\nConCoord provides a distributed and fault-tolerant threading\r\nlibrary. The library includes:\r\n\r\n* Lock\r\n* RLock\r\n* Semaphore\r\n* BoundedSemaphore\r\n* Barrier\r\n* Condition\r\n\r\nThe implementations of distributed synchronization objects follow the\r\nimplementations in the Python threading library. We will walk through\r\nan example below using the Semaphore object under\r\nconcoord/object/semaphore.py\r\n\r\nIn the blocking object implementation, the method invocations that use\r\nan object from the threading library requires an extra argument\r\n_concoord_command. This argument is used by the calling Replica node\r\nto relate any blocking/unblocking method invocation to a specific\r\nclient. This way, even if the client disconnects and reconnects, the\r\nConCoord instance will remain in a safe state::\r\n\r\n from concoord.threadingobject.dsemaphore import DSemaphore\r\n\r\n class Semaphore:\r\n def __init__(self, count=1):\r\n self.semaphore = DSemaphore(count)\r\n\r\n def __repr__(self):\r\n return repr(self.semaphore)\r\n\r\n def acquire(self, _concoord_command):\r\n try:\r\n\treturn self.semaphore.acquire(_concoord_command)\r\n except Exception as e:\r\n raise e\r\n\r\n def release(self, _concoord_command):\r\n try:\r\n return self.semaphore.release(_concoord_command)\r\n except Exception as e:\r\n raise e\r\n\r\n def __str__(self):\r\n return str(self.semaphore)\r\n\r\nTo create the proxy for this blocking object we will use the following command::\r\n\r\n $ concoord object -o concoord.object.semaphore.Semaphore -p 1\r\n\r\nThis command creates the proxy that supports blocking operations. Now\r\nyou can use blocking objects just like basic ConCoord objects. First,\r\nwe start the replica nodes the same way we did before as follows::\r\n\r\n $ concoord replica -o concoord.object.semaphore.Semaphore -a 127.0.0.1 -p 14000\r\n\r\nTo test the functionality, you can use multiple clients or print out\r\nthe Semaphore object as follows::\r\n\r\n >>> from semaphoreproxy import Semaphore\r\n >>> s = Semaphore(\"127.0.0.1:14000\")\r\n >>> s.acquire()\r\n True\r\n >>> i = 10\r\n >>> i += 5\r\n >>> s\r\n \r\n >>> s.release()\r\n >>> s\r\n \r\n >>>\r\n\r\nHOMEPAGE\r\n========\r\n\r\nVisit http://openreplica.org to get more information on ConCoord.\r\n\r\nCONTACT\r\n=======\r\n\r\nIf you believe you have found a bug or have a problem you need\r\nassistance with, you can get in touch with us by emailing\r\nconcoord@systems.cs.cornell.edu", "description_content_type": null, "docs_url": "https://pythonhosted.org/concoord/", "download_url": "http://openreplica.org/download/", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://openreplica.org/", "keywords": "", "license": "3-Clause BSD", "maintainer": "Deniz Altinbuken", "maintainer_email": "deniz@systems.cs.cornell.edu", "name": "concoord", "package_url": "https://pypi.org/project/concoord/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/concoord/", "project_urls": { "Download": "http://openreplica.org/download/", "Homepage": "http://openreplica.org/" }, "release_url": "https://pypi.org/project/concoord/1.1.0/", "requires_dist": null, "requires_python": null, "summary": "Coordination service for distributed systems.", "version": "1.1.0" }, "last_serial": 1050699, "releases": { "1.0.0": [ { "comment_text": "", "digests": { "md5": "8e55ba7cb447097ad2f37fc4421b3da3", "sha256": "3afa53e69b8b98da603249f2b88516bd5131416990b552caabf4c084000da77c" }, "downloads": -1, "filename": "concoord-1.0.0.tar.gz", "has_sig": false, "md5_digest": "8e55ba7cb447097ad2f37fc4421b3da3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 69501, "upload_time": "2013-09-22T20:39:46", "url": "https://files.pythonhosted.org/packages/68/87/b50be36098f3f95cfef7d5ccab1da5549c9e7d3d94d6a39b69c3f5922faa/concoord-1.0.0.tar.gz" } ], "1.0.1": [ { "comment_text": "", "digests": { "md5": "ca7968920fc84a6b7049e94d82b6cdd9", "sha256": "6c5fab1993ef25db60f54fbaf956d9df738a5c2c1e7b387e282ef5a7d35dcd0b" }, "downloads": -1, "filename": "concoord-1.0.1.tar.gz", "has_sig": false, "md5_digest": "ca7968920fc84a6b7049e94d82b6cdd9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 70171, "upload_time": "2013-10-05T21:19:50", "url": "https://files.pythonhosted.org/packages/6f/6f/59d3b6ec8be9ddbabd55afdc587b5037042e82f4b9c8e822c3de65d58e6a/concoord-1.0.1.tar.gz" } ], "1.0.2": [ { "comment_text": "", "digests": { "md5": "34314d005d16bd5e3e400da7b9850cc4", "sha256": "fa55f600160102e75c87fe855369f801cacbe8c65b00e6bb50b37d3759b768f0" }, "downloads": -1, "filename": "concoord-1.0.2.tar.gz", "has_sig": false, "md5_digest": "34314d005d16bd5e3e400da7b9850cc4", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 72325, "upload_time": "2014-02-22T23:29:54", "url": "https://files.pythonhosted.org/packages/dd/17/ddb75ca324333b12322196532bfed332b95bd5e5e075ba63ca0bcc98b481/concoord-1.0.2.tar.gz" } ], "1.1.0": [ { "comment_text": "", "digests": { "md5": "3069bc76beeb1b0a22e7ad46f653e56c", "sha256": "2494bf83c20fdfdb744daf97a7d68e63b342afaaa77cf95076003c3983d189fb" }, "downloads": -1, "filename": "concoord-1.1.0.tar.gz", "has_sig": false, "md5_digest": "3069bc76beeb1b0a22e7ad46f653e56c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 75448, "upload_time": "2014-04-03T20:08:17", "url": "https://files.pythonhosted.org/packages/f4/8a/00f06b084a5b15ae1980f7679f3f4ef6c048b737a4324b1f62ddc9f7d541/concoord-1.1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "3069bc76beeb1b0a22e7ad46f653e56c", "sha256": "2494bf83c20fdfdb744daf97a7d68e63b342afaaa77cf95076003c3983d189fb" }, "downloads": -1, "filename": "concoord-1.1.0.tar.gz", "has_sig": false, "md5_digest": "3069bc76beeb1b0a22e7ad46f653e56c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 75448, "upload_time": "2014-04-03T20:08:17", "url": "https://files.pythonhosted.org/packages/f4/8a/00f06b084a5b15ae1980f7679f3f4ef6c048b737a4324b1f62ddc9f7d541/concoord-1.1.0.tar.gz" } ] }