{ "info": { "author": "lvh", "author_email": "_@lvh.io", "bugtrack_url": null, "classifiers": [ "Development Status :: 3 - Alpha", "Framework :: Twisted", "Intended Audience :: Developers", "License :: OSI Approved :: Apache Software License", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 2 :: Only" ], "description": "=========\n thimble\n=========\n\n.. image:: https://travis-ci.org/lvh/thimble.svg\n :target: https://travis-ci.org/lvh/thimble\n.. image:: https://coveralls.io/repos/lvh/thimble/badge.png\n :target: https://coveralls.io/r/lvh/thimble\n\n.. image:: https://dl.dropboxusercontent.com/u/38476311/Logos/thimble.jpg\n\nA thimble is a tool for playing with needle and thread safely. This\nlibrary, thimble, wraps objects that have a blocking API with a\nnon-blocking, Twisted-friendly Deferred API by means of thread pools.\n\nQuick start\n===========\n\nThe main object you're interested in is ``thimble.Thimble``. It takes a\nthread pool, a blocking object, and a list of method names that you\nwould like to defer to the thread pool.\n\nHere's our example blocking object:\n\n>>> class Car(object):\n... wheels = 4\n... def drive_to(self, location):\n... # Assume the real implementation blocks.\n... return \"driven to {0}\".format(location)\n>>> car = Car()\n\nFor demonstration purposes, we'll use a test doubles for the thread\npool and reactor; in real code, you'll want to use the real thing.\n\n>>> from thimble.test.util import FakeThreadPool, FakeReactor\n>>> pool = FakeThreadPool()\n>>> reactor = FakeReactor()\n\nThe pool hasn't been started yet. (We'll see why that matters in a\nminute.)\n\n>>> pool.started\nFalse\n\nCreate a ``Thimble``:\n\n>>> from thimble import Thimble\n>>> car_thimble = Thimble(reactor, pool, car, [\"drive_to\"])\n\nWhen accessing a method named in the list, you get an object wrapping\nit instead. Calling it returns a Deferred. Any arguments passed are\npassed verbatim to the wrapped method.\n\n>>> def print_(s):\n... # can't use from __future__ import print_function because of a\n... # doctest limitation :-(\n... print s\n\n>>> d = car_thimble.drive_to(\"work\").addCallback(print_)\ndriven to work\n\nThis Deferred has already fired synchronously, because we're using a\nfake thread pool and reactor.\n\nYou can access other attributes of the wrapped object directly on the\n``Thimble``:\n\n>>> car.wheels\n4\n\nIf the thread pool that you pass to a ``Thimble`` hasn't been started\nyet when it first tries to use it, the ``Thimble`` will start it and\nschedule its shutdown. If you pass a thread pool that *was* already\nstarted, you are responsible for its shutdown. In this case, the\nthread pool was not started yet, so ``Thimble`` started it for you:\n\n>>> pool.started\nTrue\n\nShut down the reactor, and the reactor will ask the thread pool to\nstop right before shutting down itself.\n\n>>> reactor.stop()\n>>> pool.started\nFalse\n\nUsing thimble in your code\n--------------------------\n\nThread pools\n~~~~~~~~~~~~\n\nYou can choose to use the reactor thread pool, or create your own\nthread pool.\n\nUsing the reactor thread pool is potentially a bad idea. The reactor\nthread pool is shared between a lot of software by default, and is\nalso used for DNS resolution. If your software blocks all the\navailable threads in the pool (either by accident or because of a\nbug), that affects DNS resolution, which in turn can affect many other\nsystems; if it doesn't affect those systems directly (because they,\ntoo, want to use the reactor thread pool).\n\nIt's probably most reliable to have a dedicated thread pool per\napplication, for two reasons:\n\n- The application probably knows best what a good size would be for\n the thread pool.\n- It is an appropriate state to put the global state: if you were to\n put it in a library, different users of the library in the same\n process can end up tripping over each other.\n\nUnfortunately, shared global state is pretty much how you do it::\n\n from twisted.python.threadpool import ThreadPool\n _the_thread_pool = _ThreadPool()\n\nSee the documentation for the ThreadPool class for more details; it\nallows you to specify a minimum and maximum number of threads. The\ndefault values are probably pretty reasonable.\n\nConcurrency and thread safety\n^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\nThe number of threads you specify your thread pool to have is the\nnumber of threads that can try to access your object concurrently.\nit's up to you to make sure that the object is actually thread safe.\n\nIf you would like to provide a non-blocking API to an object that\nisn't thread safe, you can just limit the number of threads in the\nthread pool to 1, causing fully synchronized access. Keep in mind that\nattribute accesses for any attribute name that isn't in the\n``blocking_methods`` list will still be performed synchronously by the\ncalling thread.\n\nEntry points\n~~~~~~~~~~~~\n\nWhile subclassing ``Thimble`` may accidentally work, it is not\nrecommended. I reserve the right to change the implementation in a way\nthat might break that: for example, by introducing a metaclass.\n\nIt's probably better to write a small utility function that either\nconstructs a new ``Thimble`` that uses a shared thread pool, or always\nreturns the same thimble.\n\nChangelog\n=========\n\nThimble uses SemVer_.\n\n.. _SemVer: http://semver.org/\n\nv0.2.0\n------\n\n- Minor updates to the tox CI set up\n- Upgraded dependencies\n\nv0.1.1\n------\n\n- Added this changelog\n- Spelling fixes\n- Added a ``.gitignore``\n- Lots of documentation improvements\n\nv0.1.0\n------\n\nInitial public release.", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/lvh/thimble", "keywords": "twisted threads thread compat compatibility async asynchronous", "license": "Apache 2.0", "maintainer": "", "maintainer_email": "", "name": "thimble", "package_url": "https://pypi.org/project/thimble/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/thimble/", "project_urls": { "Homepage": "https://github.com/lvh/thimble" }, "release_url": "https://pypi.org/project/thimble/0.2.0/", "requires_dist": [ "Twisted (==14.0)", "zope.interface (==4.1.1)" ], "requires_python": "", "summary": "A Twisted thread-pool based wrapper for blocking APIs.", "version": "0.2.0" }, "last_serial": 1994461, "releases": { "0.1.0": [ { "comment_text": "", "digests": { "md5": "a7958188b61722d46fa70692041d7315", "sha256": "bcd83887885fc6c2ad48474e65d62cb3570098ba934a1902a8a17e9f799d1ae7" }, "downloads": -1, "filename": "thimble-0.1.0-py27-none-any.whl", "has_sig": false, "md5_digest": "a7958188b61722d46fa70692041d7315", "packagetype": "bdist_wheel", "python_version": "py27", "requires_python": null, "size": 10048, "upload_time": "2014-05-17T13:40:29", "url": "https://files.pythonhosted.org/packages/99/eb/b066464eb7c439b8a0d928c3a3dc7fd32f9da1a3d658be7afdbbd0deb1e7/thimble-0.1.0-py27-none-any.whl" }, { "comment_text": "", "digests": { "md5": "e675247d5ab5eb745d0d32b12beaf199", "sha256": "28c91cf7217f1a089b56db8d174206ad2869e3865ed81653f3c33129c3cf30f9" }, "downloads": -1, "filename": "thimble-0.1.0.tar.gz", "has_sig": false, "md5_digest": "e675247d5ab5eb745d0d32b12beaf199", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7902, "upload_time": "2014-05-17T13:40:31", "url": "https://files.pythonhosted.org/packages/52/67/a9c27472269c2655bdc558e41d9c5510d3efdf62c0975fdf432f98cf3d9a/thimble-0.1.0.tar.gz" } ], "0.1.1": [ { "comment_text": "", "digests": { "md5": "7f8e5a868ac84459c409cc70a6726d2b", "sha256": "b96d423f511dc391e4ddd5dbcdfa805222ce7479ff9e4feae769c9ed01b1d901" }, "downloads": -1, "filename": "thimble-0.1.1-py27-none-any.whl", "has_sig": false, "md5_digest": "7f8e5a868ac84459c409cc70a6726d2b", "packagetype": "bdist_wheel", "python_version": "py27", "requires_python": null, "size": 11413, "upload_time": "2014-05-18T09:34:41", "url": "https://files.pythonhosted.org/packages/47/a5/7ea55d2e784f4b0be0d77db635ad9cd3c9c7ae6f2f76d02d5853597f3860/thimble-0.1.1-py27-none-any.whl" }, { "comment_text": "", "digests": { "md5": "ec8529b480eb5f1b8d62a354bfc40d4c", "sha256": "5a0b492f19d5eeb0b9e5cb0fe8d6e6d3b3f620b9ecf7b4c49c84e1089086ff82" }, "downloads": -1, "filename": "thimble-0.1.1.tar.gz", "has_sig": false, "md5_digest": "ec8529b480eb5f1b8d62a354bfc40d4c", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8870, "upload_time": "2014-05-18T09:34:43", "url": "https://files.pythonhosted.org/packages/ed/eb/e24388cb66c85bcf77fba40d0ac8cc12394e395cd37cc55238ed03fe679e/thimble-0.1.1.tar.gz" } ], "0.2.0": [ { "comment_text": "", "digests": { "md5": "272555042ad16b824d34b832e2a0adaa", "sha256": "0945674f15497f490b05bdefd197f2fd7a6071f6799ea4565f67e7e40e72a216" }, "downloads": -1, "filename": "thimble-0.2.0-py2-none-any.whl", "has_sig": false, "md5_digest": "272555042ad16b824d34b832e2a0adaa", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 11857, "upload_time": "2016-03-07T22:35:21", "url": "https://files.pythonhosted.org/packages/8d/d1/85517135bf268a4a2daecc55049dc9d0cf1796fd2b435c257eef4bef7a66/thimble-0.2.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "596c19b9ca34a932e5b6c87975d54124", "sha256": "eb0c6e728754444a962aa75fdc13856f5e34fa448a9f531a9e1ff4d40f7897d1" }, "downloads": -1, "filename": "thimble-0.2.0.tar.gz", "has_sig": false, "md5_digest": "596c19b9ca34a932e5b6c87975d54124", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8546, "upload_time": "2016-03-07T22:35:26", "url": "https://files.pythonhosted.org/packages/3a/9c/ef08fd1b2c1465323196098e91ceb5e8814358547e1bb263d403ce2baa32/thimble-0.2.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "272555042ad16b824d34b832e2a0adaa", "sha256": "0945674f15497f490b05bdefd197f2fd7a6071f6799ea4565f67e7e40e72a216" }, "downloads": -1, "filename": "thimble-0.2.0-py2-none-any.whl", "has_sig": false, "md5_digest": "272555042ad16b824d34b832e2a0adaa", "packagetype": "bdist_wheel", "python_version": "py2", "requires_python": null, "size": 11857, "upload_time": "2016-03-07T22:35:21", "url": "https://files.pythonhosted.org/packages/8d/d1/85517135bf268a4a2daecc55049dc9d0cf1796fd2b435c257eef4bef7a66/thimble-0.2.0-py2-none-any.whl" }, { "comment_text": "", "digests": { "md5": "596c19b9ca34a932e5b6c87975d54124", "sha256": "eb0c6e728754444a962aa75fdc13856f5e34fa448a9f531a9e1ff4d40f7897d1" }, "downloads": -1, "filename": "thimble-0.2.0.tar.gz", "has_sig": false, "md5_digest": "596c19b9ca34a932e5b6c87975d54124", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8546, "upload_time": "2016-03-07T22:35:26", "url": "https://files.pythonhosted.org/packages/3a/9c/ef08fd1b2c1465323196098e91ceb5e8814358547e1bb263d403ce2baa32/thimble-0.2.0.tar.gz" } ] }