<?xml version="1.0"?>
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
         xmlns:dc="http://purl.org/dc/elements/1.1/"
         xmlns:syn="http://purl.org/rss/1.0/modules/syndication/"
         xmlns="http://purl.org/rss/1.0/">




    



<channel rdf:about="http://www.jarn.com/blog/blog-feed/RSS">
  <title>Jarn Blog</title>
  <link>http://www.jarn.com</link>
  
  <description>
    
       News, happenings and rants from the Jarn team.  
       
  </description>



  
  
            <syn:updatePeriod>daily</syn:updatePeriod>
            <syn:updateFrequency>1</syn:updateFrequency>
            <syn:updateBase>2007-08-20T10:53:11Z</syn:updateBase>
        
  
  <image rdf:resource="http://www.jarn.com/logo.jpg"/>

  <items>
    <rdf:Seq>
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/plone-cathedral-sprint-after-action-report"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/linguaplone-3.0"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/jarn-pledges-super-effort-for-the-22nd-plone-tune-up"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/faster-memcachedmanager"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/berlinale-sprint-2009"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/plone-performance-sprint-bristol-2008"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/saving-the-day-recovering-lost-objects"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/listening-for-signals-from-dead-zopes"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/catalog-query-plan"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/plone-indexing-performance"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/explore-portlet"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/getting-rid-of-redundant-reindexing"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/membrane-performance"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/plone-2-5-performance"/>
        
        
            <rdf:li rdf:resource="http://www.jarn.com/blog/announcing-plone-enterprise-forum"/>
        
    </rdf:Seq>
  </items>

</channel>

    <item rdf:about="http://www.jarn.com/blog/plone-cathedral-sprint-after-action-report">        <title>Plone Cathedral sprint after-action report</title>        <link>http://www.jarn.com/blog/plone-cathedral-sprint-after-action-report</link>        

<description>            

 Short report from the Plone 4.0 and 4.1 Cathedral sprint in Cologne, Germany.  
 
&lt;p&gt;A small delegation from Jarn, Denys Mishunov, our German freelancers Tom Lazar and Andreas Zeidler, and myself, participated in the Cathedral Sprint in Cologne, Germany, March 15-19 2010, generously sponsored and hosted by &lt;a class="external-link" href="http://www.gfu.net/"&gt;GfU Cyrus AG&lt;/a&gt;. We had a great time, a week with awesome Plone people, great mindshare, wonderful productivity and German hospitality, food and beer.&lt;/p&gt;
&lt;p&gt;The sprint focused on features and finishing for the upcoming Plone 4 and 4.1 releases and saw incredible results in the 5 days of hard work from 25 sprinters.&lt;/p&gt;
&lt;p&gt;&lt;img class="image-left" src="../images/cathedralsprinters/image_preview" alt="Cathedralsprinters" /&gt;&lt;/p&gt;
&lt;p style="clear: left;" class="discreet"&gt;Photo © Armin

 Carl Stroß-Radschinski.&lt;/p&gt;
&lt;p&gt;Here are some highlights based on &lt;a class="external-link" href="http://www.acsr.de/archive/plone-cathedral-sprint-in-koln-war-extrem-produktiv"&gt;Armin Carl Stroß-Radschinski's sprint summary in German&lt;/a&gt;, generously translated to English by &lt;a class="external-link" href="http://www.matthewwilkes.co.uk/"&gt;Matthew Wilkes&lt;/a&gt; and crippled for brevity by me. Read the &lt;a class="external-link" href="http://www.acsr.de/archive/plone-cathedral-sprint-in-koln-war-extrem-produktiv-en"&gt;original summary (english) for more details here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Results&lt;br /&gt;&lt;/h2&gt;
&lt;p&gt;I have tried listing some of the achievements from the sprint — beyond getting to spend time with the best Open Source community on the planet. I apologize for any names or features i have missed (and i'll be happy to take corrections).&lt;/p&gt;
&lt;h3&gt;Reimplementation of Plone collections &lt;br /&gt;&lt;/h3&gt;
&lt;p class="discreet"&gt;Eric Steele, Matthew Wilkes, Roel Bruggink, Maarten Kling, Ralph Jacobs , Rob Gietema, Martijn Jacobs and Geir Bækholt&lt;/p&gt;
&lt;p&gt;Collections in Plone are saved searches with complex criteria whose results are shown with a given ordering. The improvements to the interface of these 'smart folders', which will also apply to searches, has made their usage significantly more intuitive.&lt;br /&gt;The interface for entering search criteria shows search results in live time as the query is edited, in the same way as the Live-Search feature does for simple searches in Plone 3. More criteria can be added step-by-step to narrow the search even further. The results are updated real-time for instant user feedback.&lt;a class="external-link" href="http://blip.tv/file/3367082/"&gt;&lt;br /&gt;&lt;img class="image-inline" src="../images/film-icon/image_icon" alt="film icon" /&gt; Screencast of the new collections&lt;/a&gt;&lt;/p&gt;
&lt;h3 style="clear: left;"&gt;Search improvements&lt;/h3&gt;
&lt;p class="discreet"&gt;Denys Mishunov, Israel Saeta Pérez, Nejc Zupan&lt;/p&gt;
&lt;p&gt;Great improvements to search results display, and a new, improved advanced search form with instant Ajax gratification.&lt;br /&gt;&lt;a class="external-link" href="http://blip.tv/file/3367086/"&gt;&lt;img class="image-inline" src="../images/film-icon/image_icon" alt="film icon" /&gt; Screencast on search improvements&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Event upgrades&lt;/h3&gt;
&lt;p class="discreet"&gt;Andreas Jung, Vincent Fretin, Johannes Raggam, Tom Gross and Rodrigo Ristow&lt;/p&gt;
&lt;p&gt; Further improvements to the plone calendaring system, incorporating features like new (i18n) widget, full-day-events, recurring events, iCal export and more.&lt;br /&gt;&lt;a class="external-link" href="http://blip.tv/file/3362551/"&gt;&lt;img class="image-inline" src="../images/film-icon/image_icon" alt="film icon" /&gt; Screencast of event improvements&lt;/a&gt; or r&lt;a class="external-link" href="http://www.zopyx.de/blog/plone.app.event"&gt;ead more at Andreas Jung's blog. &lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Content Browsing&lt;br /&gt;&lt;/h3&gt;
&lt;p class="discreet"&gt;Robert Niederreither&lt;/p&gt;
&lt;p&gt;A new Java-Script based interface for fast and efficient navigation of the content structure of a site. The view, based on the split-pane view of MacOSX's finder is, through direct queries to the Plone catalogue, extremely fast compared to the conventional method of loading each new page in turn, and is displayed using a CSS overlay.&lt;br /&gt;The new interface can be called up from any page in the site - you immediately get an overview of the viewed content's context.&lt;br /&gt;&lt;a class="external-link" href="http://www.zope.de/redaktion/dzug/nachrichten/plone-cathedral-sprint-ein-finder-fuer-plone"&gt;&lt;img class="image-inline" src="../images/film-icon/image_icon" alt="film icon" /&gt; Screencast of Plone Finder&lt;br /&gt;German article from Jan
 Ulrich Hasecke &lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;New content migration strategy for Plone 4&lt;/h3&gt;
&lt;p class="discreet"&gt;Tom Lazar and Carsten Senger&lt;/p&gt;
&lt;p&gt;A combination of Plone 3 and Plone 4 extensions that use the content migration pipelines from Transmogrifier. With this the content of an existing site can be exported in a Plone-version agnostic form and then reconstructed in a fresh Plone 4 instance.&lt;/p&gt;
&lt;h3&gt;Translations&lt;/h3&gt;
&lt;p class="discreet"&gt;Jan Ulrich Hasecke, Martijn Schenk&lt;/p&gt;
&lt;p&gt;German and Dutch Translations for Plone 4&lt;/p&gt;
&lt;h3&gt;Plone Discussions&lt;/h3&gt;
&lt;p class="discreet"&gt;Timo Stollenwerk and Florian Friesdorf&lt;/p&gt;
&lt;p&gt;The new commenting engine for Plone, with moderation and other useful improvements.&lt;a class="external-link" href="http://blip.tv/file/3365701/"&gt;&lt;br /&gt;&lt;img class="image-inline" src="../images/film-icon/image_icon" alt="film icon" /&gt; Screencast of Plone discussions&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Performance / image scales&lt;br /&gt;&lt;/h3&gt;
&lt;p class="discreet"&gt;Andreas Zeidler,Simon Pamies&lt;/p&gt;
&lt;p&gt;Performance improvements including handling of image data and a complete revamp of image scales.&amp;nbsp;&lt;/p&gt;
&amp;nbsp;
&lt;p&gt;For more info on the sprint, &lt;a class="external-link" href="http://www.hasecke.com/nachrichten/plone-cathedral-sprint-2013-personal-wrap-up"&gt;Jan Ulrich Hasecke has also written a good personal summary of events&lt;/a&gt; while &lt;a class="external-link" href="http://www.flickr.com/photos/12317756@N08/sets/72157623659097492/"&gt;Armin
 Carl Stroß-Radshinski has posted a lot of photos from the sprint on Flickr&lt;/a&gt;.&lt;/p&gt;
-- &lt;a class="external-link" href="../people/baekholt"&gt;&lt;br /&gt;Geir Bækholt&lt;/a&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;a class="external-link" href="http://www.flickr.com/photos/12317756@N08/sets/72157623659097492/"&gt;&lt;img class="image-left" src="http://farm5.static.flickr.com/4068/4460527505_f2e2d72c24.jpg" alt="Cathedralsprinters in action" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style="clear: left;" class="discreet"&gt;Photo © Armin

 Carl Stroß-Radschinski.&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Geir Bækholt
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2010-03-26T21:58:27Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/linguaplone-3.0">        <title>LinguaPlone 3.0</title>        <link>http://www.jarn.com/blog/linguaplone-3.0</link>        

<description>            

 After one year of work a new final LinguaPlone release is out. 
 
&lt;p&gt;&lt;img title="Norden och EU - by Johannes Jansson/norden.org" class="image-right" src="../images/norden-och-eu/image_mini" alt="Norden och EU - by Johannes Jansson/norden.org" /&gt;After more than a year of work, we released a new final version of LinguaPlone a couple of days ago. LinguaPlone is the multi-lingual solution for Plone.&lt;/p&gt;
&lt;p&gt;While we have released many preview releases over the last months, we'd like to take the final release as an opportunity to give an overview of all the work.&lt;/p&gt;
&lt;p&gt;Note that LinguaPlone 3.0 only works with Plone 3.3 and the upcoming 4.0. The Plone 4.0 support is still preliminary, as Plone itself is still in early alpha stages. If you use an older Plone 3 release, you will need to use LinguaPlone 2.4 or upgrade your Plone version.&lt;/p&gt;
&lt;p&gt;Upgrading from earlier versions of LinguaPlone to the new 3.0 release requires an upgrade. Please visit the Add-on products control panel and execute the upgrade for LinguaPlone. Note that this requires a full catalog update and can take a substantial amount of time depending on the amount of content in your site.&lt;/p&gt;
&lt;p&gt;The following list gives a summary of the main changes in 3.0. A full list of all changes can be found on the &lt;a class="external-link" href="http://pypi.python.org/pypi/Products.LinguaPlone#changelog"&gt;product page&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Performance&lt;/h3&gt;
&lt;p&gt;We substantially increased performance most notably in large sites. There's a huge number of internal technical changes mostly related to the use of the Archetypes reference engine. These improve both general rendering time of all pages as well as content editing operations. LinguaPlone will now use the catalog much more effectively and require less objects to be loaded from the database.&lt;/p&gt;
&lt;h3&gt;Multi-lingual references&lt;/h3&gt;
&lt;p&gt;So far reference fields or references in general haven't been&amp;nbsp;multi-lingual aware.&lt;/p&gt;
&lt;p&gt;Imagine creating a page at /source and one at&amp;nbsp;/target. Now add "target" as a related item to "source". If you translate both pages into German, you end up with /source-de and /target-de. But "source-de" would point to "target" as a related item and not "target-de".&lt;/p&gt;
&lt;p&gt;The same problem occurs if you use the visual editors "link by UID" feature and have links inside the body text of your pages.&lt;/p&gt;
&lt;p&gt;In LinguaPlone 3.0 these references now point to the expected target. So "source-de" points to "target-de" if "target-de" exists. If the target is not translated into the translations language, the reference points to the target in the source language.&lt;/p&gt;
&lt;p&gt;This behavior applies to all reference fields marked as language neutral.&lt;/p&gt;
&lt;h3&gt;Updated language selector&lt;/h3&gt;
&lt;p&gt;LinguaPlone's language selector has been updated considerably. Both using language names and flags are supported, using names per default.&amp;nbsp;The names are now always in the native language. So you'll see "English", "Deutsch", "Norsk" and no longer English only names.&lt;/p&gt;
&lt;p&gt;When switching languages the current context will be preserved as much as possible. This includes proper handling of default pages, different views and query string arguments.&lt;/p&gt;
&lt;p&gt;If the current content item has no translation into the desired language, it will try to find the "nearest" translation in the hierarchy, instead of staying at the current page.&lt;/p&gt;
&lt;p&gt;A new content language selector is enabled by default, which ensures that the UI language always reflects the language of the content item.&lt;/p&gt;
&lt;h3&gt;Editing&lt;/h3&gt;
&lt;p&gt;The "Translate into" menu no longer contains an entry pointing to the language control panel. The entry has repeatedly been mistaken as affecting the individual page, instead of the entire site. The control panel is now only available from the site setup screens (already in 2.4).&lt;/p&gt;
&lt;p&gt;The split-screen translation edit view hides the right column, giving more space for the actual content editing. The behavior can be turned off via a setting in portal_properties.&lt;/p&gt;
&lt;p&gt;Language independent fields are shown in view mode in the translate edit screens. This prevents editors from mistakenly changing these fields affecting the canonical and all translations (already in 2.2).&lt;/p&gt;
&lt;p&gt;The metadata language in the edit screens only shows the supported languages in the site. So far you could accidentally change a content item to an unsupported language.&lt;/p&gt;
&lt;h3&gt;Technical changes&lt;/h3&gt;
&lt;p&gt;archetypes.schemaextender has been updated to seamlessly support LinguaPlone. Fully functioning support for language independent fields requires version 1.3 of schemaextender.&lt;/p&gt;
&lt;p&gt;The latest versions of plone.app.blob are fully multi-lingual aware. In standard LinguaPlone the content of language independent fields is copied to all translations, duplicating the entire data. Blobs are able to avoid this issue and share the same underlying blob data for all translations. So a large pdf document of 100mb will only be stored once in the blob storage on the filesystem, instead of once for each language in the ZODB.&lt;/p&gt;
&lt;p&gt;There's quite a number of internal changes, exposing various aspects of the translation logic as separate adapters or making certain features configurable via environment variables. A number of outdated code like the custom translation cache has been removed.&lt;/p&gt;
&lt;h3&gt;Contributions&lt;/h3&gt;
&lt;p&gt;Most of the work done by the Jarn team has been sponsored by the &lt;a class="external-link" href="http://www.norden.org/en/"&gt;Nordic Council and Nordic Council of Ministers&lt;/a&gt;. Many thanks to the organization and the communications department in particular.&lt;/p&gt;
&lt;p&gt;Significant contributions have been made by Jens Klein helping with the dark corners of the Archetypes reference engine and by Maurits van Rees helping with Plone 4.0 compatibility.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;We have many more improvements planned for LinguaPlone in the coming months. Stay tuned while Plone's multi-lingual support gets even better.&lt;/p&gt;
&lt;p&gt;&lt;a class="external-link" href="../people/hanno"&gt;Hanno Schlichting&lt;/a&gt;, Jarn AS&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Hanno Schichtling
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2009-12-23T18:05:41Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/jarn-pledges-super-effort-for-the-22nd-plone-tune-up">        <title>Jarn pledges 30 man-hours for the 22nd Plone tune-up! </title>        <link>http://www.jarn.com/blog/jarn-pledges-super-effort-for-the-22nd-plone-tune-up</link>        

<description>            

  
 
&lt;p&gt;&lt;img class="image-right" src="../images/sledgehammer/image_mini" alt="Sledgehammer" /&gt;Plone Tune-Ups are regular online events that aim at addressing tickets in the Plone issue tracker and advancing the Plone open source Content Management System in general.&lt;/p&gt;
&lt;p&gt;For the &lt;a class="external-link" href="http://plone.org/events/plone-tuneups/tuneup-22"&gt;22nd Tune-Up&lt;/a&gt; the tune-up-team is asking Plone companies to pledge development time to make a huge push forward in bugfixing and also boost participation in general.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The Jarn team of employees and freelancers makes an extra effort and pledges 30 man-hours of expert, veteran Plone developer time!&amp;nbsp;&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Helge Tesdal&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Martin Opstad Reistadbakk&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Martijn Pieters&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Geir Bækholt&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Andreas Zeidler&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Stefan Holek&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span class="Apple-style-span"&gt;Florian Schulze&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;From &lt;a class="external-link" href="http://plone.org/events/plone-tuneups/tuneup-22"&gt;friday morning (October 23rd 2009)&lt;/a&gt; Central European Time we will be working on plone-bugs in the #plone-tuneup channel on the freenode irc network.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;Join us!&lt;/p&gt;
&lt;p&gt;Geir Bækholt, Jarn&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Geir Bækholt
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2009-10-22T16:48:16Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/faster-memcachedmanager">        <title>Faster MemcachedManager</title>        <link>http://www.jarn.com/blog/faster-memcachedmanager</link>        

<description>            

 MemcachedManager goes to 11 with refactoring and pylibmc  
 
&lt;p&gt;&lt;a class="external-link" href="http://pypi.python.org/pypi/Products.MemcachedManager/"&gt;MemcachedManager&lt;/a&gt; enables Zope to cache data in one or more shared &lt;a class="external-link" href="http://www.danga.com/memcached/"&gt;memcached&lt;/a&gt; instances instead of in memory in each Zope process. This provides a reasonable tradeoff between added overhead and memory consumption. So far, we have been using python-memcached as a library for talking to memcached. python-memcached is compact and convenient, but can never compete with C-based libraries on speed.&lt;/p&gt;
&lt;h3&gt;pylibmc&lt;/h3&gt;
&lt;p&gt;While &lt;a class="external-link" href="http://gijsbert.org/cmemcache/"&gt;cmemcache&lt;/a&gt; never really took off as a memcached library for python, &lt;a class="external-link" href="http://lericson.blogg.se/code/category/pylibmc.html"&gt;Ludvig Ericson&lt;/a&gt; has now made &lt;a class="external-link" href="http://pypi.python.org/pypi/pylibmc"&gt;pylibmc&lt;/a&gt; which is a wrapper around &lt;a class="external-link" href="http://tangent.org/552/libmemcached.html"&gt;libmemcached&lt;/a&gt;, and promises significant speedups.&lt;/p&gt;
&lt;h3&gt;&lt;img class="image-right" src="../images/memcachedmanager-and-pylibmc/image_preview" alt="MemcachedManager and pylibmc" /&gt;Improving MemcachedManager&lt;/h3&gt;
&lt;p&gt;As we tested pylibmc and the retrieval of data had become significantly faster, it became obvious that some profiling and improvements to MemcachedManager itself was appropriate. The changes was mainly to &lt;a class="external-link" href="http://dev.plone.org/collective/changeset/82120"&gt;remove unused code and avoid unnecessary invocation of DateTime&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Testing the improvements&lt;/h3&gt;
&lt;p&gt;We set up two tests. The first one is synthetic and returns a list of 25 dictionaries, each dictionary containing 3 elements with Title, Description and url. This is similar to caching a content listing, and it also uses pickling which adds some overhead but will usually be used when caching anything in Zope. The cached script was then called 1001 times from another script, for a total of 4004 calls to get content from memcached.&lt;/p&gt;
&lt;p&gt;python-memcached and MemcachedManager 1.0rc1 took 1382m. When applying the MemcachedManager improvements, that time went down to 1014ms, and adding pylibmc to the mix gave a result of 812ms.&lt;/p&gt;
&lt;p&gt;The second test is for a development site with plenty of content and Membrane based users. Membrane is mainly used for caching user info, which are rather largeish and complex objects. Viewing a page 10 times gave 620 calls to get content from memcached.&lt;/p&gt;
&lt;p&gt;python-memcached and MemcachedManager 1.0rc1 took 789ms for those 620 calls, the improved MemcachedManager gave a barely noticeable improvement of 707ms, while pylibmc got a chance to really shine and only took 355ms.&lt;/p&gt;
&lt;h3&gt;Test for yourself&lt;br /&gt;&lt;/h3&gt;
&lt;p&gt;The improvements to MemcachedManager have been released as 1.0rc2. If you want to compile pylibmc with Python 2.4, you have to apply a patch and point to the correct libraries and include files. We have created a buildout for your convenience.&lt;/p&gt;
&lt;pre&gt;svn co http://svn.plone.org/svn/collective/Products.MemcachedManager/buildouts/pylibmc pylibmc
cd pylibmc
python bootstrap.py
bin/buildout&lt;/pre&gt;
&lt;p&gt;Then you have to start memcached with&lt;/p&gt;
&lt;pre&gt;bin/memcached&lt;/pre&gt;
&lt;p&gt;and start zope like you're used to.&lt;/p&gt;
&lt;p&gt;MemcachedManager is available as a type in the ZMI, and can be used as a drop in replacement for RAMCache.&lt;/p&gt;
&lt;p&gt;-- Helge Tesdal&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Helge Tesdal
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2009-03-25T12:50:10Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/berlinale-sprint-2009">        <title>Berlin(ale) Sprint 2009</title>        <link>http://www.jarn.com/blog/berlinale-sprint-2009</link>        

<description>            

 Spent your 10% time with us in Berlin! 
 &lt;img title="Berlin TV tower" style="padding: 0pt 0pt 1em 1em; float: right;" src="berlin-tv-tower/image_preview" alt="Berlin TV tower" height="400" width="162" /&gt;
&lt;p&gt;Ever since Jarn — or rather Plone Solutions at the time — &lt;a class="external-link" href="the-10-plone-manifesto"&gt;declared the 10% Manifesto&lt;/a&gt;, setting aside time to work on Plone while not interfering with ongoing projects has been somewhat tricky. Many times 10% time ended up being deferred or piled up over time. Of course, another reason for this was that projects at Jarn are usually a challenging and fun thing to do. So spending time on Plone all by yourself sometimes just didn't seem as appealing as working on things together with your team mates.&lt;/p&gt;
&lt;p&gt;Overall following up on the 10% Manifesto didn't quite work as we had hoped for. So we came up with another approach: accumulate time and then once in a while schedule a few days together in order to work on and improve Plone. In other words: sprint! We also decided it would be even more fun to invite people to stop by and join in. That is, have small but &lt;a class="external-link" href="http://plone.org/events/sprints"&gt;proper Plone sprints&lt;/a&gt; instead of just internal ones.&lt;/p&gt;
&lt;p&gt;And here we go: the first one will be held in the somewhat &lt;a class="external-link" href="http://maps.google.com/maps/ms?ie=UTF8&amp;amp;hl=en&amp;amp;msa=0&amp;amp;ll=52.492511,13.42355&amp;amp;spn=0.000908,0.001776&amp;amp;t=h&amp;amp;z=19&amp;amp;msid=108583178989000445492.00046162eba6239e437c7"&gt;semi-official new Jarn office&lt;/a&gt; in Berlin. Actually it's just a shared office space where everybody happens to work for Jarn most of their time, but that's another story.&lt;/p&gt;
&lt;p&gt;The first Jarn 10% Sprint will run February 9th—11th, in Berlin Neukölln. Not quite accidentally it was scheduled in parallel with the Berlinale Film Festival and hence dubbed "Berlin(ale) Sprint". That's also the reason&amp;nbsp;&lt;a class="external-link" href="http://www.openplans.org/projects/berlinale-sprint/participants"&gt;most of the sprinters will arrive a bit earlier&lt;/a&gt;...&lt;/p&gt;
&lt;p&gt;So if you happen to be in the area, or if you want to follow up this year's UI sprint in Baarn with some actual coding :) — not to mention having cake &amp;amp; coffee on top of &lt;a class="external-link" href="http://en.wikipedia.org/wiki/Fernsehturm"&gt;Berlin's TV tower&lt;/a&gt;, &lt;a class="external-link" href="http://play-berlin.de/"&gt;playing games&lt;/a&gt; and taking a tour of some of our favourite pubs — &lt;a class="external-link" href="http://www.openplans.org/projects/berlinale-sprint/"&gt;let us know&lt;/a&gt; and join the fun!&lt;/p&gt;
&lt;p&gt;-- Andreas Zeidler, Tom Lazar and Stefan Holek&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Andreas Zeidler
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                    <dc:subject>Blog</dc:subject>                    <dc:subject>Plone</dc:subject>                    <dc:subject>Jarn</dc:subject>                <dc:date>2009-01-26T18:50:34Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/plone-performance-sprint-bristol-2008">        <title>Plone performance sprint bristol 2008</title>        <link>http://www.jarn.com/blog/plone-performance-sprint-bristol-2008</link>        

<description>            

 A summary of the performance sprint in Bristol, 2008 
 
&lt;p&gt;It's been some time since the performance sprint in Bristol now, but it certainly deserves a summary.&lt;/p&gt;
&lt;h3&gt;&lt;img class="image-right" src="../images/castle-park-bristol/image_mini" alt="Castle Park, Bristol" /&gt;Location&lt;/h3&gt;
&lt;p&gt;Turns out Bristol is a great city with a wonderful atmosphere. There is plenty of history and old buildings (unlike in Norway). Netsight also picked a great location for the sprint, and provided plenty of refreshments to keep the geeks doing long days.&lt;/p&gt;
&lt;h2&gt;&lt;a class="external-link" href="http://www.openplans.org/projects/plone-performance-sprint-2008/topics"&gt;Sprint topics&lt;/a&gt;&lt;/h2&gt;
&lt;h3&gt;Automated performance tests&lt;/h3&gt;
&lt;p&gt;The most important result from the performance sprint is probably the &lt;a class="external-link" href="http://www.openplans.org/projects/plone-performance-sprint-2008/standard-performance-scalability-test-suite-buildout"&gt;automated funkload tests&lt;/a&gt;. In Copenhagen in 2007 we looked into using JMeter, but it was too much hassle to work with, and we didn't get beyond creating some &lt;a class="external-link" href="http://dev.plone.org/collective/browser/JMeterTestPlans/trunk"&gt;test plan templates&lt;/a&gt; for Plone.&lt;/p&gt;
&lt;p&gt;With &lt;a class="external-link" href="http://dev.plone.org/collective/browser/collective.loadtesting"&gt;collective.loadtesting&lt;/a&gt; we have something that is a lot easier to set up and use in a buildout, and we can have daily performance runs and keep track of the general performance of Plone (although it doesn't seem to be set up yet). This means we can easily and immediately spot changes that affect performance in a negative way, and make informed decisions whether the advantages of functionality or code changes is worth the performance loss.&lt;/p&gt;
&lt;h3&gt;Instrumentation&lt;/h3&gt;
&lt;p&gt;&lt;a class="external-link" href="http://www.openplans.org/projects/plone-performance-sprint-2008/instrumentation-zodb-transactions-and-catalogging"&gt;Instrumentation&lt;/a&gt; was the other important topic at the sprint. We always need more performance data, more accurate information, and better ways of presenting that data to enable us to understand and improve the system we're profiling.&lt;/p&gt;
&lt;p&gt;Enter &lt;a class="external-link" href="http://pypi.python.org/pypi/mr.bent/"&gt;mr.bent&lt;/a&gt;. Mr. Bent &lt;a class="external-link" href="http://wiki.lspace.org/wiki/Mavolio_Bent"&gt;knows his numbers&lt;/a&gt;, and is a framework for allowing profile data to be collected in a Python
application and viewed at different logical levels.&lt;/p&gt;
&lt;p&gt;One example of usage is &lt;a class="external-link" href="http://dev.plone.org/collective/browser/collective.performancecolouriser"&gt;collective.performancecolouriser&lt;/a&gt; which enables the developer to visually see timing info for different page components by color.&lt;/p&gt;
&lt;h3&gt;ExtendedPathIndex refactoring&lt;/h3&gt;
&lt;p&gt;While the ExtendedPathIndex has worked quite well for a long time, the implementation was rather obtuse, or obfuscated if you like.&lt;/p&gt;
&lt;p&gt;Martijn Pieters has been planning a rewrite for quite some time, and at the sprint he finally had the opportunity to do so. He found several bugs in the old implementation, added tests and implemented all features for all scenarios, while also improving performance by being smarter about set operation ordering.&lt;/p&gt;
&lt;p&gt;The improvements were released as version &lt;a class="external-link" href="http://pypi.python.org/pypi/Products.ExtendedPathIndex/"&gt;2.5&lt;/a&gt;, and will be included in Plone at the earliest convenience.&lt;/p&gt;
&lt;h3&gt;Catalog&lt;/h3&gt;
&lt;p&gt;&lt;a class="external-link" href="http://pypi.python.org/pypi/experimental.catalogqueryplan"&gt;experimental.catalogqueryplan&lt;/a&gt; saw two improvements. The first one is faster set operations when intersecting a large and a small set. In Plone, especially with Membrane, there are some cases where you have a rather small result set from one index (like user or group ids) and a large result set from another (implemented interfaces or permissions). In those cases it is more efficient to check if the large set has a certain key by direct lookup than to scan all keys for a match. The size check is implemented in Python as a temporary monkeypatch used for the catalogqueryplan indexes, and gives a noticeable improvement. The exact improvement depends on whether all values in the small set are found at the beginning ('Low values' in graph) or end ('high values' in graph) of the large set. It might be as much as 20x faster to check for a key.&lt;/p&gt;
&lt;p&gt;&lt;img class="image-right" src="../images/intersection-performance/image_preview" alt="Intersection performance" /&gt;The graph shows the timing of an intersection between a set of 10000 items and a subset of 10 items, repeated 100 times. The green bar is the regular C implementation from IIBTree, the yellow bar is our python implementation using has_key with fallback to the C implementation, and the blue bar is using the builtin Python set (instead of the IISet from Zope).&lt;/p&gt;
&lt;p&gt;Inside the indexes, we now sort the sets on length when doing intersection operations, to use the smallest sets first. When doing OR operations, we use multiunion instead of several unions. This should be noticeable for the permissions index (allowedRolesAndUsers) for example.&lt;/p&gt;
&lt;p&gt;The improvements are released as version &lt;a class="external-link" href="http://pypi.python.org/pypi/experimental.catalogqueryplan/"&gt;1.1&lt;/a&gt;, and can easily be tested by including experimental.catalogqueryplan in your buildout.&lt;/p&gt;
&lt;p&gt;The second improvement is the inclusion of a new index. &lt;a class="external-link" href="http://dev.plone.org/collective/browser/Products.BooleanIndex/trunk"&gt;BooleanIndex&lt;/a&gt; is a simplified FieldIndex which only stores True values and ignores everything else. This will lower the object count slightly for indexes like default page and folderish and will enable the use of the intersection improvements for smaller sets. This only works as long as there are fewer True than False values indexed.&lt;/p&gt;
&lt;p&gt;-- Helge Tesdal&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Helge Tesdal
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2009-01-05T18:12:07Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/saving-the-day-recovering-lost-objects">        <title>Saving the day: recovering lost objects</title>        <link>http://www.jarn.com/blog/saving-the-day-recovering-lost-objects</link>        

<description>            

 When a customer discovers over a week later that an important object was accidentially deleted, what do you do? 
 &lt;h3&gt;Oh noes!&lt;/h3&gt;
&lt;p&gt;A customer discovered that an important entire section of his site was missing and asked us to bring it back. This was in a heavily edited site, with loads of writes each day, but we quickly located the offending transaction: someone had deleted the object in question 9 days earlier.&lt;/p&gt;
&lt;p&gt;Undo was no longer an option, though: too many things had changed, not least the catalog. Truncating the Data.fs (removing all transactions since, including the offending one) was not only undesirable, but impossible as the site stores the data in Oracle through &lt;a href="http://wiki.zope.org/ZODB/RelStorage"&gt;RelStorage&lt;/a&gt;.&lt;/p&gt;
&lt;img class="image-right" src="resolveuid/9bad330fe62bf3ce4053922ab7ce61ca" alt="Antique timepiece" /&gt;&lt;h3&gt;Time travel&lt;/h3&gt;
&lt;p&gt;So, instead of permanently removing transactions, we used a handy little package to do some time traveling: &lt;a href="http://pypi.python.org/pypi/zc.beforestorage"&gt;zc.beforestorage&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;zc.beforestorage&lt;/code&gt; does require a ZODB version 3.8 or 3.9; the customer installation is on Plone 3.0, so a newer ZODB3 egg was necessary for this operation. A small additional buildout configuration file (saved as beforestorage.cfg) helps out:&lt;/p&gt;
&lt;pre&gt;[buildout]&lt;br /&gt;extends =&lt;br /&gt;    buildout.cfg&lt;br /&gt;eggs +=&lt;br /&gt;    zc.beforestorage&lt;br /&gt;    ZODB3&lt;br /&gt;    zope.proxy&lt;br /&gt;&lt;br /&gt;[versions]&lt;br /&gt;ZODB3 = 3.8.1&lt;br /&gt;zope.proxy = 3.4.2&lt;br /&gt;&lt;br /&gt;[relstorage-patch]&lt;br /&gt;recipe = plone.recipe.command&lt;br /&gt;command = &lt;br /&gt;    cd ${buildout:eggs-directory}/ZODB3-3.8.1-py2.4-linux-i686.egg/ZODB&lt;br /&gt;    curl -s http://svn.zope.de/zope.org/relstorage/tags/1.1c1/poll-invalidation-1-zodb-3-8-0.patch | patch -N -p0&lt;br /&gt;    cd ${buildout:directory}&lt;br /&gt;update-command = ${relstorage-patch:command}&lt;br /&gt;&lt;br /&gt;[instance]&lt;br /&gt;zope-conf-additional +=&lt;br /&gt;    enable-product-installation False&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;relstorage-patch&lt;/code&gt; section in the above code ensures that our ZODB3 egg is patched with the RelStorage additions, and the zope.proxy egg is needed because ZODB 3.8 requires a newer version. The &lt;code&gt;enable-product-installation&lt;/code&gt; line is required because &lt;code&gt;zc.beforestorage&lt;/code&gt; puts your ZODB in read-only mode (understandibly); the option tells Zope not to try and write product information to the ZODB.&lt;/p&gt;
&lt;p&gt;Once buildout has been run with this configuration (with the &lt;code&gt;-c&lt;/code&gt; switch), you'll still need to edit the zope.conf file for your instance, usually in parts/instance/etc/zope.conf. You need to edit the &amp;lt;zodb_db main&amp;gt; section to wrap the storage in the beforestorage. Ours looked something like this:&lt;/p&gt;
&lt;pre&gt;&amp;lt;zodb_db main&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; # Main database&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; cache-size 650000&lt;br /&gt;%import zc.beforestorage&lt;br /&gt;%import relstorage&lt;br /&gt;    &amp;lt;before&amp;gt;&lt;br /&gt;    before 2008-12-08T10:29:03&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;relstorage&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;oracle&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; dsn RELSTORAGE_DSN&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; password xxxxxxxxx&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; user xxxxxxxx&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/oracle&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/relstorage&amp;gt;&lt;br /&gt;    &amp;lt;/before&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mount-point /&lt;br /&gt;&amp;lt;/zodb_db&amp;gt;&lt;/pre&gt;
&lt;p&gt;Any line with the word 'before' in it is new. The timestamp we learned from the undo log, simply converted to UTC. Now, when you start the instance, you are in the past. You can't alter this past (no killing of grandfathers), but you &lt;em&gt;can&lt;/em&gt; read it. And lo and behold, the deleted object is back.&lt;/p&gt;
&lt;h3&gt;Recovery&lt;/h3&gt;
&lt;p&gt;Now that we have found the lost object, we can recover it. We simply exported it; in the ZMI, choose the Export/Import button, and save the export on the server. Remove the zc.beforestorage configuration (just run buildout with your regular buildout file), restart, import the .zexp file, done!&lt;/p&gt;
&lt;p&gt;Note that you'll need to reindex the imported content and that any related data that lives outside of the object itself is gone. For example, its intid are gone and all relationships to it will have to be recreated etc. But you just saved your customers bacon, I'm sure they won't mind a little manual work!&lt;/p&gt;
&lt;p&gt;--&lt;br /&gt;Martijn Pieters&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Martijn Pieters
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-12-18T09:47:43Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/listening-for-signals-from-dead-zopes">        <title>Listening for signals from dead Zopes</title>        <link>http://www.jarn.com/blog/listening-for-signals-from-dead-zopes</link>        

<description>            

 Occasionally the impossible, or at least very unlikely, happens: your Zope instance hangs. You can see in the process listing that it is working very hard on something but it is refusing to show you what that is. 
 &lt;p&gt;This phenomenon is commonly known as a &lt;em&gt;deadlocked Zope&lt;/em&gt;. This is a bit of a misnomer since you might be dealing with infinite loops instead of a deadlock.&lt;/p&gt;
&lt;p&gt;There are two popular tools to help you debug your Zope: &lt;a class="generated" href="http://www.zope.org/Members/nuxeo/Products/DeadlockDebugger"&gt;DeadlockDebugger&lt;/a&gt; and &lt;a class="generated" href="http://pypi.python.org/pypi/z3c.deadlockdebugger"&gt;z3c.deadlockdebugger&lt;/a&gt;. Both provide a magic URL you can visit and which will return an overview of all stackframes for all threads. This will show you exactly what Zope is hiding from you.&lt;/p&gt;
&lt;p&gt;&lt;img class="image-right" src="resolveuid/65bd836bd3c6ced0934fd81baabe8f49/image_mini" alt="internet heartbeat" /&gt;Both these tools have an achilles heel: If all your Zope threads are stuck there is nothing available to process your magic URL. We ran into exactly that situation for a customer project and had to find a solution. Luckily this turned out to be simple: instead of requesting and returning the stackframe data through the webserver why not do it directly on the console? UNIX already provides us with a very useful signalling system available for: signals. Signals also have the benefit of being more secure: they can only be sent by someone who has access to the server and the account used to run the Zope instance. And thus was born a new product: &lt;a class="generated" href="http://pypi.python.org/pypi/Products.signalstack"&gt;Products.signalstack&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Once you have installed signalstack in your Zope instance all your need to do is send a USR1 signal to the Zope process and it dumps the stackframes of all threads to its standard output.&lt;/p&gt;
&lt;h3&gt;Installing&lt;/h3&gt;
&lt;p&gt;Installing signalstack is simple: you only need to install the Products.signalstack package in your site. If you are using &lt;a class="generated" href="http://pypi.python.org/pypi/zc.buildout"&gt;zc.buildout&lt;/a&gt; just add it to the eggs-line for your instance and run buildout.&amp;nbsp;&lt;/p&gt;
&lt;pre&gt;[instance]&lt;br /&gt;recipe = plone.recipe.zope2instance&lt;br /&gt;zope2-location = ${zope2:location}&lt;br /&gt;eggs =&lt;br /&gt;    Plone&lt;br /&gt;    PIL&lt;br /&gt;    Products.signalstack&lt;/pre&gt;
&lt;p&gt;If you are not using buildout you can use easy_install to install it either globally or inside your Zope instance.&lt;/p&gt;
&lt;h3&gt;Using&lt;/h3&gt;
First you need to figure out the pid (process id) of your Zope instance. You can find this in the &lt;em&gt;var/instance.pid&lt;/em&gt; file in your buildout. If you can not find that file look for a zope process in your process listing. Once you have found the pid you can send a signal to it:
&lt;pre&gt;$ kill -USR1 4361&lt;/pre&gt;
&lt;p&gt;Zope will respond in kind by throwing a lot of data at you:&lt;/p&gt;
&lt;pre&gt;Threads traceback dump at 2008-10-21 11:34:47&lt;br /&gt;&lt;br /&gt;Thread -1340051456:&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZServer/PubCore/ZServerPublisher.py", line 19, in __init__&lt;br /&gt;    name, a, b=accept()&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZServer/PubCore/ZRendezvous.py", line 73, in accept&lt;br /&gt;    l.acquire()&lt;br /&gt;&lt;br /&gt;Thread -1340583936 (GET /Plone):&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZServer/PubCore/ZServerPublisher.py", line 25, in __init__&lt;br /&gt;    response=b)&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZPublisher/Publish.py", line 401, in publish_module&lt;br /&gt;    environ, debug, request, response)&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZPublisher/Publish.py", line 202, in publish_module_standard&lt;br /&gt;    response = publish(request, module_name, after_list, debug=debug)&lt;br /&gt;&lt;br /&gt;[ .. removed a lot of uninteresting frames here ..]&lt;br /&gt;&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/Products/PageTemplates/Expressions.py", line 123, in render&lt;br /&gt;    ob = ob()&lt;br /&gt;  File "/Users/wichert/Development/plone/plone3.2/src/Plone/Products/CMFPlone/browser/ploneview.py", line 287, in showEditableBorder&lt;br /&gt;    request = self.request&lt;br /&gt;  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/bdb.py", line 48, in trace_dispatch&lt;br /&gt;    return self.dispatch_line(frame)&lt;br /&gt;  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/bdb.py", line 66, in dispatch_line&lt;br /&gt;    self.user_line(frame)&lt;br /&gt;  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/pdb.py", line 135, in user_line&lt;br /&gt;    self.interaction(frame, None)&lt;br /&gt;  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/pdb.py", line 158, in interaction&lt;br /&gt;    self.cmdloop()&lt;br /&gt;  File "/opt/local/Library/Frameworks/Python.framework/Versions/2.4/lib/python2.4/cmd.py", line 130, in cmdloop&lt;br /&gt;    line = raw_input(self.prompt)&lt;br /&gt;&lt;br /&gt;Thread -1341648896:&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZServer/PubCore/ZServerPublisher.py", line 19, in __init__&lt;br /&gt;    name, a, b=accept()&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZServer/PubCore/ZRendezvous.py", line 73, in accept&lt;br /&gt;    l.acquire()&lt;br /&gt;&lt;br /&gt;Thread -1341116416:&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZServer/PubCore/ZServerPublisher.py", line 19, in __init__&lt;br /&gt;    name, a, b=accept()&lt;br /&gt;  File "/Users/wichert/Library/Zope/Zope-2.10.6-final-py2.4/lib/python/ZServer/PubCore/ZRendezvous.py", line 73, in accept&lt;br /&gt;    l.acquire()&lt;br /&gt;&lt;br /&gt;End of dump&lt;/pre&gt;
&lt;p&gt;It is immediately obvious that this Zope has a problem: someone forgot to remove a pdb.set_trace() statement at line 287 of ploneview.py.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;--&lt;br /&gt;Wichert Akkerman&lt;/p&gt;&lt;p&gt;&lt;/p&gt;
     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Wichert Akkerman
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-10-22T09:54:08Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/catalog-query-plan">        <title>Catalog query plan</title>        <link>http://www.jarn.com/blog/catalog-query-plan</link>        

<description>            

 Making the catalog faster 
 
&lt;p&gt;While the catalog tool in Zope is immensely useful, we have seen some slowdowns in large Plone sites with a combination of additional indexes and lots of content.&lt;/p&gt;
&lt;h2&gt;Analyzing Catalog implementation&lt;/h2&gt;
&lt;p&gt;The catalog implementation is using BTree set operations like union, multiunion and intersection. Those operations are fairly fast, especially when everything is in memory. However, the catalog implementation is rather naïve which leads to lots of set operations on rather big sets.&lt;/p&gt;
&lt;h3&gt;Example&lt;/h3&gt;
&lt;p&gt;A typical simple scenario is an intranet with 150000 content items, most of them published, and local roles used to handle access to most of the content.&lt;/p&gt;
&lt;p&gt;We want to look for pending Documents in a section of the site. In addition to the specified requirements, the catalog tool in Plone would add a search for allowedRolesAndUsers and effectiveRange to only return results the user is allowed to see.&lt;/p&gt;
&lt;p&gt;There is no explicit ordering of the indexes, so in our first example our ordering is &lt;em&gt;portal_type,&amp;nbsp;&lt;/em&gt;&lt;em&gt;allowedRolesAndUsers&lt;/em&gt;, &lt;em&gt;review_state&lt;/em&gt;, &lt;em&gt;effectiveRange&lt;/em&gt;, &lt;em&gt;path&lt;/em&gt;. The first index, &lt;em&gt;portal_type&lt;/em&gt; returns 90000 items.&amp;nbsp; Then we continue on to &lt;em&gt;allowedRolesAndUsers&lt;/em&gt;, which returns 40000 items. This is intersected with the the previous set, yielding a set of 20000.  As all the content in this section is published, there are no items in the &lt;em&gt;review_state=pending&lt;/em&gt;, which gives an empty set when intersected with the previous set.&lt;em&gt; effectiveRange&lt;/em&gt; returns 140000 items, which is intersected with empty set. &lt;em&gt;path&lt;/em&gt; returns 400 items which is once again intersected with the empty result set. The end result is an empty set and the query typically takes 0.15 seconds on my laptop.&lt;/p&gt;
&lt;p&gt;As a basic first improvement, it would help to immediately return after getting an empty result set from an index, but we can go even further.&lt;/p&gt;
&lt;h2&gt;Query plan&lt;/h2&gt;
&lt;p&gt;Search engines and databases uses &lt;a href="http://en.wikipedia.org/wiki/Query_optimizer"&gt;query optimizers&lt;/a&gt; to select &lt;a href="http://en.wikipedia.org/wiki/Query_plan"&gt;query plans&lt;/a&gt; that will minimize the result set as early as possible, because working with large amounts of data is time consuming.&lt;/p&gt;
&lt;p&gt;What we want to do is to search against the indexes giving the smallest result set first. However, for that to be useful, we need to pass that result along into the indexes to allow the indexes to limit the result set as soon as possible internally. When calculating a path search, there is no need to look in all 150000 results if the portal type index has already limited the possible result to 10000. If we have already limited the result to 10000 results, all set operations are going to be significantly faster.&lt;/p&gt;
&lt;h2&gt;Solution&lt;/h2&gt;
&lt;p&gt;We identify different searches by the list of indexes that are searched. If there are no query plans for a set of indexes, the query is run like normal while storing the number of results for each index. When all indexes have been checked, the list is sorted on number of results and stored as a query plan. Next time a search on the same indexes comes in, the query plan is looked up.&lt;/p&gt;
&lt;p&gt;To get different query plans for similar queries, you can provide additional bogus index names. They will be ignored by the catalog, but will become part of the key. This means that if you search for Documents in &lt;em&gt;draft&lt;/em&gt; state for a worklist, you can have a different ordering than when searching for &lt;em&gt;published&lt;/em&gt; Documents, as there are likely to be very few items in draft state, but many in published state.&lt;/p&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;p&gt;&lt;img class="image-right" src="resolveuid/725ef1a64e34a3e72f552bd09714afcd" alt="Catalog query plan" /&gt;I tested this in an example site locally with a 15GB Data.fs, 150000 content items, and running a JMeter test plan that logged in, viewed a couple of pages and logged out again.&lt;/p&gt;
&lt;p&gt;When measuring in the regular catalog, there were 1220 queries taking 81 seconds with the regular catalog, which is 66ms per query. When using the query plan, the queries took 14.1 seconds, which is 11ms per query. The catalog implementation is also used for membrane and reference catalog to look up users and objects, but those have significantly fewer indexes than the regular catalog tool, so we also measure on the Catalog Tool.&lt;/p&gt;
&lt;p&gt;When measuring only the catalog tool, there were 510 queries taking 80.9 seconds with the regular catalog, which is 159ms per query. With the query plan it took 14.3 seconds, which is 28ms per query. We consider 14.3 vs 14.1 to be within normal variations when measuring, and the numbers indicate that the time spent in membrane and reference catalog can be ignored compared to the time spent in the catalog tool.&lt;/p&gt;
&lt;p&gt;Going from 159ms to 28ms for typical queries is a noticeable improvement. If you are mildly abusing the catalog, this might add up to a second or more on a single page view.&lt;/p&gt;
&lt;h2&gt;Interested?&lt;/h2&gt;
&lt;p&gt;You can try these performance improvements by installing the &lt;a href="http://pypi.python.org/pypi/experimental.catalogqueryplan"&gt;experimental.catalogqueryplan&lt;/a&gt; package in your Plone site. Just add it to the eggs list in your buildout configuration and either import experimental.catalogqueryplan from your code, or load its zcml.&lt;/p&gt;
&lt;h2&gt;Sponsored by&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.elkjop.no/"&gt;&lt;img class="image-inline" src="resolveuid/4e61c35d8a124ab01cbf776feffb5ae6" alt="Elkjøp logo" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;--&lt;br /&gt;
Helge Tesdal&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Helge Tesdal
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-07-29T10:15:45Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/plone-indexing-performance">        <title>Clean and fast indexing in Plone</title>        <link>http://www.jarn.com/blog/plone-indexing-performance</link>        

<description>            

 Getting rid of redundant reindexing the right way. 
 &lt;h2&gt;Background and motivation&lt;/h2&gt;
&lt;p&gt;We have already established the fact that indexing can be improved in Plone in a &lt;a title="Getting rid of redundant reindexing" href="resolveuid/36e1ea51b7421a9435fdf93a40d3483d"&gt;previous blog posting&lt;/a&gt;, where we investigated the potential for improvement by applying an insane/inspired monkeypatch.&lt;/p&gt;
&lt;p&gt;The monkeypatch made the Plone site temporarily ignore any indexing requests, and it had side effects. Like the fact that
any additional indexing triggered by content creation in factory method
or initializeArchetype would be ignored.&lt;/p&gt;
&lt;h2&gt;Moving forward&lt;/h2&gt;
&lt;p&gt;The fundamental problem with indexing from a performance point of view, is that indexing is performed instantly instead of at transaction boundary. By postponing indexing until the transaction commits, we are able to filter the indexing events. This enables us to&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Ignore unnecessary indexing (add followed by delete)&lt;/li&gt;&lt;li&gt;Only do one (re)indexing instead of many on the same object&lt;/li&gt;&lt;/ul&gt;
&lt;h2&gt;Technical details&lt;/h2&gt;
&lt;p&gt;We added an indexing queue, which was in turn controlled by a transaction manager. The transaction manager pattern was reused from &lt;em&gt;enfold.solr&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;On modified event, or when (re)indexObject is called, the indexing requests are
put in the queue. When the transaction commits, the queue is processed. There is a default reducer which filters duplicates (which can be overridden by registering a new adapter). Then the requests are dispatched to any queue processors registered. The default queue processor is for adding content in portal_catalog, and dispatches to CatalogAware and CatalogMultiplex. You can easily add queue processors for asynchronous queue processing, or for external indexing.&lt;/p&gt;
&lt;h2&gt;Results&lt;/h2&gt;
&lt;p&gt;&lt;img class="image-right" src="resolveuid/f28ad2f2114b99ff3d0fa6ad11757fd3" alt="collective.indexing performance improvement" /&gt;When measuring improvements, we created 100 news articles using the &lt;a href="http://dev.plone.org/collective/browser/JMeterTestPlans/trunk"&gt;JMeter Test Plan&lt;/a&gt; from the collective. Unmodified is plain Plone. Indexing refers to a site with the &lt;a href="http://plone.org/products/collective.indexing/"&gt;collective.indexing&lt;/a&gt; extension profile applied. Experimental refers to &lt;a href="http://dev.plone.org/collective/browser/experimental.contentcreation/trunk"&gt;experimental.contentcreation&lt;/a&gt; (without redundant reindex hack), and E+I is &lt;a href="http://dev.plone.org/collective/browser/experimental.contentcreation/trunk"&gt;experimental.contentcreation&lt;/a&gt; and &lt;a href="http://plone.org/products/collective.indexing/"&gt;collective.indexing&lt;/a&gt; together.&lt;/p&gt;
&lt;p&gt;Note that the test results are not useful as a measure of absolute performance or to be compared with other tests. We can see that the performance improves when avoiding redundant reindexing, and now it is done in a clean and efficient way.&lt;/p&gt;
&lt;p&gt;In a real life deployment with more indexes and metadata, and possibly file conversion as well, the improvement will be bigger.&lt;/p&gt;
&lt;h2&gt;Try it out for yourself&lt;/h2&gt;
&lt;p&gt;You can use the buildout for testing this yourself.&lt;/p&gt;
&lt;pre&gt;svn co http://svn.plone.org/svn/collective/collective.indexing/buildout indexing&lt;br /&gt;cd indexing&lt;br /&gt;python bootstrap.py&lt;br /&gt;bin/buildout&lt;br /&gt;bin/instance start&lt;/pre&gt;
&lt;p&gt;Create a new Plone site, using the &lt;a href="http://plone.org/products/collective.indexing/"&gt;collective.indexing&lt;/a&gt; extension profile.&lt;/p&gt;
&lt;h2&gt;Future plans&lt;/h2&gt;
&lt;p&gt;While this component is fully usable, it is also about exploring indexing in Zope in general. During the Sorrento Sprint, Malthe Borch and Sylvain Viollon were looking into Xapian integration, and found the time to start splitting &lt;a href="http://plone.org/products/collective.indexing/"&gt;collective.indexing&lt;/a&gt; into &lt;em&gt;z3c.indexing.dispatcher&lt;/em&gt;, which will in turn dispatch to components like &lt;em&gt;z3c.indexing.zcatalog&lt;/em&gt;, external indexers or asynchronous queues similar to the one in &lt;em&gt;ore.xapian&lt;/em&gt;. For extracting data from content in Plone, there will be a &lt;em&gt;plone&lt;/em&gt; namespace packages with adapters for data extraction.&lt;/p&gt;

&lt;p&gt;Because &lt;a href="http://plone.org/products/collective.indexing/"&gt;collective.indexing&lt;/a&gt; is about adapters and utilities and not data structures, it is simple to switch parts of it as it becomes available in &lt;em&gt;z3c&lt;/em&gt; packages, and when that's done, move it into the &lt;em&gt;plone&lt;/em&gt; namespace and hopefully also towards inclusion in Plone core...&lt;/p&gt;
&lt;h2&gt;Sponsored by&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.elkjop.no/"&gt;&lt;img class="image-inline" src="resolveuid/4e61c35d8a124ab01cbf776feffb5ae6" alt="Elkjøp logo" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;--&lt;br /&gt;Andreas Zeidler and Helge Tesdal&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Helge Tesdal
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-04-01T07:33:33Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/explore-portlet">        <title>Explore portlet</title>        <link>http://www.jarn.com/blog/explore-portlet</link>        

<description>            

  
 &lt;img class="image-right" src="resolveuid/a495a27a76fcfab7da90bd858b8b33bd/image_mini" alt="" /&gt;
&lt;h2&gt;Navigating the seas of Plone&lt;/h2&gt;
&lt;p&gt;One of the most important things you need to do when using a content management system such as Plone is to find your way to your data. Typically this involves navigating through a site using the navigation portlet: for every step your browser needs to load another page so you can find the next step on your path. This can be a slow procedure since you need a full page load at each step.&lt;/p&gt;
&lt;h2&gt;A faster way to travel&lt;/h2&gt;
&lt;p&gt;To help you get to your destination faster we wrote the &lt;a href="http://plone.org/products/collective.portlet.explore"&gt;Explore portlet&lt;/a&gt;. This is an alternative to the standard Plone 3 navigation portlet which features AJAX-based navigation: simply click on the triangle next to a folder in the navigation tree and its contents will be loaded into the tree. Click again and the tree collapses again. This gives you a very fast and intuitive method to explore the contents of your site.&lt;/p&gt;
&lt;h2&gt;Sponsored by&lt;/h2&gt;
&lt;p&gt;&lt;a href="http://www.elkjop.no/"&gt;&lt;img class="image-inline" src="resolveuid/4e61c35d8a124ab01cbf776feffb5ae6" alt="Elkjøp logo" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;--&lt;br /&gt;Wichert Akkerman&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Wichert Akkerman
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-03-07T10:51:15Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/getting-rid-of-redundant-reindexing">        <title>Getting rid of redundant reindexing</title>        <link>http://www.jarn.com/blog/getting-rid-of-redundant-reindexing</link>        

<description>            

 experimental.contentcreation cuts amount of reindexing. 
 
&lt;h3&gt;Redundant reindexing&lt;/h3&gt;
&lt;p&gt;While creating a new object using the factory tool, the new object would be reindexed four times.&lt;/p&gt;
&lt;ol&gt;&lt;li&gt;ObjectAddedEvent event handler&lt;/li&gt;&lt;li&gt;Finish construction in factory method&lt;/li&gt;&lt;li&gt;processForm in Archetypes.BaseObject&lt;/li&gt;&lt;li&gt;Rename after creation&lt;/li&gt;&lt;/ol&gt;
&lt;p&gt;This is 3 times more than necessary. The first two are called by &lt;em&gt;factory_tool.doCreate&lt;/em&gt;, and the two last are in &lt;em&gt;processForm&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;Avoiding reindexing&lt;/h3&gt;
&lt;p&gt;All the reindexing was happening in methods called by &lt;em&gt;content_edit_impl&lt;/em&gt;, and all reindexing went through &lt;em&gt;CatalogMultiplex&lt;/em&gt;. In &lt;em&gt;experimental.contentcreation&lt;/em&gt; we already take advantage of the fact that &lt;em&gt;CatalogMultiplex&lt;/em&gt; gets a list of all catalogs to index in, and by returning an empty list, the object is not indexed. The strategy would be to let &lt;em&gt;content_edit_impl&lt;/em&gt; change the result of the catalog listing while the reindexing method was called, then finally do 1 reindex afterwards.&lt;/p&gt;
&lt;p&gt;First of all we needed to override the &lt;em&gt;content_edit_impl&lt;/em&gt; script. In Plone, it is implemented as a skin script, which enables easy customization. As we needed trusted code, we added it to the patch in &lt;em&gt;experimental.contentcreation&lt;/em&gt; and set it as an attribute to the &lt;em&gt;Portal&lt;/em&gt; class, which prevents the use of the script in &lt;em&gt;portal_skins&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Before calling &lt;em&gt;doCreate&lt;/em&gt; and &lt;em&gt;processForm&lt;/em&gt; from &lt;em&gt;content_edit_impl&lt;/em&gt;, we create a lambda function that returns an empty list and set the &lt;em&gt;getCatalogsByType&lt;/em&gt; method of the Archetypes tool object to the newly created lambda function. In addition, we set &lt;em&gt;_p_changed&lt;/em&gt; to &lt;em&gt;False&lt;/em&gt; on the Archetypes tool to avoid the transaction machinery trying to save the function during savepoint.&lt;/p&gt;
&lt;p&gt;After &lt;em&gt;doCreate&lt;/em&gt; and &lt;em&gt;processForm&lt;/em&gt;, we delete the function object and reset &lt;em&gt;_p_changed&lt;/em&gt; again, before doing a single and final &lt;em&gt;reindexObject&lt;/em&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;img class="image-right" src="resolveuid/413da58e760aa535a016908c678d47c6" alt="Redundant reindexing" /&gt;The result&lt;/h3&gt;
&lt;p&gt;No performance blog posting without a graph. We tested the setup with JMeter on a laptop, 10 loops for each scenario. The blue bar is content creation with &lt;em&gt;experimental.contentcreation&lt;/em&gt; with 1 reindex.&lt;/p&gt;
&lt;p&gt;Our tests show that time went down from 567ms in regular Plone to 203ms with &lt;em&gt;experimental.contentcreation&lt;/em&gt; and the redundant reindexing removal. &lt;em&gt;experimental.contentcreation&lt;/em&gt; without reindexing removal was 284ms.&lt;/p&gt;
&lt;p&gt;If you have converters to handle uploaded files and more fields and indexes in the catalog, the time difference will be even bigger.&lt;/p&gt;
&lt;h3&gt;Future&lt;/h3&gt;
&lt;p&gt;We also created a &lt;em&gt;plone.app.content&lt;/em&gt; based content type with formlib forms to compare response times compared to regular Plone. While not directly comparable and not feature complete, the numbers give an indication of what to expect in the future, and why people are looking into Zope 3 technology.&lt;/p&gt;
&lt;h3&gt;Try it out for yourself&lt;/h3&gt;
&lt;p&gt;To try it out for yourself, you can check out &lt;a href="http://svn.plone.org/svn/collective/experimental.contentcreation/trunk"&gt;experimental.contentcreation&lt;/a&gt; from SVN, add it to your buildout (don't forget the ZCML slug) and restart Zope.&lt;/p&gt;
&lt;p&gt;
-- Helge Tesdal&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Helge Tesdal
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-02-17T22:11:31Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/membrane-performance">        <title>Membrane performance</title>        <link>http://www.jarn.com/blog/membrane-performance</link>        

<description>            

 Optimization of the object_implements method in Membrane 
 
&lt;h3&gt;The challenge&lt;/h3&gt;
&lt;p&gt;While looking at content creation in a Membrane scenario, we noticed that &lt;em&gt;object_implements&lt;/em&gt; took a lot of time. &lt;em&gt;object_implements&lt;/em&gt; is a catalog index wrapper that lists both the directly implemented interfaces &lt;strong&gt;and&lt;/strong&gt; any interfaces that can be adapted into. This is used when looking up user objects, as you normally associate adapters with your member types to make them behave like users.&lt;/p&gt;
&lt;p&gt;There was a note in &lt;em&gt;object_implements&lt;/em&gt; about it being slow.
Timing the method call while running tests indicated that the method
typically took &lt;strong&gt;1.2 seconds&lt;/strong&gt; on a MBP laptop. It also did not help that objects are reindexed 4 times when creating content, but that's &lt;a title="Getting rid of redundant reindexing" href="resolveuid/36e1ea51b7421a9435fdf93a40d3483d"&gt;another story&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;The problem&lt;/h3&gt;
&lt;p&gt;Previously, &lt;em&gt;object_implements&lt;/em&gt; was using the &lt;em&gt;getRequiredAdapters&lt;/em&gt;&amp;nbsp; method from &lt;em&gt;zope.app.apidoc.component&lt;/em&gt; to list all required adapters for an interface. &lt;em&gt;getRequiredAdapters&lt;/em&gt; would check all adapters and instantiate a registration info object for each matching adapter. It would be called once for each interface implemented by the object currently being examined. Judging by the package name, this info object was originally intended to be used for API documentation, and contains more info than we need for this use case.&lt;/p&gt;
&lt;h3&gt;Poking the adapter registry&lt;/h3&gt;
&lt;p&gt;As we were not aware of any current methods in the adapter registries that would give the result we were looking for, we started &lt;a href="http://dev.plone.org/collective/changeset/58797"&gt;poking the internals of the registry&lt;/a&gt; from membrane. The registry has a dictionary of interfaces and their corresponding adapters, and we used that to look up the adapters. If an exception occurs in the new code, we have a fallback to the old code.&lt;/p&gt;
&lt;p&gt;Poking the internals of the adapter registry is not future proof, as we are circumventing interfaces and depending on the internal data structures of the adapter registry to stay the same. While not very likely to change, the data structure might change between Zope versions - requiring us to update Membrane.&lt;/p&gt;
&lt;p&gt;&lt;img class="image-right" src="resolveuid/d848b317be8bf81ad27bc9992ed34921" alt="object_implements optimization" /&gt;&lt;/p&gt;
&lt;h3&gt;Measuring improvement&lt;/h3&gt;
&lt;p&gt;After testing again, the time spent in &lt;em&gt;object_implements&lt;/em&gt; was &lt;strong&gt;0.0006&lt;/strong&gt; seconds, and the set of interfaces returned were exactly the same with both methods.&lt;/p&gt;
&lt;p&gt;The difference was difficult to express in our regular go-faster-graphs, so we used an area plot instead. The four pixels on the right indicate the time after optimization relative to before the optimization.&lt;/p&gt;
&lt;p&gt;This change is checked in on &lt;a href="http://dev.plone.org/collective/changeset/58797"&gt;membrane trunk&lt;/a&gt;, and will be part of the next release unless there are any unforeseen problems.&lt;/p&gt;
&lt;p&gt;
--&lt;br /&gt;
Helge Tesdal&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Helge Tesdal
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-02-17T21:32:19Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/plone-2-5-performance">        <title>Plone 2.5 performance</title>        <link>http://www.jarn.com/blog/plone-2-5-performance</link>        

<description>            

 Profiling of content creation and teamspace scenario in Plone 2.5, and publishing contentmenu and factoryhack. 
 
&lt;p&gt;We have blogged about performance before, after doing &lt;a title="Improving Plone performance" href="resolveuid/a8edf29a40dc8dd8dc4cf64f6ac04e79"&gt;profiling for Plone 2.5&lt;/a&gt; and during the &lt;a title="Plone performance sprint" href="resolveuid/a72bdfd5ff78f1636ad53d5cb3125260"&gt;Copenhagen Performance Sprint where we made experimental.contentcreation&lt;/a&gt;. Prior to experimental.contentcreation we made two Plone 2.5 products named factoryhack and contentmenu that are now available in the &lt;a href="http://dev.plone.org/collective/browser/experimental.contentcreation/plone2.5"&gt;collective&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Performance improvements&lt;/h3&gt;
&lt;p&gt;First of all we'll take a look at what you'll get from these products by setting up some tests with jmeter. Each test is run 10 times after
warming up 2 times. Neither of the tests were done on plain Plone, they
have several add on products installed, and other factors that affect
performance. The results can not be used as an absolute benchmark on
Plone performance, but are useful for showing relative results with and
without the optimizations.&lt;/p&gt;
&lt;p&gt;The first test shows results for
content creation. Listing is listing folder contents, Addform is
showing the addform to add content in the folder, Create is pressing
the save button and creating the content, and show is displaying the
newly created content.&lt;/p&gt;
&lt;img class="image-inline" src="resolveuid/ddf3744637278c126448c3dfb670d05a" alt="Plone 2.5 optimizations when creating content" /&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;The
second test is for a teamspace scenario. Teamspaces is viewing a
listing of teamspaces, Teamspace is viewing one teamspace, Subfolder 1
is listing contents in a subfolder of Teamspace, and Subfolder 2 is
another folder, parallell to Subfolder 1.&lt;/p&gt;
&lt;img class="image-inline" src="resolveuid/8546508399128cff2d75bb5d5d38d6cd" alt="Plone 2.5 optimizations in a teamspace scenario" /&gt;
&lt;h3&gt;Install&lt;/h3&gt;
&lt;p&gt;If you want to try this for yourself, you can check out the products into your Products directory using command line svn or a client like TortoiseSVN:&lt;/p&gt;
&lt;pre&gt;svn co https://svn.plone.org/svn/collective/experimental.contentcreation/plone2.5/factoryhack factoryhack&lt;/pre&gt;
&lt;pre&gt;svn co https://svn.plone.org/svn/collective/experimental.contentcreation/plone2.5/contentmenu contentmenu&lt;/pre&gt;
&lt;p&gt;Content menu then has to be installed in the install products control panel.&lt;/p&gt;
&lt;h3&gt;Technical&lt;/h3&gt;
&lt;p&gt;The technical details are covered pretty well in the two previous blog postings [&lt;a title="Improving Plone performance" href="resolveuid/a8edf29a40dc8dd8dc4cf64f6ac04e79"&gt;1&lt;/a&gt;][&lt;a title="Plone performance sprint" href="resolveuid/a72bdfd5ff78f1636ad53d5cb3125260"&gt;2&lt;/a&gt;].&lt;/p&gt;
&lt;p&gt;Factoryhack is mainly about optimizing the portal factory tool, but also the type listings. It is implemented as a monkey patch, meaning that it it automatically applies itself when Zope starts, and is completely gone as soon as you remove it from the Products directory.&lt;/p&gt;
&lt;p&gt;Contentmenu is about improving the type listings further. It is installed in the control panel and provides a skin override. It does not alter the data in any way, and will be gone as soon as you uninstall in control panel and remove from Products directory.&lt;/p&gt;
&lt;h3&gt;Disclaimer&lt;/h3&gt;
&lt;p&gt;Note that the type listings are optimized by bypassing the regular security machinery and trying to emulate it in a more efficient way by gathering all local roles first, then check against roles required for adding content. This is working in production, but if you experience unexpected results in the add content dropdown after installing these products, you will have to uninstall them again. It does not affect actual create permissions, only the drop down menu that lists the types available. The worst that can happen is that you don't see all content types you are allowed to create, or get an error message because you are trying to add a content type without really being allowed to.&lt;br /&gt;&lt;br /&gt;-- Helge&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Helge Tesdal
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-02-08T14:57:14Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>
    <item rdf:about="http://www.jarn.com/blog/announcing-plone-enterprise-forum">        <title>Announcing Plone Enterprise Forum</title>        <link>http://www.jarn.com/blog/announcing-plone-enterprise-forum</link>        

<description>            

  
 
&lt;p&gt;&lt;br /&gt;We are proud and happy to announce a new interest group and mailing list: "&lt;em&gt;Plone in the Enterprise&lt;/em&gt;".&lt;br /&gt;There is a growing interest in features for using Plone in Enterprise-level deployments like:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;scaling to handle hundreds or thousands of parallel authenticated users&lt;/li&gt;&lt;li&gt;Enterprise search (being able to quickly search through millions of objects)&lt;/li&gt;&lt;li&gt;Integration &lt;/li&gt;&lt;li&gt;Clustering and hosting solutions&lt;/li&gt;&lt;li&gt;High availability architcture&lt;/li&gt;&lt;li&gt;more…&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;We are now launching a separate forum for the discussion of Plone in the Enterprise.&lt;br /&gt;There are already many interesting projects happening, and the sooner we can join our efforts the better it will be for the world of large-scale Plone. Let's share experiences, needs, war stories and help each other on development of large-scale features:&lt;br /&gt;The mailing list is available at&lt;br /&gt;&lt;a href="http://lists.plone.org/mailman/listinfo/enterprise"&gt;http://lists.plone.org/mailman/listinfo/enterprise&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It is available in Gmane for those of us that prefer a newsgroup interface:&lt;br /&gt;&lt;a href="news:gmane.comp.web.zope.plone.enterprise"&gt;gmane.comp.web.zope.plone.enterprise&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;and as a web-forum at Nabble:&lt;br /&gt;&lt;a href="http://www.nabble.com/Enterprise-f30548.html"&gt;http://www.nabble.com/Enterprise-f30548.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you care about enterprise level Plone, Please join us!&lt;/p&gt;
&lt;p&gt;--&lt;/p&gt;
&lt;p&gt;Geir Bækholt&lt;/p&gt;

     
</description>

        <dc:publisher>No publisher</dc:publisher>        

  <dc:creator> 
      Geir Bækholt
      - Jarn 
  </dc:creator>
  
  
      
     
          <dc:rights></dc:rights>                <dc:date>2008-01-28T22:43:04Z</dc:date>        <dc:type>Blog Posting</dc:type>    </item>




</rdf:RDF>
