{ "info": { "author": "Brady Catherman", "author_email": "github@gecka.us", "bugtrack_url": null, "classifiers": [], "description": "================\n=== Twitcher ===\n================\n\n1. License\n2. Overview\n3. Installation\n4. Configuration Language\n4.1 Examples\n4.2 Things to Avoid\n5. Known Issues\n6. Future Features\n7. Change Log\n\n1. License\n==========\n\nThis software is licensed under the Apache 2.0 license. Please see LICENSE\nin the top level of this git repository for more information.\n\n2. Overview\n===========\n\nTwitcher is a minimal tool used to run scripts when a znode in ZooKeeper\nchanges. The intent is to allow various system tasks to take place on a\nwatched model rather than via polling.\n\nThe best description of Twitcher is to highlight an example that it solves\nvery well. Lets assume we are facing a problem where we need a single git\nrepository to be checked out and up to date on 100 machines in a cluster. The\ntypical solution to this is to add a cron job that performs a git pull every\nminute. This can be problematic as your git server has to endure the load of\n100 servers performing a pull every minute. You can configure Twitcher on all\nmachines to watch /git/head on your ZooKeeper instance. When that znode\nchanges Twitcher can run git pull. Add a post-commit script in your main\ngit repository that pokes that file and you will be able to fetch updates\nwithin few seconds of a commit on all machines while not requiring constant\nfetching when no changes are being made.\n\n3. Installation\n===============\n\nThe default installation of Twitcher places the twitcher binary (bin/twitcher)\nin /usr/sbin and the twitcher module (twicher/*) in the site-packages\ndirectory which is often /usr/lib/python2.6/sites-packages/twitcher.\n\nThe configs are read recursively from /etc/twitcher while twitcher is running.\n\nNote that Twitcher uses inofity to update when files change so it can\nautomatically reload them. This is used to allow quick adding and removing\nof configs without restarting the server binary. If a config fails to parse\nthen it will not be updated in the running binary and a log message will be\nwritten.\n\nBy default Twitcher uses syslog under daemon as the default logging method.\n\n4. Configuration Language\n=========================\n\nThe configuration language for Twitcher is actually just python. Each\nconfiguration must register a znode, and an action for each watch it wants.\nThis is done via a RegisterWatch function which takes several arguments.\n\nRegisterWatch(): Creates a watch that will run a script when a Zookeeper node\n is updated.\n znode: This is the znode in ZooKeeper that is to be watched.\n action: This is a function or lambda that will perform an action when\n the znode is modified. The most common use here is to call Exec()\n which is a function documented later.\n pipe_stdin: If True then the contents of 'znode' will be piped to the stdin\n of the processes running action. Default is True.\n run_on_load: If True then the action will be executed when Twitcher starts.\n Without this your action may miss updates.\n The default is True.\n run_mode: This defines how Twitcher will react when 'znode' is updated\n while it is running 'action' for a previous update. The optional\n modes are:\n QUEUE: This will queue the watch until the currently running\n 'action' finishes, then run 'action' with the most\n recent contents. If several watches are received while\n 'action' is running then only the last update will\n be executed.\n DISCARD: Ignore the update, don't run the script, but\n re-register the watch.\n PARALLEL: Run the script in parallel for every update received.\n The default run mode is QUEUE.\n uid: The user id to run the process as (string or int). The default is to\n run as root.\n gid: The group id to run the process as (string or int). The default is to\n run as root.\n notify_signal: This is the signal that will be send to the spawned\n process that is currently running when a new update has\n been received. By default this is not used, and it will only\n work if the run_mode is QUEUE.\n timeout: The number of seconds before any spawned process should be sent\n a SIGTERM. Five seconds later the process will be sent a SIGKILL.\n description: This is a text description of the watch which will be used\n for logging. The default is to name watches after the file\n they are configured in.\n\nExec(): Returns a lambda that will execute a given command when run.\n command: If this is a string then the command will be invoked in a\n shell interpreter. If its a list then it will be executed\n exactly as specified.\n\nBy default the configuration files should be placed in /etc/twitcher and\nshould use an extension of \".twc\".\n\n\n4.1. Examples\n=============\n\nIn this example config a node called '/twitcher/example1' will be watched for\nupdates, and when it changes it will execute\n\"date >> /tmp/twitcher_example1.out\".\n\nRegisterWatch(\n znode='/twitcher/example1',\n action=Exec('date >> /tmp/twitcher_example1.out')\n )\n\nAs another example we can run a python function rather than executing a\ncommand. For this example we will execute the function example2() every time\n'/twitcher/example2' is updated.\n\ndef example2():\n open('/tmp/twitcher_example2.out', 'w').write('testing')\n\nRegisterWatch(\n znode='/twitcher/example2',\n action=example2\n )\n\nKeep in mind that the action function is run in a process that has been forked\noff from the main Twitcher instance. As such the following example\nDOES NOT WORK AS EXPECTED. The output will always be 1 since the increment\nhappens in the child process which exits after doesnotwork() finishes.\n\nx = 0\ndef doesnotwork():\n global x\n x += 1\n open('/tmp/twitcher_badexample.out', 'w').write(x)\n\nRegisterWatch(\n znode='/twitcher/doesnotwork',\n action=doesnotwork\n )\n\n4.2 Things to Avoid\n===================\n\nAny action run by Twitcher is expected to by idempotent. Since the script may\nbe executed at any time and can be triggered rapidly it is expected that\neach script does basic health and sanity checking before performing expensive\nor destructive actions.\n\nEven if the script is in QUEUE mode there is a possibility that it may be run\ntwice. If Twitcher is restarted while the script is running it will then\nrestart the script when Twitcher restarts which leaves two running at the\nsame time. In order to prevent this your script should use file based sigil\nor other method to verify exclusivity.\n\n5. Known Issues\n===============\n\nNone at the moment.\n\n6. Future Features\n==================\n\nFailure handling on the child process: Allow the config to specify what should\nbe done in the case where the script fails (returns non zero). Some examples\ninclude \"retry x times\" \"fail but keep watch\" \"fail and stop watching\"\n\n7. Change Log\n=============\n\nRelease 1.7.5:\n\n2014/05/13: Trusty support for Ubuntu.\n\nRelease 1.7.4:\n\n2014/04/02: Allow uploading of builds to be skipped so they are easier to\n test locally.\n2014/04/02: Fix a bug in the upstart script.\n2014/04/02: Better error handling and reporting, as well as a format string\n fix that caused connections to be impossible.\n\nRelease 1.7.3\n\n2014/04/02: Imported print() from future to support python3.0 properly.\n\nRelease 1.7.2\n\n2014/03/21: Better Python 3.0 support.\n\nRelease 1.7.1\n\n2014/03/19: Integrated wickman and jtrosby's improvements into the code base.\n\nRelease 1.7.0\n\n2014/03/19: No signifigant code changes but major changes to the delivery\n and build structure.\n\nRelease: 1.5\n\n2010/11/08: Make connection re-establish all existing watches.\n\nRelease: 1.4\n\n2010/10/25: Fix client session expiration recovery.\n\n2010/8/3: Documentation fixes.\n\nRelease: 1.3\n\n2010/8/2: Added notify_signal and timeout support and fix a few bugs.\n\nRelease: 1.2, Open source under the Apache 2.0 license.\n\n2010/7/15: Added uid/gid support\n\nRelease: 1.1\n\n2010/6/24: Fixed a bug that allowed child processes to get ignored forever.\n\nRelease 1.0\n\n2010/6/19: Initial review.\n", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://github.com/liquidgecka/twitcher", "keywords": null, "license": "UNKNOWN", "maintainer": null, "maintainer_email": null, "name": "twitcher", "package_url": "https://pypi.org/project/twitcher/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/twitcher/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://github.com/liquidgecka/twitcher" }, "release_url": "https://pypi.org/project/twitcher/1.7.5/", "requires_dist": null, "requires_python": null, "summary": "A tool for watching Zookeeper nodes.", "version": "1.7.5" }, "last_serial": 1091176, "releases": { "1.7.0": [ { "comment_text": "", "digests": { "md5": "dae0f9fc64628ab65b6965bbe14861a3", "sha256": "eabfa89235fec1cd2d1da7b4dbb4ebc9c69428e91238f607db7054c7afe4b5fb" }, "downloads": -1, "filename": "twitcher-1.7.0.tar.gz", "has_sig": false, "md5_digest": "dae0f9fc64628ab65b6965bbe14861a3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19304, "upload_time": "2014-03-19T19:29:58", "url": "https://files.pythonhosted.org/packages/ad/d6/7c4685a61b593904711f3ab8538b00b5f5ede396524f70ebb5f7a2c0f664/twitcher-1.7.0.tar.gz" } ], "1.7.1": [ { "comment_text": "", "digests": { "md5": "505c78a4fe2328e3970af7a0c0d25606", "sha256": "6a3d7654986aff28bdf8c5cba91c03218b8ac205a680d0095f55efee1092544a" }, "downloads": -1, "filename": "twitcher-1.7.1.tar.gz", "has_sig": false, "md5_digest": "505c78a4fe2328e3970af7a0c0d25606", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19321, "upload_time": "2014-03-19T21:57:09", "url": "https://files.pythonhosted.org/packages/9d/08/fa3c485d4c8a21698905a0242c67a1ceb42d87094220dc0e0fe1bb4adbd3/twitcher-1.7.1.tar.gz" } ], "1.7.2": [ { "comment_text": "", "digests": { "md5": "bb2a28a02c7e388343ed4567c737afa0", "sha256": "f3baa276c9fc9850532af1bc12ce3e9017b6ef5c0e236532065fc8766149cf93" }, "downloads": -1, "filename": "twitcher-1.7.2.tar.gz", "has_sig": false, "md5_digest": "bb2a28a02c7e388343ed4567c737afa0", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19335, "upload_time": "2014-03-21T23:19:02", "url": "https://files.pythonhosted.org/packages/cc/b6/1566be19056e2a8197990d02585f9fadf5e7a8d6f56fa25e409e120e3e57/twitcher-1.7.2.tar.gz" } ], "1.7.3": [ { "comment_text": "", "digests": { "md5": "adf47eda3b95e2b17d2493717670fec3", "sha256": "2b2e036a20ddbf37449cc99cfd1e7e3cb8ac79e86c90b30e4ec677f16f5ccfeb" }, "downloads": -1, "filename": "twitcher-1.7.3.tar.gz", "has_sig": false, "md5_digest": "adf47eda3b95e2b17d2493717670fec3", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19396, "upload_time": "2014-04-02T19:29:56", "url": "https://files.pythonhosted.org/packages/5a/83/f729eb8a1925e85a85633aaad722b56271e92016bde6092936cf534ee5cb/twitcher-1.7.3.tar.gz" } ], "1.7.4": [ { "comment_text": "", "digests": { "md5": "9025541c92d25f265000b0f85f7938a6", "sha256": "c81583f8bbdac88456dfdc2af1616e05e69b64d57971b9c8dfbaa516115e3e22" }, "downloads": -1, "filename": "twitcher-1.7.4.tar.gz", "has_sig": false, "md5_digest": "9025541c92d25f265000b0f85f7938a6", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19520, "upload_time": "2014-04-02T21:15:14", "url": "https://files.pythonhosted.org/packages/fd/56/7e559ed397976586c8a1713f7311f1afd72e3c5677cb014a1b3d866e2de5/twitcher-1.7.4.tar.gz" } ], "1.7.5": [ { "comment_text": "", "digests": { "md5": "2d895b25beb0a19fc4d5e667922b79be", "sha256": "9398cc052c23c07dde587d119702d2aa6706c6ec2703de4be7c87571f2774428" }, "downloads": -1, "filename": "twitcher-1.7.5.tar.gz", "has_sig": false, "md5_digest": "2d895b25beb0a19fc4d5e667922b79be", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19356, "upload_time": "2014-05-13T18:58:43", "url": "https://files.pythonhosted.org/packages/73/d4/a55bc10d9d44ad6fa568760acdbcf697097fe89468670ef002a0bde7a310/twitcher-1.7.5.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "2d895b25beb0a19fc4d5e667922b79be", "sha256": "9398cc052c23c07dde587d119702d2aa6706c6ec2703de4be7c87571f2774428" }, "downloads": -1, "filename": "twitcher-1.7.5.tar.gz", "has_sig": false, "md5_digest": "2d895b25beb0a19fc4d5e667922b79be", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 19356, "upload_time": "2014-05-13T18:58:43", "url": "https://files.pythonhosted.org/packages/73/d4/a55bc10d9d44ad6fa568760acdbcf697097fe89468670ef002a0bde7a310/twitcher-1.7.5.tar.gz" } ] }