Package: tcpnetlock
TcpNetLockNetwork lock based on TCP socketsFree software: GNU General Public License v3Documentation:https://tcpnetlock.readthedocs.io/GitHub:https://github.com/hgdeoro/tcpnetlock/Docker:https://hub.docker.com/r/hgdeoro/tcpnetlock/Why?While deploying applications to Kubernetes, I needed a way to make sure that
some potential concurrent, distributed actions, are not executed concurrently.
For example:database migrations: just one Pod in the Kubernetes cluster should be able to apply the database migrationsforbatch jobs, different workers could be working on the same resource, this can be avoided with this lock mechanismOf course, Zookeeper is a MUCH BETTER solution, but that’s too much for my use cases…How it worksAssuming the server is running on localhost, let’s get a lock using telnet:$ telnet localhost 7654
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.To try to acquire a lock, send:lock,name:django-migrationsServer responds with:okFrom that point, and while the TCP connection is open, you have the lock.If you try the same in a different terminal, you will get:$ telnet localhost 7654
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
lock,name:django-migrations        <= you write
not-granted                        <= server response
Connection closed by foreign host. <= server closed the connectionHere the server responded withnot-grantedand closed the TCP connection. The lock was not granted to you.But, in real-life scenarios, you would use the provided utilitytcpnetlock_do:$ tcpnetlock_do --lock-name django-migrations -- python manage.py migrateTo test it, you will need the server running. To get the server running with Docker, just run:$ docker pull hgdeoro/tcpnetlock
$ docker run -ti --rm -p 7654:7654 hgdeoro/tcpnetlockAlternatively, you can install the package in a virtualenv and launch the server:$ virtualenv -p python3.6 venv
$ source venv/bin/activate
$ pip install tcpnetlock
$ tcpnetlock_server --info
INFO:root:Started server listening on localhost:7654FeaturesRuns on Python 3.6 / Python 3.5Do not require external librariesReady to use Docker image (based on Alpine)Includes server and python clientIncludes utility to run Linux commands while holding the lockSimple protocol: you can get a lock even withnetcatAppendix: netcatSince the protocol is just text over a TCP connection, you can get a lock just writing the
right text overt the TCP connection and leaving that TCP connection open, and that’s the default
behaviour of netcat:$ echo 'lock,name:LOCK_NAME' | nc localhost 7654The first line uses netcat to open the TCP connection and tries to get the lock.The biggest problem would be to READ the response to the server (will be one of ‘ok’ or ‘not-granted’) while
sendncto the background. We can use afifofor that:$ echo 'lock,name:LOCK_NAME' | nc -v localhost 7654 | tee /tmp/.tcpnetlock &
$ result=$(head -n 1 /tmp/.tcpnetlock)Even though this works, using one of the two existing python clients (tnl_clientandtnl_do) would be much better.CreditsThis package was created withCookiecutterand theaudreyr/cookiecutter-pypackageproject template.History0.1.8 (2018-07-20)Make period of cleanup configurable via environment variablesFIX response for stats actionAdd tests for background threadAdd client method to call the stats action0.1.7 (2018-07-19)Log release of lock causde by client disconnectingAdd .stats actionAdd background thread to cleanup old locksRemove global server state hold on Context class0.1.6 (2018-07-06)FIX tag used in Docker imagelog server version when starting0.1.5 (2018-06-26)FIX variable name used for building Docker imageChange theme for docs0.1.4 (2018-06-26)Implements retries for cli tnl_do0.1.3 (2018-06-22)Server logs granted lockAdd description to CLIClient use environment variables for host/portAdd __str__ to Action to have better logs in server0.1.2 (2018-06-21)Update client & server to handle errors in a better wayAdd testsUpdate docs0.1.1 (2018-06-20)Add .bashrc (for developers)Fix setup.py0.1.0 (2018-06-19)Docker start server with –info by defaultAdds cloudbuild.yaml to facilitate building in GCPChange in protocol to detect unintended usesDetect invalid requests and always send response to clientBIG refactor of server and client classesAdd lot of tests (current coverage: 99%)0.0.8 (2018-06-18)Refactor messy code from server, client and cli0.0.7 (2018-06-17)Code cleanup and refactorAdd testsImplements run_with_lock script to make really easy to use from shell scripts0.0.6 (2018-06-16)Create shell script to be sourced, to facilitate use of tcpnetlock from shell scripts0.0.5 (2018-06-15)Update CONTRIBUTING (documents commands for the full release process)Disable upload to pypi from Travis-CI0.0.4 (2018-06-15)Encapsulate Lock, adds client id and timestampImplement sending of keepalive from clientRemove use of ‘click’Start server from cli with configurable parameters (listen address, port, etc)Use client id to identify who has the lock0.0.3 (2018-06-15)Validate lock name in serverFIX client to handle RESPONSE_ERR responseAdd unittestsRefactor locks into server classUse threading for test serverMake code compatible with Python 3.50.0.2 (2018-06-15)Implements RELEASE of locksFIX release of lock when client closes the connectionValidates lock nameCode refactoring0.0.1 (2018-06-15)Add files from cookiecutter-pypackageMigrate test cases to pytest