{ "info": { "author": "Netsight Internet Solutions", "author_email": "dev@netsight.co.uk", "bugtrack_url": null, "classifiers": [ "Framework :: Plone :: 4.0", "Framework :: Plone :: 4.1", "Framework :: Plone :: 4.2", "Framework :: Plone :: 4.3", "Programming Language :: Python :: 2.7" ], "description": ".. image:: https://api.travis-ci.org/ploneintranet/experimental.securityindexing.png\n :target: https://travis-ci.org/ploneintranet/experimental.securityindexing\n\n.. image:: https://coveralls.io/repos/ploneintranet/experimental.securityindexing/badge.png\n :target: https://coveralls.io/r/ploneintranet/experimental.securityindexing\n\n=============================\nexperimental.securityindexing\n=============================\n\nDescription\n===========\nThis package aims to address a long-standing performance issue in Plone: \n\n Under circumstances which require security for an object to be re-indexed, \n for example, when adding roles to users or groups via the @@sharing view,\n the object for which the sharing form is being used and all of its decendant objects\n in the content tree are unconditionally fetched from the database (ZODB) and\n their security attributes (allowedRolesAndUsers) are re-indexed.\n\n This can yield terrible performance for some sites, depending upon the size (number of objects),\n and workflow complexity.\n\n\nInstallation\n============\nTo install this package, add ``experimental.securityindexing`` to your Plone sites'\neggs and re-run buildout:\n\n.. code-block: ini\n\n [buildout]\n ...\n eggs += experimental.securityindexing\n\n\nTesting it out\n--------------\nThis package provides some rudementry benchmarks which are aimed to be a sanity test\nanswering the question:\n\n \"Are we at least faster than the previous implementation by default?\"\n\nThese benchmarks should not be treated as authorative, nor indicative of the performance\nyou should expect on a real site.\n\nTo do so, the best way to ascertain results is to install the package in a development/staging \nversions of your site aginst some realistic data.\n\n\nInstallation is as above, but add the extras ``[benchmarks,tests]``:\n\n.. code-block: ini\n\n [buildout]\n ...\n eggs += experimental.securityindexing [benchmarks,test]\n\nPlease read the `benchmark docs`_ for details.\n\n\nExisting behaviour in Plone 4.x sites\n=====================================\nWhen local roles are assigned to user on a given folderish content item, \nthe folder will be indexed and all of it's descendants (child folders) -\nunconditionally.\n\nDepending upon the combination of:\n\n * The structure of the tree\n\n * The number of descendant content items (depth and breath of the sub-tree\n \"beneath\" the object being edited)\n\nThis behaviour is currently implemented twice (Dexterity and Archetypes),\nby the method `reindexObjectSecurity`. This method invoked on the context \nthat local roles are being manipulated upon, in order to reflect the changes in the \n`allowedRolesAndUsers` `Keywordindex` in the `ZCatalog`.\n\nThe `allowedRolesAndUsers` index is used in Plone to determine which content a user can see.\ne.g: \n\n In the site search\n \nWithin a Plone 4.x site, the two implementations of the `reindexObjectSecurity` API are: \n\n - Products.CMFCore.CMFCatalogAware.CatalogAware.reindexObjectSecuity(skip_self=False):\n Indexes the content item (self). The keyword parameter skip_self \n will be False when invoked from the @@sharing action.\n For each child node in the content tree \"beneath\" this content item, \n fetch that object, ultimately via the ZCatalog.unrestrictedTraverse API, \n and re-index each one, unconditionally.\n \n - Products.Archetypes.CatalogMultiplex.CatalogMultiplex \n The archetypes tool is used to look up all catalogs that have \n been registered for the `meta_type` of the content item (self).\n\nN.B Both these implementations implement the Products.CMFCore.interfaces.ICatalogAware\n interface.\n\nThe expensive operations seem to be:\n\n 1. \"Waking up\" each child node via `unrestrictedTraverse`\n\n 2. When any local roles of significance are assigned to the object,\n the indexer for local roles (Products.CMFPlone.CatalogTool.allowedRolesAndUsers) \n invokes Products.PlonePAS.plugins.local_roles.LocalRolesManager.getAllLocalRolesInContext API,\n which performs the following algorithm for each object to be indexed:\n \n 1. Acquire the inner context.\n\n 2. acquire the content object and it's parent.\n and calculate the unique set of local roles for the content object.\n\n 3. If __ac_block_local_roles__ is not set, exit and returns the local roles calculated.\n\n 4. Repeats 2. until a parent is None (root of the tree).\n \n\nThe goals of any solution to address the previously described performance issue(s) are:\n \n 1. Wake up as few objects as possible.\n\n 2. Where local roles information has not changed, avoid re-indexing.\n\nThe following scheme was envisioned to optimise the above algorithm:\n\n 1. When an object is indexed for the first time `CatalogTool.indexObject`,\n persist a unique token representing the unique set of local roles and the __ac_local_roles_block__\n flag, along with the object's id and physical path in a \"shadow tree\" which has\n the same form as the main content tree (ZODB).\n \n 2. Avoid re-indexing where possible, avoid waking up content objects:\n \n 2.1 Given an item of content `obj`, determine the set of child objects that need to be re-indexed,\n retrieve the node corresponding to the `obj` from the shadow tree, and each node representing \n `obj`'s corresponding descendants, and group these nodes by the unique local roles. \n \n 2.2 For each group of nodes, retrieve the content object corresponding to the first node in the group.\n \n 2.3 Ask the first object for it's `allowedRolesAndUsers` (aka local roles)\n \n 2.4 Index each node in group, supplying a faux object (either the shadow node or some other \n object standing-in for the content object)\n\nCredit\n======\nThis work has been done as part of the `Plone Intranet project`_. \nWork sponsored by `Netsight Internet Solutions`_.\n\n\n.. _`Netsight Internet Solutions`: http://www.netsight.co.uk\n.. _`Plone Intranet project`: http://github.com/ploneintranet\n.. _`benchmark docs`: docs/benchmarks.rst\n\n\n=========\nChangelog\n=========\n\n0.6 (2014-06-04)\n================\n\n- Nothing changed yet.\n\n\n0.5 (2014-06-04)\n================\n\n- Nothing changed yet.\n\n\n0.4 (2014-06-04)\n================\n - Fix versioning metadata, bumped version for new release.\n\n0.2 (2014-06-04)\n================\n - Corrected package metadata.\n - Update README.rst to remove wrongly named branch in badge urls.\n - Control panel configlet for synchronising/view state of shadowtree.\n - Use itertools to group nodes\n - The shadowtree tool is now a site-local tool (but managed by a global utility)\n - Add functional tests\n\n0.2dev (unreleasd)\n==================\n\n0.1dev (unreleasd)\n==================\n\n0.1 (2014-05-16)\n================\n - Initial pypi release.\n\n0.1 (2014-05-16)\n================\n - Initial pypi release.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://github.com/ploneintranet/experimental.securityindexing", "keywords": null, "license": "GPLv2", "maintainer": null, "maintainer_email": null, "name": "experimental.securityindexing", "package_url": "https://pypi.org/project/experimental.securityindexing/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/experimental.securityindexing/", "project_urls": { "Download": "UNKNOWN", "Homepage": "https://github.com/ploneintranet/experimental.securityindexing" }, "release_url": "https://pypi.org/project/experimental.securityindexing/0.6/", "requires_dist": null, "requires_python": null, "summary": "Optimises indexing of object security for a Plone site.", "version": "0.6" }, "last_serial": 1113682, "releases": { "0.1": [ { "comment_text": "", "digests": { "md5": "9f9ba6578f2e9a3f97ad09659cd730d7", "sha256": "2693a000585558f5f7fabe3da38a9733164b4fc49543fd6498bcf712d12c069b" }, "downloads": -1, "filename": "experimental.securityindexing-0.1.zip", "has_sig": false, "md5_digest": "9f9ba6578f2e9a3f97ad09659cd730d7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 41091, "upload_time": "2014-05-16T14:28:10", "url": "https://files.pythonhosted.org/packages/0e/f6/2ebd0b4d06e8d54603d5b3e51e2e773ddfeb9aeeee69173153c5d18e7466/experimental.securityindexing-0.1.zip" } ], "0.2": [ { "comment_text": "", "digests": { "md5": "bd47b363c749c3e10a1c261020270720", "sha256": "4c2149a504edc2fd197047879ebac88ff4b5b88fc86480840661e2a76a230284" }, "downloads": -1, "filename": "experimental.securityindexing-0.2.zip", "has_sig": false, "md5_digest": "bd47b363c749c3e10a1c261020270720", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 192560, "upload_time": "2014-06-03T15:18:41", "url": "https://files.pythonhosted.org/packages/ef/91/dd8a97550f8809c648b97cf4080e7bf673a8e180a849fecfa8e8fe257b31/experimental.securityindexing-0.2.zip" } ], "0.2dev": [], "0.3": [], "0.4": [ { "comment_text": "", "digests": { "md5": "b805470d2151a954df8c2c9ec8288c1f", "sha256": "9989f19961f146cea8f140068765bbe9a04b08755f1f7e1a22509b8fb670bb57" }, "downloads": -1, "filename": "experimental.securityindexing-0.4.zip", "has_sig": false, "md5_digest": "b805470d2151a954df8c2c9ec8288c1f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 161510, "upload_time": "2014-06-04T10:54:20", "url": "https://files.pythonhosted.org/packages/68/61/76ca0b04d17107397386e2cc2b57c19e5638dd287b0f07aba65bf9bf7a8f/experimental.securityindexing-0.4.zip" } ], "0.5": [], "0.6": [ { "comment_text": "", "digests": { "md5": "bcda09e8993fbcb6a5488d86dec8141b", "sha256": "899450c4abb0ad2f80cbdfceef7f089a80ee1ee7fbc4ba706f01817b06a833e5" }, "downloads": -1, "filename": "experimental.securityindexing-0.6.zip", "has_sig": false, "md5_digest": "bcda09e8993fbcb6a5488d86dec8141b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51859, "upload_time": "2014-06-04T13:20:57", "url": "https://files.pythonhosted.org/packages/19/35/14e52eaa8ff714b62c741fa8ba0dd66b871a6f2f80666c84933572fc042d/experimental.securityindexing-0.6.zip" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "bcda09e8993fbcb6a5488d86dec8141b", "sha256": "899450c4abb0ad2f80cbdfceef7f089a80ee1ee7fbc4ba706f01817b06a833e5" }, "downloads": -1, "filename": "experimental.securityindexing-0.6.zip", "has_sig": false, "md5_digest": "bcda09e8993fbcb6a5488d86dec8141b", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 51859, "upload_time": "2014-06-04T13:20:57", "url": "https://files.pythonhosted.org/packages/19/35/14e52eaa8ff714b62c741fa8ba0dd66b871a6f2f80666c84933572fc042d/experimental.securityindexing-0.6.zip" } ] }