<?xml version="1.0" encoding="utf-8" ?>
<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://rpatterson.net/front-page/RSS">
  <title>Ross Patterson</title>
  <link>http://rpatterson.net</link>
  
  <description>
    
       Welcome to my blog and professional website.
       
  </description> 

  
  
            <syn:updatePeriod>daily</syn:updatePeriod>
            <syn:updateFrequency>1</syn:updateFrequency>
            <syn:updateBase>2007-12-20T00:21:18Z</syn:updateBase>
        
  
  <image rdf:resource="http://rpatterson.net/logo.gif"/>

  <items>
    <rdf:Seq>
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/collective.formcriteria-folder_contents"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/testbrowser-patches"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/gsml"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/software/collective.gsqi"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/software/collective.contemplate"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/gpg-key-transition"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/ldap-certificates-and-buildout-oh-my"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/stagger-supervisord"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/software/bbdb.gmailfilter"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/collective.formcriteria"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/bristol-performance-sprint-post-mortem"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/plone-4-framework-team"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/emacs-tips-navigate-camelcase"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/functional-benchmarking-accessibility"/>
        
        
            <rdf:li rdf:resource="http://rpatterson.net/blog/at-the-plone-performance-sprint"/>
        
    </rdf:Seq>
  </items>

</channel>

    <item rdf:about="http://rpatterson.net/blog/collective.formcriteria-folder_contents">        <title>collective.formcriteria folder_contents - Managing content with collections</title>        <link>http://rpatterson.net/blog/collective.formcriteria-folder_contents</link>        <description>&lt;p&gt;&lt;a class="reference" href="http://pypi.python.org/pypi/collective.formcriteria#id1"&gt;collective.formcriteria&lt;/a&gt; is quite stable now and the latest release includes some additional features.&lt;/p&gt;
&lt;p&gt;Firstly, an &amp;quot;Export&amp;quot; document action (ala &amp;quot;Print&amp;quot;, &amp;quot;Send to&amp;quot;, etc.) allows the collection's results to be exported to CSV where the columns are those specified in the collection's &amp;quot;Table Columns&amp;quot; fields.  This merges (and deprecates) my collective.catalogexport package and duplicates SmartCSVExporter.  One advantage of the collective.formcriteria version is that it will stream the results to the response.  Since catalog results are lazy, this should be fairly efficient.&lt;/p&gt;
&lt;p&gt;I've also tightened up the styling on the search form portlet so it's not quite as unwieldy.  I'd still love to get some contributions here from someone better at CSS than I.&lt;/p&gt;
&lt;p&gt;But the most significant piece of work has been to get the folder_contents form to work with collection results.  The &amp;quot;Tabular Form&amp;quot; display layout is now available for collections.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Use &amp;quot;Table Columns&amp;quot; fields for the folder contents form to control the folder contents columns&lt;/li&gt;
&lt;li&gt;Use a &amp;quot;Table Column Links&amp;quot; collection filed to specify which folder contents form columns should link to the item&lt;/li&gt;
&lt;li&gt;The &amp;quot;Copy&amp;quot;, &amp;quot;Cut&amp;quot;, &amp;quot;Rename&amp;quot;, &amp;quot;Change State&amp;quot;, and &amp;quot;Delete&amp;quot; folder contents form button now all work for objects listed by the collections even if they are in different folders&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;With all this in place, collections and formcriteria make a fairly powerful combination for managing Plone content.  You can setup a collection with a search form portlet and use search queries to find all the objects you want to apply a workflow transition to, delete, or copy.&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                <dc:date>2009-08-23T16:19:07Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/testbrowser-patches">        <title>testbrowser Patches - collective.testcaselayer 1.2 includes some patches for functional browser testing</title>        <link>http://rpatterson.net/blog/testbrowser-patches</link>        <description>&lt;p&gt;To use these patches, include the collective.testcaselayer
configure.zcml.  The patches address some bugs in
Testing.ZopeTestCase.&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h3&gt;&lt;a id="data-streamed-to-the-response" name="data-streamed-to-the-response"&gt;Data streamed to the response&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Due to some behavior in Testing.ZopeTestCase.zopedoctest.functional,
the testbrowser.contents was empty when data had been streamed
directly into the response (as opposed to returning the data from the
callable published).  This made it difficult to do functional testing
for code that needed to stream data to the response for performance,
such as when the response data is very large and would consume too
much memory.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h3&gt;&lt;a id="http-referrer" name="http-referrer"&gt;HTTP_REFERRER&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Due to &lt;a class="reference" href="https://bugs.launchpad.net/bugs/98437"&gt;bug #98437&lt;/a&gt;,
&amp;quot;TestBrowser Referer: header set to 'localhost'&amp;quot;, some testbrowser
requests would raise NotFound.  Two examples would be visiting the
Plone login_form directly rather than following a link, or using the
Plone content_status_history form.&lt;/p&gt;
&lt;/div&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                <dc:date>2009-08-23T20:11:27Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/gsml">        <title>GSML - GenericSetup import hadlers ala ZCML directive handlers</title>        <link>http://rpatterson.net/blog/gsml</link>        <description>&lt;p&gt;I've gotten so far behind on my blogging, I think it's time to admit
that I'm not behind, I've simply stopped.  :)  In the hopes that I
start up again, I'd like to write a bit about something I wrote a
while ago and still use today: GSML.&lt;/p&gt;
&lt;p&gt;The amount of code duplication involved in writing a properly
declaritive GenericSetup import/export handler has always bothered
me.  It seems like most of the duplication involves fairly manually
walking the XML DOM to extract the data needed.  I find this to be
very tedious and error prone.  I think implementing GS import/export
handlers should have &lt;em&gt;nothing&lt;/em&gt; to do with XML.&lt;/p&gt;
&lt;p&gt;ZCML does a great job of allowing directive handlers to be simple
Python functions that know nothing of XML.  I wrote GSML to bring that
separation of concerns to GS import handlers so I could stop writing
DOM walkers.&lt;/p&gt;
&lt;p&gt;Currently, GSML lives in &lt;a class="reference" href="http://pypi.python.org/pypi/collective.gsqi"&gt;collective.gsqi&lt;/a&gt; which is just my
grab bag of patches to GS and portal_quickinstaller I use in my client
work.  Here's a doctest that covers &lt;a class="reference" href="http://dev.plone.org/collective/browser/collective.gsqi/trunk/collective/gsqi/gsml/README.txt"&gt;writing an import handler&lt;/a&gt;
with GSML.  Here's are a &lt;a class="reference" href="http://dev.plone.org/collective/browser/collective.gsqi/trunk/collective/gsqi/group/README.txt"&gt;groups import handler&lt;/a&gt;
and a &lt;a class="reference" href="http://dev.plone.org/collective/browser/collective.gsqi/trunk/collective/gsqi/refs/meta.py"&gt;references import handler&lt;/a&gt;
implemented with GSML.&lt;/p&gt;
&lt;p&gt;The current implementation of GSML just wraps the ZCML configuration
engine sufficiently to use it for GS import handlers.  Since ZCML has
never concerned itself with writing ZCML, however, GSML currently
includes no support for export handlers.  This is obviously the most
important TODO.&lt;/p&gt;
&lt;p&gt;So please try it out, take a look at it and let me know what you
think.  In particular, if anyone out there has any interest in the
export stuff, either in contributing to it, sprinting on it, advising
on it, or anything else, I'd really like to hear from you.&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                <dc:date>2009-08-23T15:36:20Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/software/collective.gsqi">        <title>collective.gsqi - A grab bag of patches to GS and portal_quickinstaller</title>        <link>http://rpatterson.net/software/collective.gsqi</link>        <description>&lt;p&gt;This &lt;a class="reference" href="http://pypi.python.org/pypi/collective.gsqi"&gt;package&lt;/a&gt; is my grab bag of patches to GS and portal_quickinstaller
I use in my client work.  It is unstable, unpolished, subject to my
whim, and really should be experimental.gsqi.  If, however, the same
GenericSetup and portal_quickinstaller quirks and bugs bother you, or
the same conveniences are of value to you, you might want to look at
whats in it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Fix &lt;a class="reference" href="http://dev.plone.org/collective/browser/collective.gsqi/trunk/collective/gsqi/workflow/exportimport.py"&gt;import of group roles&lt;/a&gt;
during workflow import&lt;/li&gt;
&lt;li&gt;Fix &lt;a class="reference" href="http://dev.plone.org/plone/ticket/8350"&gt;circular import handler dependencies&lt;/a&gt; bug&lt;/li&gt;
&lt;li&gt;Fix portal_quickinstaller so that &lt;a class="reference" href="http://dev.plone.org/collective/browser/collective.gsqi/trunk/collective/gsqi/qi.py"&gt;persistent data is not lost&lt;/a&gt;
on reinstall&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also included are a number of perhaps naughty extensions to the CMF
content import handler.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;Permissive registrations of the StructureFolderWalkingAdapter so
that folders under the profile's &amp;quot;structure&amp;quot; folder with the same
name as in the container's .objects file can be used to import any
kind of content object, not just folders.  This allows, amongst
other things, creating topics/collections and criteria on import.&lt;/li&gt;
&lt;li&gt;Set arbitrary AT fields on import using the options under the
[FIELDS] section of .properties as field names and the option
values as field values.  If field.multiValued is True, then the
option value will be split on newlines and each value stripped.&lt;/li&gt;
&lt;li&gt;Reindex imported objects so that imported titles, descriptions,
and any other AT fields are reflected in the catalog and portal
navigation after import.&lt;/li&gt;
&lt;li&gt;Set local roles on import where each option under the [ROLES]
section of .properties is the principal/user id and the roles
assigned to that principal are taken from the option value split
at newlines with each item stripped.&lt;/li&gt;
&lt;li&gt;Do each workflow transition listed under the &amp;quot;transitions&amp;quot; option
of the [DEFAULT] section of .properties.  The option value is
split at newlines with each item stripped.&lt;/li&gt;
&lt;li&gt;Set display layout using the layout option in the [DEFAULT]
section of .properties&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;Also included is &lt;a class="reference" href="http://rpatterson.net/blog/gsml"&gt;GSML&lt;/a&gt; which
allows implementing GS import handlers as you would implement ZCML
directive handlers.  Some import handlers are included in
collective.gsqi that make use of GSML.&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;A &lt;a class="reference" href="http://dev.plone.org/collective/browser/collective.gsqi/trunk/collective/gsqi/group/README.txt"&gt;groups import handler&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A &lt;a class="reference" href="http://dev.plone.org/collective/browser/collective.gsqi/trunk/collective/gsqi/refs/meta.py"&gt;references import handler&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                    <dc:subject>Software</dc:subject>                <dc:date>2009-08-23T15:34:21Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/software/collective.contemplate">        <title>collective.contemplate - Add content from existing content templates</title>        <link>http://rpatterson.net/software/collective.contemplate</link>        <description>&lt;p&gt;The &lt;a class="reference" href="http://pypi.python.org/pypi/collective.contemplate"&gt;collective.contemplate&lt;/a&gt; package allows
site administrators to designate content items as the template from
which new items of that type will be created.&lt;/p&gt;
&lt;p&gt;When creating content from a template, the initial edit form is
rendered and validation performed on the template after changing the
owner of the template to the current user within a
transaction.savepoint() which is rolled back after rendering.  As a
result, portal_factory is not involved and indexing occurs only on the
final copy of the template.  This may result in performance gains
though this has not been tested.&lt;/p&gt;
&lt;p&gt;While designed to be Archetypes agnostic, only an Archetypes
implementation is currently provided.  Templates may currently be
designated using Archetype UIDs for the global templates or references
for the context specific templates.&lt;/p&gt;
&lt;p&gt;A reserved_id property can also be set on type information objects in
portal_types.  If set and an object with that ID already exists in the
container, then the type is not allowed to be added.&lt;/p&gt;
&lt;div class="contents topic"&gt;
&lt;p class="topic-title first"&gt;&lt;a id="table-of-contents" name="table-of-contents"&gt;Table of Contents&lt;/a&gt;&lt;/p&gt;
&lt;ul class="simple"&gt;
&lt;li&gt;&lt;a class="reference" href="#installation" id="id1" name="id1"&gt;Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a class="reference" href="#usage" id="id2" name="id2"&gt;Usage&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id1" id="installation" name="installation"&gt;Installation&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;To use collective.contemplate for the Plone content types, include the
collective.contemplate configure.zcml in your instance and install
&amp;quot;Content Templates&amp;quot; in the &amp;quot;Add-on Products&amp;quot; control panel, or in the
ZMI through portal_setup.  This will replace the Plone content type
information with template versions.&lt;/p&gt;
&lt;p&gt;To install for other content types, register a template add form for
the content type and use the TemplateDynamicViewTypeInfo meta_type for
the content type information.&lt;/p&gt;
&lt;p&gt;In the ZCML for the browser views:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;contemplate:formControllerPage
     name=&amp;quot;addFoo&amp;quot;
     type_name=&amp;quot;Foo&amp;quot;
     for=&amp;quot;zope.app.container.interfaces.IAdding&amp;quot;
     permission=&amp;quot;foo.AddFoo&amp;quot; /&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Note that the &amp;quot;foo.AddFoo&amp;quot; permission must be registered and the name
&amp;quot;addFoo&amp;quot; must be the same as your content type constructor.  If you're
using Archetypes, then the constructor may auto-generated by prefixing
&amp;quot;add&amp;quot; to the content class name.&lt;/p&gt;
&lt;p&gt;In the GenericSetup profile types.xml file:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;object name=&amp;quot;Foo&amp;quot; meta_type=&amp;quot;TemplateDynamicViewTypeInfo &amp;quot;/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;In the GenericSetup profile types/Foo.xml file:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;gt;
&amp;lt;object name=&amp;quot;Foo&amp;quot;
   meta_type=&amp;quot;TemplateDynamicViewTypeInfo&amp;quot;&amp;gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h3&gt;&lt;a class="toc-backref" href="#id2" id="usage" name="usage"&gt;Usage&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This package is currently incomplete until a UI for designating
templates is included.  In the mean time, you may set the global
templates in the ZMI or context specific templates using the
references GenericSetup import handler provided by collective.gsqi.&lt;/p&gt;
&lt;p&gt;You can use a given content item as the global template by setting the
global_uid property of the content type information under portal_types
in the ZMI.  Set global_uid to the Archetypes UID of the template.&lt;/p&gt;
&lt;p&gt;You can use a content item as the template in the context of a
specific folder by setting a reference from the folder to the item
with the relationship of &amp;quot;contemplate.${type_info/getId}&amp;quot; where
&amp;quot;${type_info/getId}&amp;quot; is the id of the content type.&lt;/p&gt;
&lt;p&gt;A reserved id can be set using the reserved_id property of the content
type information under portal_types in the ZMI.&lt;/p&gt;
&lt;/div&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                    <dc:subject>Software</dc:subject>                <dc:date>2009-08-23T22:14:57Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/gpg-key-transition">        <title>GPG Key Transition - I'm now using a new and more secure OpenPGP key</title>        <link>http://rpatterson.net/blog/gpg-key-transition</link>        <description>&lt;p&gt;For a number of reasons, i've recently set up a new OpenPGP key, and
will be transitioning away from my old one.&lt;/p&gt;
&lt;p&gt;The old key will continue to be valid for some time, but i prefer all
future correspondence to come to the new one.  I would also like this
new key to be re-integrated into the web of trust.  This message is
also &lt;a class="reference" href="/key-transition.txt.asc"&gt;available signed by both keys&lt;/a&gt; to
certify the transition.&lt;/p&gt;
&lt;p&gt;the old key was:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pub   1024D/DA3C0A60 2007-10-03
      Key fingerprint = 5A41 9205 15DA 73C7 9D04  9EAF 79E1 C766 DA3C 0A60
&lt;/pre&gt;
&lt;p&gt;And the new key is:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
pub   4096R/983EA5AB 2009-08-02
      Key fingerprint = A815 9EE0 8317 DE08 8FE8  4EA1 FC5B 12B8 983E A5AB
&lt;/pre&gt;
&lt;p&gt;To fetch the full key, you can get it with:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
wget -q -O- http://rpatterson.net/rpatterson.gpg | gpg --import -
&lt;/pre&gt;
&lt;p&gt;Or, to fetch my new key from a public key server, you can simply do:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
gpg --keyserver subkeys.pgp.net --recv-key 983EA5AB
&lt;/pre&gt;
&lt;p&gt;If you already know my old key, you can now verify that the new key is
signed by the old one:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
gpg --check-sigs 983EA5AB
&lt;/pre&gt;
&lt;p&gt;If you don't already know my old key, or you just want to be double
extra paranoid, you can check the fingerprint against the one above:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
gpg --fingerprint 983EA5AB
&lt;/pre&gt;
&lt;p&gt;If you are satisfied that you've got the right key, and the UIDs match
what you expect, I'd appreciate it if you would sign my key:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
gpg --sign-key 983EA5AB
&lt;/pre&gt;
&lt;p&gt;Lastly, if you could upload these signatures, i would appreciate it.
You can either send me an e-mail with the new signatures (if you have
a functional MTA on your system):&lt;/p&gt;
&lt;pre class="literal-block"&gt;
gpg --armor --export 983EA5AB | mail -s 'OpenPGP Signatures' rpatterson&amp;#64;rpatterson.net
&lt;/pre&gt;
&lt;p&gt;Or you can just upload the signatures to a public keyserver directly:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
gpg --keyserver subkeys.pgp.net --send-key 983EA5AB
&lt;/pre&gt;
&lt;p&gt;Please let me know if there is any trouble, and sorry for the
inconvenience.&lt;/p&gt;
&lt;p&gt;Thanks!&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                <dc:date>2009-08-03T00:06:24Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/ldap-certificates-and-buildout-oh-my">        <title>LDAP, Certificates and Buildout, oh my! - Bringing LDAP and SSL/SASL/TLS certificates into the buildout fold</title>        <link>http://rpatterson.net/blog/ldap-certificates-and-buildout-oh-my</link>        <description>&lt;p&gt;I hate modified dependencies.  I'm none to fond of
python-ldap/buildout issues either.  So when a client had a patch to
modify the various Plone LDAP eggs just to get SSL/SASL/TLS
certificates working, I'd had it.  I decided it was time to make
everythign reproducible and bring LDAP fully into the buildout fold.&lt;/p&gt;
&lt;p&gt;The modifications were used to get the python-ldap package to properly
authenticate/verify certificates when connecting via SSL/SASL/TLS.  I
found a &lt;a class="reference" href="http://lists.plone.org/pipermail/setup/2009-January/004601.html"&gt;Plone setup list post&lt;/a&gt;
that provides most of the solution.&lt;/p&gt;
&lt;p&gt;The right way to get certificates working is to have the underlying
openldap installation properly configured to use the certificates.  If
that's configured properly, python-ldap will just work and no
modifications are required to the Plone LDAP eggs.&lt;/p&gt;
&lt;p&gt;The post contains the basic buildout configuration layout required to
get things working which includes building openldap using CMMI and
using a template to install an ldap.conf that tells the openldap build
where to find the certificates.  I ran into one issue during the
openldap build for which some quick googling pointed me to an
&lt;a class="reference" href="http://www.openldap.org/lists/openldap-bugs/200808/msg00130.html"&gt;environment variable workaround&lt;/a&gt;.
The post uses a buildout part to install the certificates into the
buildout configuration, but since the ldap.conf template has to say
where the certificates are anyways, I just point to them in the ldap.conf template at
etc/ldap.conf.in:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
TLS_CACERTDIR /usr/local/ssl/certs
TLS_REQCERT hard
&lt;/pre&gt;
&lt;p&gt;Then we build python-ldap telling it to use the openldap build from
the buildout.  The final key is to make sure that the custom
python-ldap egg is used and not one retrieved by buildout &lt;em&gt;prior&lt;/em&gt; to
building the custom egg.  The way to achieve this is to make sure that
the instance(s) eggs option does a valiable substitution from the
python-ldap buildout part, thus forcing the right dependency
ordering.&lt;/p&gt;
&lt;p&gt;The end result is my ldap.cfg file:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[buildout]
extends = base.cfg
parts +=
    openldap-build
    ldap.conf
    python-ldap

[instance1]
eggs += ${python-ldap:egg}

[openldap-build]
recipe = zc.recipe.cmmi
url = ftp://ftp.openldap.org/pub/OpenLDAP/openldap-stable/openldap-stable-20090411.tgz
environment =
# Workaround for &amp;quot;error: storage size of ‘peercred’ isn’t known&amp;quot;
# http://www.openldap.org/lists/openldap-bugs/200808/msg00130.html
    CPPFLAGS=-D_GNU_SOURCE
extra_options =
    --with-sasl --with-tls --enable-slapd=no

[ldap.conf]
recipe = collective.recipe.template
depends = ${openldap-build:location}
input = etc/ldap.conf.in
output = ${openldap-build:location}/etc/openldap/ldap.conf

[python-ldap]
recipe = zc.recipe.egg:custom
egg = python-ldap
include-dirs = ${openldap-build:location}/include
library-dirs = ${openldap-build:location}/lib
rpath = ${openldap-build:location}/lib
&lt;/pre&gt;
&lt;p&gt;Enjoy!&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                <dc:date>2009-07-19T02:07:51Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/stagger-supervisord">        <title>Stagger supervisord - Poor man's supervisor program startup delay</title>        <link>http://rpatterson.net/blog/stagger-supervisord</link>        <description>&lt;div class="section"&gt;
&lt;h3&gt;&lt;a id="update" name="update"&gt;Update&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The right way to solve my original problem concerning ConflictErrors
when starting up multiple ZEO clients and subsequent TypeErrors, as
pointed out by both Hanno Schlichting and Martijn Pieters, is to add
the following to the configuration of all but the first ZEO client:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
zope-conf-additional +=
    enable-product-installation False
&lt;/pre&gt;
&lt;p&gt;Here's the genericized post in case someone needs supervisor
staggering for some other reason.&lt;/p&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h3&gt;&lt;a id="staggering" name="staggering"&gt;Staggering&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Thanks to some discussion with aclark and dukebody and some previous
experience abusing zc.recipe.egg to add hackish scripts to a buildout,
I came up with a solution.  Adding the following part to a buildout
will add a &amp;quot;bin/sleep NUM COMMAND ARGS...&amp;quot; script that will sleep for
NUM seconds and then call COMMAND with ARGS:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[sleep]
recipe = zc.recipe.egg
eggs = zc.recipe.egg
initialization =
    import sys, time
    time.sleep(float(sys.argv[1]))
arguments = sys.argv[2], sys.argv[2:]
entry-points = sleep=os:execvp
&lt;/pre&gt;
&lt;p&gt;This script can then be used in etc/supervisor.conf:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
[program:foo]
command = %(here)s/../bin/foo
startsecs = 30

[program:foo2]
command = %(here)s/../bin/sleep 30 %(here)s/../bin/foo2
startsecs = 60

[program:foo3]
command = %(here)s/../bin/sleep 60 %(here)s/../bin/foo3
startsecs = 90

[program:foo4]
command = %(here)s/../bin/sleep 90 %(here)s/../bin/foo4
startsecs = 120
&lt;/pre&gt;
&lt;p&gt;Now bin/supervisord will stagger the startup of all foo* programs and
prevent them from running afoul of each other.&lt;/p&gt;
&lt;/div&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                <dc:date>2009-06-04T07:27:01Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/software/bbdb.gmailfilter">        <title>bbdb.gmailfilter - GMail filters from emacs BBDB</title>        <link>http://rpatterson.net/software/bbdb.gmailfilter</link>        <description>&lt;p&gt;&lt;a class="reference" href="http://pypi.python.org/pypi/bbdb.gmailfilter"&gt;bbdb.gmailfilter&lt;/a&gt;
installs a command-line python script and an emacs command for
exporting a GMail filters Atom feed from the gnus-public and
gnus-private fields in BBDB.&lt;/p&gt;
&lt;div class="section"&gt;
&lt;h3&gt;&lt;a id="installing" name="installing"&gt;Installing&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The package can be installed using the standard python package
installation procedure.  Extract the tarball, then run the following
command inside the extracted directory:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
$ python setup.py install
&lt;/pre&gt;
&lt;p&gt;This will install the command-line utility and the rpatterson-gmail.el
emacs library.  Then add the following to your ~/.emacs:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(require 'rpatterson-gmail)
&lt;/pre&gt;
&lt;/div&gt;
&lt;div class="section"&gt;
&lt;h3&gt;&lt;a id="usage" name="usage"&gt;Usage&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Once installed, the filters can be exported to a file simply by
calling M-x bbdb-export-gmail-filters.  You will be prompted for a
file to export the filters to.&lt;/p&gt;
&lt;p&gt;For every BBDB record that has a value in the gnus-private field, a
filter will be included that matches the &amp;quot;To&amp;quot; GMail filter field on
any BBDB net addresses for that record and applies the label specified
in the gnus-private field value.  The same is done for BBDB records
with values in the gnus-public BBDB field but filters on the &amp;quot;From&amp;quot;
GMail filter field instead.&lt;/p&gt;
&lt;/div&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                    <dc:subject>Software</dc:subject>                <dc:date>2009-06-04T07:24:32Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/collective.formcriteria">        <title>collective.formcriteria - Ready for beta testers!</title>        <link>http://rpatterson.net/blog/collective.formcriteria</link>        <description>&lt;p&gt;I think &lt;a class="reference" href="http://pypi.python.org/pypi/collective.formcriteria"&gt;collective.formcriteria 0.9.5&lt;/a&gt; is in an
acceptable beta state.  I'm reasonable sure that I'm done makeing
backwards incompatible changes so it's time to invite y'all to start
hammering at it.  Add it to your eggs, your ZCML, and install it in
your site and have at it.  Report bugs to me via email.  I'm also interested in any CSS anyone can contribute to improve the portlet appearance.&lt;/p&gt;
&lt;p&gt;If you're wondering what it does, it allows collections and their
criteria to be used to generate search forms and search form portlets.
It also includes a handful of useful collection views.  &lt;a class="reference" href="http://74.125.19.132/translate_c?hl=en&amp;amp;sl=it&amp;amp;u=http://www.plone.it/news/prodotti-della-settimana/collective.formcriteria&amp;amp;prev=/search%3Fq%3Dhttp://www.plone.it/news/prodotti-della-settimana/collective.formcriteria%26hl%3Den%26client%3Dfirefox-a%26rls%3Dcom.ubuntu:en-US:unofficial%26hs%3DPPU&amp;amp;usg=ALkJrhjLb9QpgyYxexNHxHvanWsFYS0nWg"&gt;Many&lt;/a&gt;
have found it useful and I hope yet more will.  :)&lt;/p&gt;
&lt;p&gt;Thanks to Oxfam America, Jazkarta, and another client for sponsoring portions of the work!&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                <dc:date>2009-03-07T05:11:00Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/bristol-performance-sprint-post-mortem">        <title>Bristol Performance Sprint Post-Mortem - Functional benchmarking plus buildbot</title>        <link>http://rpatterson.net/blog/bristol-performance-sprint-post-mortem</link>        <description>&lt;p&gt;I'll start with apologies for the tardiness of this post.
Predictably, things got crazy as soon as I landed back home and
between catchup and holidays, it's been tough.  Thanks to &lt;a class="reference" href="http://www.jarn.com/blog/plone-performance-sprint-bristol-2008"&gt;Helge
Tesdal&lt;/a&gt; for
shaming me into posting finally.  Fortunately, I had so much more fun
at the sprint than over my holidays, the memory is still pretty fresh.
:)&lt;/p&gt;
&lt;p&gt;In fact, I couldn't put it down.  Despite running on only a few hours
sleep, a massively overloaded brain, and AirCanada's genuinely
respectable selection of on-demand movies, I kept working on the
buildbot integration.  But I'm getting ahead of myself.&lt;/p&gt;
&lt;p&gt;Since my last post on the performance sprint, Andrew continued to
alternate between poking at the write concurrency issues and doing
functional benchmark comparisons for some of the work being done at
the sprint to measure impact.  I really want to resume working with
Andrew on the write concurrency issue.  In particular I want to
document what of the various performance optimizations, experimental
or otherwise, have any significant impact on the performance.  I had a
lot of fun working with Andrew so maybe we can do some remote
sprinting.&lt;/p&gt;
&lt;p&gt;Meanwhile, I know Tom was working on the documentation in the buildout
and refining the &amp;quot;candidate&amp;quot; story.  The &amp;quot;candidate&amp;quot; stuff is a
buildout configuration file that is intended to make it easy for
developers to do comparison benchmarks to measure the impact their
work has on the baseline Plone performance.  I'm very excited about
this work as a part of making &lt;a class="reference" href="http://rpatterson.net/blog/functional-benchmarking-accessibility"&gt;functional benchmarking accessible&lt;/a&gt;
and it's definitely something we'll want to take advantage of as we
poke at the write concurrency issues.&lt;/p&gt;
&lt;p&gt;For my part, I further refined the funkload and zope.testing
integration.  I also added a zc.recipe.testrunner clone to support
adding the funkload test runner to a buildout.  My real focus on the
last day and on the flight home, however, was trying to work towards
buildbot integration.  I started by adding a build-diffs console
script that uses &amp;quot;fl-build-report --diff&amp;quot; to generates differential
reports comparing the most recent benchmark report against the
previous report and against any available reports from a day, a week,
a month and a year ago.  The goal is to use this script in a buildbot
setup, then to check the diffs generated to raise an error or a
warning when performance appears to be negatively impacted by a
change.  Buildbot could then also be a way to access the longer term
(day, week, month, year) diffs for a more long-term view of
performance changes.&lt;/p&gt;
&lt;p&gt;This next step is the actual buildbot integration.  All the funkload
support is there and the buildout works as needed.  Getting buildbot
to detect status from the diffs and to provide links to the diff
reports will require some support from a buildbot step.  I began
researching buildbot steps on the flights home, but haven't started
work yet.  Matt has a server ready and waiting when we finally do have
a working buildbot setup so I'd really like to get this done.&lt;/p&gt;
&lt;p&gt;Hopefully it won't be as long until I get to poke at the write
concurrency issue and finishing the buildbot integration as it was
until this post.  :)&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                <dc:date>2009-01-08T06:20:28Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/plone-4-framework-team">        <title>Plone 4 Framework Team - Why I'm excited to have been selected</title>        <link>http://rpatterson.net/blog/plone-4-framework-team</link>        <description>&lt;p&gt;The more I think about it the more excited I am to be a part
of the Plone 4 Framework Team (FWT).&lt;/p&gt;
&lt;p&gt;I think it's fair to say that Plone is a very successful open source
project.  On that point alone, it's an honor to serve a role in the
continued success of the project.  More than that, however, Plone has
been successful for some time now.  That success lies not just in the
technology, but in the community as well, or if you prefer, the
ecosystem.&lt;/p&gt;
&lt;p&gt;What we have, then, is success that carries with it a history and a
community that can't be abandoned without destroying that very
success.  That history and community also bring challenges with it.  I
myself find that my enjoyment of developing with Plone has kinda
plateaued largely because I continue to have to deal with the code
that is the legacy of that history.&lt;/p&gt;
&lt;p&gt;The funny thing is that I don't find myself motivated as a crusader
&lt;em&gt;against&lt;/em&gt; that history wanting to rip it out wholesale.  While this is
a no-brainer in terms of the direction Plone development needs to
take, I'm personally surprised by my motivations.  I'm no longer so
purely motivated as a developer.  I'm genuinely excited to be a part
of figuring out how to make Plone more fun and powerful for the whole
community, users, themers, integrators, and developers alike.&lt;/p&gt;
&lt;p&gt;How do we ditch old code without alienating large portions of the
community when those portions of the community depend on their
familiarity with the old code?  How do we get developers excited about
preserving continuity when we tend to prefer moving on?  How do we
make documentation sexy enough to attract and retain rock stars?  How
can we make preserving and improving performance as prestigious as
adding new features?&lt;/p&gt;
&lt;p&gt;I know I've changed because I can't imagine a more exciting set of
questions to tackle. So yeah, I'm stoked to be a part of the FWT as we
tackle exactly these issues in earnest.  :)&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                <dc:date>2009-01-08T07:28:39Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/emacs-tips-navigate-camelcase">        <title>Emacs tips: Navigate CamelCase - M-f, M-b, M-d, &lt;M-backspace&gt; over camelCase!</title>        <link>http://rpatterson.net/blog/emacs-tips-navigate-camelcase</link>        <description>&lt;p&gt;Update: See the comment below about using c-subword-mode.  It's already included in my emacs at least, and it seems to be a bit better supported.  camelCase-mode seems to conflict with org-mode at least.&lt;/p&gt;
&lt;p&gt;I'm terribly behind on my blogging but I wanted to re-post this nice
little &lt;a class="reference" href="http://juripakaste.fi/cgi/pyblosxom.cgi/emacs-tip.html"&gt;tidbit&lt;/a&gt; from Planet
Python for those who aren't on it already.  The &lt;a class="reference" href="http://www.eecs.ucf.edu/~leavens/emacs/camelCase/camelCase-mode.el"&gt;camelCase-mode&lt;/a&gt;
for emacs allows you to do most word based operations over the
separate words that make up a camel case word.&lt;/p&gt;
&lt;p&gt;I've been needing something like this for some time.  As an emacs
junkie, I've gotten quite accustomed to being able to move point
pretty much directly where I want it in just a few key strokes.  Camel
case words, however, can get quite long so correcting a typo or
changing a plural in one of the constituent words can leave me
reaching for my mouse of hammering away at C-f or C-b.  Simply
unacceptable!  :)&lt;/p&gt;
&lt;p&gt;So I downloaded &lt;a class="reference" href="http://www.eecs.ucf.edu/~leavens/emacs/camelCase/camelCase-mode.el"&gt;camelCase.el&lt;/a&gt;
to /usr/local/share/emacs/site-lisp and then added the following to my
.emacs:&lt;/p&gt;
&lt;pre class="literal-block"&gt;
(require 'camelCase)
(add-hook 'find-file-hook 'camelCase-mode)
&lt;/pre&gt;
&lt;p&gt;Ta da!  CamelCaseGoodness!&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                    <dc:subject>Planet Zope</dc:subject>                <dc:date>2009-01-06T19:44:32Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/functional-benchmarking-accessibility">        <title>Functional Benchmarking Accessibility - More progress on load test benchmarking</title>        <link>http://rpatterson.net/blog/functional-benchmarking-accessibility</link>        <description>&lt;p&gt;Yesterday was another great day at the Plone Performance Sprint in
Bristol, UK.&lt;/p&gt;
&lt;p&gt;I continued working with the &lt;a class="reference" href="http://www.openplans.org/projects/plone-performance-sprint-2008/standard-performance-scalability-test-suite-buildout"&gt;load test benchmarking&lt;/a&gt;
team yesterday.  One of the more enjoyable aspects of our teams work
is how natural and effective the division of labor has been.  &lt;a class="reference" href="http://www.openplans.org/people/tomster/profile"&gt;Tom&lt;/a&gt; and I worked on
the funkload buildout and the Plone core load read-only tests.
&lt;a class="reference" href="http://www.openplans.org/people/amleczko/profile"&gt;Andrew&lt;/a&gt; built on
the read-only tests to produce a write-heavy load test.  Ed and &lt;a class="reference" href="http://www.openplans.org/people/russf/profile"&gt;Russ&lt;/a&gt; have been working at
least in part on different content profiles against which to run the
different test scenarios.&lt;/p&gt;
&lt;p&gt;Toward the end of the day, Tom and I moved onto working on making the
funkload more generally usable to the wider Plone ecosystem.  One of
the first things I did after having a buildout that could run
read-only load test benchmarks was to install and turn on CacheFu
without a cache proxy.  Then I ran the benchmarks again and had
Funkload plot &lt;a class="reference" href="http://rpatterson.net/~xen/diff_ReadOnly-20081212T_145919_vs_140903/"&gt;some pretty benchmark diff graphs&lt;/a&gt;.
Tom started working on packaging this extension of the buildout as a
sample so that add-on maintainers and integrators can see how to do
the same for other add-ons.  Then they can easily compare how their
add-on affects base plone performance using funkload benchmark diffs.
Funkload rocks!  Meanwhile, I began work on making the funkload script
invocations simpler and more familiar to those of us in the
zope.testing world.&lt;/p&gt;
&lt;p&gt;One goal here is to make load test benchmarking more accessible in
general.  Ideally, an integrator who is savvy enough to work with
buildout, can use the collective.loadtesting buildout or extend it,
record a new Funkload test using the recorder proxy.  Then they can
post the resulting test module and configuration with their problem
report or question.  Part of me shudders at the thought of encouraging
broader access to benchmarking, especially since it's so easy to
create unrepresentative benchmarks.  I think, however, that drawing
back the curtains on Plone performance to expose both the positive and
the negative, even if messy, can be best in the end.&lt;/p&gt;
&lt;p&gt;Meanwhile, the Andrew's write-heavy load tests reproduced the
write-concurrency ZODB conflict bug that has recently been discussed
on the lists.  This is actually my big yin so I'm totally stoked to
see some light being shed on this.  The test scenario registers a new
user, logs them in, goes to their member folder, adds a folder, adds a
page to the new folder with lipsum field values, and logs out.  The
problems began to show themselves pretty heavily starting at about 5
concurrent users hitting one instance.  After brainstorming with
Lawrence, Andrew began generating load test diffs after experimenting
with changes to try and isolate the write concurrency bug.  First, Andrew looked into whether the response was being rendered before
hitting a conflict error and thus being forced to render it again when
it retries.  The idea was that this could extend the duration of the transaction long enough to
significantly increase conflicts.  Archetypes does already, however, do a redirect after successful edit.  We do have
many more ideas to test out and now we have real measurements.  The
day ended with Andrew factoring out the member registration part of
the test scenario to try and isolate the problem further.&lt;/p&gt;
&lt;p&gt;Today Tom and I will likely focus on further polishing and documenting
the buildout for release to the community.  We'll probably also work
on the buildbot configuration that &lt;a class="reference" href="http://www.openplans.org/people/witsch/profile"&gt;Andreas&lt;/a&gt; provided.  We want
to package it to be run against Plone core development on a regular
basis.  It would be great to have a set of pages available to view the
diff of performance for the last day of changes, the last week of
changes, the last month of changes, etc..&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                <dc:date>2008-12-13T06:13:38Z</dc:date>        <dc:type>News Item</dc:type>    </item>
    <item rdf:about="http://rpatterson.net/blog/at-the-plone-performance-sprint">        <title>At the Plone Performance Sprint - In Bristol helping make Plone go faster</title>        <link>http://rpatterson.net/blog/at-the-plone-performance-sprint</link>        <description>&lt;p&gt;I'm at the &lt;a class="reference" href="http://www.openplans.org/projects/plone-performance-sprint-2008"&gt;Plone Performance Sprint&lt;/a&gt; in
Bristol, UK and I'm having a total blast.&lt;/p&gt;
&lt;p&gt;First and foremost, it's a great group.  I'm just having too much fun
working in person with all these people I've heretofore only known
through the interwebs.  The &lt;a class="reference" href="http://www.openplans.org/projects/plone-performance-sprint-2008/topics"&gt;topics&lt;/a&gt;
brainstorming session yielded a lot of great ideas and potential
directions.  I kinda resent having to choose between the
instrumentation and &lt;a class="reference" href="http://www.openplans.org/projects/plone-performance-sprint-2008/standard-performance-scalability-test-suite-buildout"&gt;load testing&lt;/a&gt;
topics.  :)&lt;/p&gt;
&lt;p&gt;Florian has a lot of nifty ideas about instrumenting various levels of
the Plone stack to get meaningful performance data.  This is sorely
needed.  Theory and guessing in discussions about Plone performance is
all well and good, but as we all know, measure, don't guess.
Florian's instrumentation effort stands to get us good measurements of
things ranging from pickle retrieval on the ZODB level all the way up
to viewlet rendering time in the UI.  I'm definitely looking forward
to using whatever they produce.  I can't say much right now, but
hopefully in the near future we'll all be hearing from Mr. Bent.  :)&lt;/p&gt;
&lt;p&gt;In the end I've decided to go with the &lt;a class="reference" href="http://www.openplans.org/projects/plone-performance-sprint-2008/standard-performance-scalability-test-suite-buildout"&gt;load testing topic&lt;/a&gt;.
I've been wanting good baseline metrics for Plone performance for some
time.  Every now and then, a Plone rock star does some profiling and
finds some code and applies a two line change that increases
performance by some ridiculous factor.  While certainly not the
rockstar's fault and not to denigrate the rockstar's contribution, but
this should never happen.  Something should have alerted us that a
hotspot was introduced very shortly after it was introduced.  Our hope
is that having a basic set of load tests run by buildbot, we'll know
when changes are made that impact performance.  There are other goals
you can read about on the &lt;a class="reference" href="http://www.openplans.org/projects/plone-performance-sprint-2008/standard-performance-scalability-test-suite-buildout"&gt;wiki&lt;/a&gt;,
but this is my primary goal.  I hope to be a part of making work on
Plone performance boringly predictable.  Lets take the mystery out of
it.  :)&lt;/p&gt;
&lt;p&gt;After the brainstorming and topic selection and such, we got a bit of
a start on the load testing story.  The first question was which tool
to use, for which there were basically only two contenders: JMeter,
and Funkload.  I started out advocating for JMeter.  I'd had a brief
exposure to Funkload and had a bad experience with it, though I can't
remember why any more.  I built a very intricate load test suite with
JMeter after that.  It did everything I needed it to do, and the
capacity to slice and dice the reports and graphs using the UI is
great, but everything else sucks.  The UI sucks.  Using regexps for
the things JMeter uses them for sucks.  Using Java sucks.  Still I
advocated for it because it does what it says it will do quite
admirably.&lt;/p&gt;
&lt;p&gt;At this sprint, many were also under the impression that we should use
JMeter, but there are also a handful of Funkload lovers.  Through the
subsequent discussion and experimentation, I think most, if not all,
of us in the JMeter camp have been thoroughly converted.  Now that I
understand Funkload better, I see that I give up nothing I really need
and I gain... well, Python!&lt;/p&gt;
&lt;p&gt;One idea I'm not sure I'll have time to explore is integrating
testbrowser and funkload.  If I could make that work then I can write
testbrowser doctests that can be run as load tests with full reporting
options!  /me swoons&lt;/p&gt;
&lt;p&gt;Today we'll be getting started with the actual load tests.  Good
times!&lt;/p&gt;
</description>        <dc:publisher>No publisher</dc:publisher>        <dc:creator>ross</dc:creator>        <dc:rights></dc:rights>                    <dc:subject>Front Page</dc:subject>                    <dc:subject>Planet Plone</dc:subject>                    <dc:subject>Ideas</dc:subject>                <dc:date>2008-12-12T08:19:06Z</dc:date>        <dc:type>News Item</dc:type>    </item>




</rdf:RDF>
