<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:posterous="http://posterous.com/help/rss/1.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/">
  <channel>
    <title>Why not?</title>
    <link>http://blog.rosania.org</link>
    <description>There is nothing like a dream to create the future.</description>
    <generator>posterous.com</generator>
    <link type="application/json" rel="http://api.friendfeed.com/2008/03#sup" href="http://posterous.com/api/sup_update#c313fce92" xmlns="http://www.w3.org/2005/Atom"/>
    <atom:link rel="self" href="http://blog.rosania.org/rss.xml"/>
    <atom:link rel="hub" href="http://posterous.superfeedr.com"/>
    <item>
      <pubDate>Sat, 15 May 2010 14:30:00 -0700</pubDate>
      <title>JRuby Deployment with GlassFish and Capistrano</title>
      <link>http://blog.rosania.org/jruby-deployment-with-glassfish-and-capistran</link>
      <guid>http://blog.rosania.org/jruby-deployment-with-glassfish-and-capistran</guid>
      <description>
        <![CDATA[<p>
	<div><span style="font-size: large;"><strong>Background</strong></span></div>
<p>At <a href="http://collegejobconnect.com">CollegeJobConnect</a>, we need to process Word and PDF-format resumes that we receive from our members.  In order to carefully curate our initial candidate pool, we have done a lot of this work by hand.  However, as we grow we need to automate as much of the registration process as we can.  This involves using automated text extraction to retrieve some basic attributes from these files.  Fortunately, there are some great <a href="http://poi.apache.org/">open</a> <a href="http://pdfbox.apache.org/">source</a> tools out there that wrangle Word and PDF documents into raw text.  <em>Un<span style="font-style: normal;">fortunately, they are written in Java.  Enter <a href="http://jruby.org">JRuby</a>.</span></em></p>
<div>JRuby makes our job drop-dead simple.  We can tap into the Java libraries we need, while keeping our code in the language we love.  Unfortunately, the state-of-the-art in JRuby deployment is in a bit of disarray.  Charles Nutter does a good job of guiding the decision in his <a href="http://blog.headius.com/2009/08/which-deployment-for-jruby-on-rails.html">August 2009 blog post</a>.  We settled on his recommended approach for simple apps -- GlassFish gem.  However, things fell apart in the details.  A <a href="http://blogs.sun.com/Jacobkessler/entry/capistrano_and_glassfish_now_with">post on Jacob Kessler's blog</a> at Sun provided some guidance, but we had trouble getting his deployment script working properly.  We also wanted something that we could administer with initscripts, to DRY out process control.  After a few hours of head-scratching frustration, we got things running.  Here's how:</div>
<div><span style="font-size: large;"><strong>Prerequisites</strong></span></div>
<div><span style="font-size: large;"><strong><span style="font-weight: normal; font-size: small;"> 
</span></strong></span><ul>
<li>Java 6 JRE (sun-java6-jre on Ubuntu)</li>
<li>JRuby 1.5</li>
<li>Git</li>
</ul>
<div>(Our server is running Ubuntu 10.04 LTS "Lucid Lynx", but this should work in 9.10 and 8.04, and with minor adjustments in any similar Unix environment.)</div>
<div>
<div><span style="font-size: large;"><strong>Getting It Done</strong></span></div>
<div><span style="font-size: large;"><strong><span style="font-weight: normal; font-size: small;"> 
</span></strong></span><ul>
</ul>
</div>
</div>
<div>1. Install GlassFish gem:</div>
<div><span style="font-family: courier new, monospace;">sudo jruby -S gem install glassfish</span></div>
<div>2. Capify your JRuby application. From your application's root directory, run:</div>
<div><span style="font-family: courier new, monospace;">capify .</span></div>
<div>3. Customize <span style="font-family: courier new, monospace;">config/deploy.rb</span> for GlassFish.  (Change the <span style="font-size: large;"><strong><span style="font-weight: normal; font-size: small;">
</span></strong></span><div style="display: inline !important;"><span style="font-size: large;"><strong><span style="font-weight: normal; font-size: small;">
</span></strong></span><div style="display: inline !important;">"example_app" </div>
</div>
<span style="font-size: large;"><strong><span style="font-weight: normal; font-size: small;">
</span></strong></span><div style="display: inline !important;">references to match your app.)</div>

</div>
<div><div class="data type-ruby">
    
      <table cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
<span rel="#L19" id="L19">19</span>
<span rel="#L20" id="L20">20</span>
<span rel="#L21" id="L21">21</span>
<span rel="#L22" id="L22">22</span>
<span rel="#L23" id="L23">23</span>
<span rel="#L24" id="L24">24</span>
<span rel="#L25" id="L25">25</span>
<span rel="#L26" id="L26">26</span>
<span rel="#L27" id="L27">27</span>
<span rel="#L28" id="L28">28</span>
<span rel="#L29" id="L29">29</span>
<span rel="#L30" id="L30">30</span>
<span rel="#L31" id="L31">31</span>
<span rel="#L32" id="L32">32</span>
<span rel="#L33" id="L33">33</span>
<span rel="#L34" id="L34">34</span>
<span rel="#L35" id="L35">35</span>
<span rel="#L36" id="L36">36</span>
<span rel="#L37" id="L37">37</span>
<span rel="#L38" id="L38">38</span>
<span rel="#L39" id="L39">39</span>
<span rel="#L40" id="L40">40</span>
<span rel="#L41" id="L41">41</span>
<span rel="#L42" id="L42">42</span>
<span rel="#L43" id="L43">43</span>
<span rel="#L44" id="L44">44</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="n">set</span> <span class="ss">:application</span><span class="p">,</span> <span class="s2">&quot;example_app&quot;</span></div><div class="line" id="LC2"><span class="n">set</span> <span class="ss">:domain</span><span class="p">,</span> <span class="s2">&quot;example-app.com&quot;</span></div><div class="line" id="LC3"><br /></div><div class="line" id="LC4"><span class="c1">## IMPORTANT: &quot;true&quot; prevents the server from booting properly</span></div><div class="line" id="LC5"><span class="c1">## This line is sometimes recommended in other Capistrano configurations,</span></div><div class="line" id="LC6"><span class="c1">## but do not use it for GlassFish.</span></div><div class="line" id="LC7"><span class="c1"># default_run_options[:pty] = true</span></div><div class="line" id="LC8"><br /></div><div class="line" id="LC9"><span class="n">set</span> <span class="ss">:scm</span><span class="p">,</span>        <span class="ss">:git</span></div><div class="line" id="LC10"><span class="n">set</span> <span class="ss">:repository</span><span class="p">,</span> <span class="s2">&quot;git@github.com:paulrosania/example_app.git&quot;</span></div><div class="line" id="LC11"><span class="n">set</span> <span class="ss">:user</span><span class="p">,</span>       <span class="s2">&quot;deploy&quot;</span></div><div class="line" id="LC12"><span class="n">set</span> <span class="ss">:branch</span><span class="p">,</span>     <span class="s2">&quot;master&quot;</span></div><div class="line" id="LC13"><span class="n">set</span> <span class="ss">:deploy_via</span><span class="p">,</span> <span class="ss">:remote_cache</span></div><div class="line" id="LC14"><span class="n">set</span> <span class="ss">:deploy_to</span><span class="p">,</span>  <span class="s2">&quot;/home/deploy/sites/</span><span class="si">#{</span><span class="n">application</span><span class="si">}</span><span class="s2">&quot;</span></div><div class="line" id="LC15"><span class="n">set</span> <span class="ss">:use_sudo</span><span class="p">,</span>   <span class="kp">false</span></div><div class="line" id="LC16"><br /></div><div class="line" id="LC17"><span class="n">role</span> <span class="ss">:web</span><span class="p">,</span> <span class="n">domain</span>                          <span class="c1"># Your HTTP server, Apache/etc</span></div><div class="line" id="LC18"><span class="n">role</span> <span class="ss">:app</span><span class="p">,</span> <span class="n">domain</span>                          <span class="c1"># This may be the same as your `Web` server</span></div><div class="line" id="LC19"><span class="n">role</span> <span class="ss">:db</span><span class="p">,</span>  <span class="n">domain</span><span class="p">,</span> <span class="ss">:primary</span> <span class="o">=&gt;</span> <span class="kp">true</span> <span class="c1"># This is where Rails migrations will run</span></div><div class="line" id="LC20"><span class="c1"># role :db,  &quot;your slave db-server here&quot;</span></div><div class="line" id="LC21"><br /></div><div class="line" id="LC22"><span class="n">namespace</span> <span class="ss">:deploy</span> <span class="k">do</span></div><div class="line" id="LC23">&nbsp;&nbsp;<span class="n">desc</span> <span class="s2">&quot;Start Glassfish Gem from a shutdown state&quot;</span></div><div class="line" id="LC24">&nbsp;&nbsp;<span class="n">task</span> <span class="ss">:cold</span> <span class="k">do</span></div><div class="line" id="LC25">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">start</span></div><div class="line" id="LC26">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC27">&nbsp;&nbsp;</div><div class="line" id="LC28">&nbsp;&nbsp;<span class="n">desc</span> <span class="s2">&quot;Stop a server running GlassFish gem&quot;</span></div><div class="line" id="LC29">&nbsp;&nbsp;<span class="n">task</span> <span class="ss">:stop</span> <span class="k">do</span></div><div class="line" id="LC30">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">run</span> <span class="s2">&quot;/usr/sbin/service glassfish-example_app stop&quot;</span></div><div class="line" id="LC31">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC32">&nbsp;&nbsp;</div><div class="line" id="LC33">&nbsp;&nbsp;<span class="n">desc</span> <span class="s2">&quot;Starts a server running GlassFish gem&quot;</span></div><div class="line" id="LC34">&nbsp;&nbsp;<span class="n">task</span> <span class="ss">:start</span> <span class="k">do</span></div><div class="line" id="LC35">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">run</span> <span class="s2">&quot;/usr/sbin/service glassfish-example_app start&quot;</span></div><div class="line" id="LC36">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC37">&nbsp;&nbsp;</div><div class="line" id="LC38">&nbsp;&nbsp;<span class="n">desc</span> <span class="s2">&quot;Restarts a server running GlassFish gem&quot;</span></div><div class="line" id="LC39">&nbsp;&nbsp;<span class="n">task</span> <span class="ss">:restart</span> <span class="k">do</span></div><div class="line" id="LC40">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">stop</span></div><div class="line" id="LC41">&nbsp;&nbsp;&nbsp;&nbsp;<span class="n">start</span></div><div class="line" id="LC42">&nbsp;&nbsp;<span class="k">end</span></div><div class="line" id="LC43"><span class="k">end</span></div><div class="line" id="LC44"><br /></div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></div>
<div>4. Install the <span style="font-family: courier new, monospace;">glassfish-example_app</span> initscript in <span style="font-family: courier new, monospace;">/etc/init.d</span>.  (Change the "example_app" references and customize the GlassFish arguments to suit your fancy.)</div>
<div><div class="data type-shell">
    
      <table cellspacing="0" cellpadding="0">
        <tr>
          <td>
            <pre class="line_numbers"><span rel="#L1" id="L1">1</span>
<span rel="#L2" id="L2">2</span>
<span rel="#L3" id="L3">3</span>
<span rel="#L4" id="L4">4</span>
<span rel="#L5" id="L5">5</span>
<span rel="#L6" id="L6">6</span>
<span rel="#L7" id="L7">7</span>
<span rel="#L8" id="L8">8</span>
<span rel="#L9" id="L9">9</span>
<span rel="#L10" id="L10">10</span>
<span rel="#L11" id="L11">11</span>
<span rel="#L12" id="L12">12</span>
<span rel="#L13" id="L13">13</span>
<span rel="#L14" id="L14">14</span>
<span rel="#L15" id="L15">15</span>
<span rel="#L16" id="L16">16</span>
<span rel="#L17" id="L17">17</span>
<span rel="#L18" id="L18">18</span>
<span rel="#L19" id="L19">19</span>
<span rel="#L20" id="L20">20</span>
<span rel="#L21" id="L21">21</span>
<span rel="#L22" id="L22">22</span>
<span rel="#L23" id="L23">23</span>
<span rel="#L24" id="L24">24</span>
<span rel="#L25" id="L25">25</span>
<span rel="#L26" id="L26">26</span>
<span rel="#L27" id="L27">27</span>
<span rel="#L28" id="L28">28</span>
<span rel="#L29" id="L29">29</span>
<span rel="#L30" id="L30">30</span>
<span rel="#L31" id="L31">31</span>
<span rel="#L32" id="L32">32</span>
<span rel="#L33" id="L33">33</span>
<span rel="#L34" id="L34">34</span>
<span rel="#L35" id="L35">35</span>
<span rel="#L36" id="L36">36</span>
<span rel="#L37" id="L37">37</span>
<span rel="#L38" id="L38">38</span>
<span rel="#L39" id="L39">39</span>
<span rel="#L40" id="L40">40</span>
<span rel="#L41" id="L41">41</span>
<span rel="#L42" id="L42">42</span>
<span rel="#L43" id="L43">43</span>
<span rel="#L44" id="L44">44</span>
<span rel="#L45" id="L45">45</span>
<span rel="#L46" id="L46">46</span>
<span rel="#L47" id="L47">47</span>
<span rel="#L48" id="L48">48</span>
<span rel="#L49" id="L49">49</span>
<span rel="#L50" id="L50">50</span>
<span rel="#L51" id="L51">51</span>
</pre>
          </td>
          <td width="100%">
            
              
                <div class="highlight"><pre /><div class="line" id="LC1"><span class="c">#!/bin/sh</span></div><div class="line" id="LC2"><br /></div><div class="line" id="LC3"><span class="c">### BEGIN INIT INFO</span></div><div class="line" id="LC4"><span class="c"># Provides:          example_app</span></div><div class="line" id="LC5"><span class="c"># Required-Start:    $local_fs $remote_fs $network $syslog</span></div><div class="line" id="LC6"><span class="c"># Required-Stop:     $local_fs $remote_fs $network $syslog</span></div><div class="line" id="LC7"><span class="c"># Default-Start:     2 3 4 5</span></div><div class="line" id="LC8"><span class="c"># Default-Stop:      0 1 6</span></div><div class="line" id="LC9"><span class="c"># Short-Description: starts the example_app app server</span></div><div class="line" id="LC10"><span class="c"># Description:       starts the example_app app server</span></div><div class="line" id="LC11"><span class="c">### END INIT INFO</span></div><div class="line" id="LC12"><br /></div><div class="line" id="LC13"><span class="nb">set</span> -u</div><div class="line" id="LC14"><span class="nb">set</span> -e</div><div class="line" id="LC15"><br /></div><div class="line" id="LC16"><span class="c"># Feel free to change any of the following variables for your app:</span></div><div class="line" id="LC17"><span class="nv">APP_ROOT</span><span class="o">=</span>/home/deploy/sites/example_app/current</div><div class="line" id="LC18"><span class="nv">PID</span><span class="o">=</span><span class="nv">$APP_ROOT</span>/tmp/pids/glassfish.pid</div><div class="line" id="LC19"><span class="nv">ENV</span><span class="o">=</span>production</div><div class="line" id="LC20"><span class="nv">CMD</span><span class="o">=</span><span class="s2">&quot;/usr/local/jruby/bin/jruby -S glassfish --contextroot / --port 3000 --environment production --runtimes 1 --runtimes-min 1 --runtimes-max 2 -P /home/deploy/sites/example_app/current/tmp/pids/glassfish.pid --daemon /home/deploy/sites/example_app/current&quot;</span></div><div class="line" id="LC21"><br /></div><div class="line" id="LC22"><br /></div><div class="line" id="LC23"><span class="nb">cd</span> <span class="nv">$APP_ROOT</span> <span class="o">||</span> <span class="nb">exit </span>1</div><div class="line" id="LC24"><br /></div><div class="line" id="LC25">sig <span class="o">()</span> <span class="o">{</span></div><div class="line" id="LC26">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">test</span> -s <span class="s2">&quot;$PID&quot;</span> <span class="o">&amp;&amp;</span> <span class="nb">kill</span> -<span class="nv">$1</span> <span class="sb">`</span>cat <span class="nv">$PID</span><span class="sb">`</span></div><div class="line" id="LC27"><span class="o">}</span></div><div class="line" id="LC28"><br /></div><div class="line" id="LC29"><span class="k">case</span> <span class="nv">$1</span> in</div><div class="line" id="LC30">start<span class="o">)</span></div><div class="line" id="LC31">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig 0 <span class="o">&amp;&amp;</span> <span class="nb">echo</span> &gt;&amp;2 <span class="s2">&quot;Already running&quot;</span> <span class="o">&amp;&amp;</span> <span class="nb">exit </span>0</div><div class="line" id="LC32">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nv">$CMD</span></div><div class="line" id="LC33">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;</div><div class="line" id="LC34">stop<span class="o">)</span></div><div class="line" id="LC35">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig INT <span class="o">&amp;&amp;</span> <span class="nb">exit </span>0</div><div class="line" id="LC36">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">echo</span> &gt;&amp;2 <span class="s2">&quot;Not running&quot;</span></div><div class="line" id="LC37">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;</div><div class="line" id="LC38">force-stop<span class="o">)</span></div><div class="line" id="LC39">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig TERM <span class="o">&amp;&amp;</span> <span class="nb">exit </span>0</div><div class="line" id="LC40">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">echo</span> &gt;&amp;2 <span class="s2">&quot;Not running&quot;</span></div><div class="line" id="LC41">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;</div><div class="line" id="LC42">restart|reload<span class="o">)</span></div><div class="line" id="LC43">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;sig INT <span class="o">||</span> sig TERM</div><div class="line" id="LC44">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nv">$CMD</span></div><div class="line" id="LC45">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;</div><div class="line" id="LC46">*<span class="o">)</span></div><div class="line" id="LC47">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">echo</span> &gt;&amp;2 <span class="s2">&quot;Usage: $0 &lt;start|stop|restart|force-stop&gt;&quot;</span></div><div class="line" id="LC48">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="nb">exit </span>1</div><div class="line" id="LC49">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;;</div><div class="line" id="LC50"><span class="k">esac</span></div><div class="line" id="LC51"><br /></div></pre></div>
              
            
          </td>
        </tr>
      </table>
    
  </div></div>
<div>5. Install the initscript in rc.d (this will only work on Ubuntu/Debian):</div>
<div><span style="font-family: courier new, monospace;">sudo update-rc.d glassfish-example_app defaults</span></div>
<div>6. Deploy your app with <span style="font-family: courier new, monospace;">cap deploy</span>.</div>
<div>
<em>... and you're done!</em>  Post in the comments if you have any comments or questions.  If this saves you time, let me know!</div>
</div>
	
</p>

<p><a href="http://blog.rosania.org/jruby-deployment-with-glassfish-and-capistran">Permalink</a> 

	| <a href="http://blog.rosania.org/jruby-deployment-with-glassfish-and-capistran#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/400347/86c7478c8cbd09cfb150dcabdab2da22.jpeg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/people/3sINGUH4D8hX</posterous:profileUrl>
        <posterous:firstName>Paul</posterous:firstName>
        <posterous:lastName>Rosania</posterous:lastName>
        <posterous:nickName>Paul</posterous:nickName>
        <posterous:displayName>Paul Rosania</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Fri, 12 Feb 2010 08:57:38 -0800</pubDate>
      <title>On Privacy (or: what Buzz failed to learn from Newsfeed)</title>
      <link>http://blog.rosania.org/on-privacy-or-what-buzz-failed-to-learn-from</link>
      <guid>http://blog.rosania.org/on-privacy-or-what-buzz-failed-to-learn-from</guid>
      <description>
        <![CDATA[<p>
	<div>On Friday, September 8, 2006, Mark Zuckerberg <a href="http://blog.facebook.com/blog.php?post=2208562130">published an apology</a> for the <a href="http://www.wired.com/science/discoveries/news/2006/09/71739">botched</a> <a href="http://www.theregister.co.uk/2006/09/07/facebook_update_controversy/">launch</a> of Facebook Newsfeed.</div> <p /><div>The gist of his open letter was:</div><div><ul><li>We did a poor job explaining the new features</li><li>We did not provide anywhere near enough privacy control</li><li>We are launching better privacy controls today, after a marathon 48 hour coding session</li> </ul><div>A public apology from the CEO of a major company is commendable.  But contrast this with his <a href="http://blog.facebook.com/blog.php?post=2208197130">post on Tuesday night</a>, just 3 days beforehand:</div><div> <ul><li>Newsfeed is great and you need to give it a chance</li><li>Your privacy settings have not changed</li><li>Things that were private are still private</li><li>Your friends can see the exact same things they could see before</li> </ul></div></div><div>What changed?  Why the sudden change in tone?  Mark was coming to grips with a fundamental issue facing social software:</div><p /><div><b>Companies don&#39;t understand privacy!</b></div> <p /><div><b><span style="font-weight: normal;">... and as a result, they make the same mistakes, over and over again.</span></b></div> <p /><div><b><span style="font-weight: normal;">We live in public.  And we always have.  <b><span style="font-weight: normal;"><a href="http://www.youtube.com/watch?v=_XSTwfdFwIY">Moreso now</a>, perhaps.  But if you have <b><span style="font-weight: normal;"><b><span style="font-weight: normal;">ever <b><span style="font-weight: normal;"><b><span style="font-weight: normal;">had your picture taken, eaten at a restaurant, or had an argument in a public place, a little bit of your self has been copied into the ether.  Yet, just because we do these things does not mean we want them to be <i>public</i>.  That argument with your significant other would drop dead if a film crew showed up and pointed a camera in your direction.</span></b></span></b></span></b></span></b></span></b></span></b></div> <p /><div><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;">In a declarative sense, one can think about privacy as <i>action</i> and <i>context</i>.  <i>What</i> we do, and <i>where</i> and <i>with whom </i>we do it.  Indeed, the Googles and Facebooks of the world have gotten pretty sophisticated about this kind of privacy.  <i>&quot;Share my vacation photos with my close friends.&quot;  &quot;Invite my coworkers to my housewarming.&quot;</i></span></b></span></b></span></b></span></b></span></b></span></b></div> <p /><div><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;"><b><span style="font-weight: normal;">However, (as is typical with computers) things break down when you start to make inferences.  <i>She wrote on someone&#39;s public wall, therefore she intended for everyone to read.  She posted the pictures on her public blog, therefore she wants her coworkers to see them.</i>  It&#39;s pretty easy to see where the wheels come off.  That public argument we were discussing earlier?  It happened in the middle of Faneuil Hall with thousands of people around.  <i>Let&#39;s podcast it automatically!</i></span></b></span></b></span></b></span></b></span></b></span></b></div> <p /><div>Action: audio conversation; context: extraordinarily public place.  Privacy setting: <b>Everyone.</b></div><p /><div><b>What&#39;s missing is intent.</b></div><p /><div>Just because something is public does not mean it is intended to be seen.  We do things in public all the time that would be <a href="http://www.people.com/people/article/0,,20323528,00.html">humiliating</a> or <a href="http://www.ivygateblog.com/2008/12/dartmouth-religion-professor-apparently-clueless-about-the-perils-of-facebook/">destructive</a> if broadcasted.  We are so used to doing these things that sometimes we <i>don&#39;t even notice the context in which we are acting!</i>  Relying on the context of an action to determine intent is a recipe for failure.</div> <p /><div><b>Privacy and the human mind.</b></div><p /><div><div>As we use software, we map its features to our intentions.  We learn how to perform actions, and we learn to control context using privacy settings.  But that map is not perfect.  We can be confused or misled by the abundance of options or by our interpretation of instructions.  We can be downright lazy.  Or, like the public argument, we can simply forget (or ignore) context.  When those things happen, we rely on software to understand our intent, and shield us from mistakes caused by our imperfect mental map.  And unfortunately, when it comes to understanding intent, computers fail.  (<a href="http://gadgetwise.blogs.nytimes.com/2009/06/29/pushing-the-limits-of-googles-speech-recognition/">Sorry</a>, <a href="http://gvscrewups.blogspot.com/">Google</a>.)</div> <p /></div><div><b>What about Buzz?</b></div><p /><div>Back to Buzz.  The controversy over privacy is not stemming from the design of Buzz.  It stems from default settings.  The Google Buzz team is attempting to make Buzz useful <i>right out of the gate</i> by guessing your preferred list of followers and followees.  But <i>computers fail at intent</i>, and despite thoughtful design of privacy settings, Buzz is a <a href="http://fugitivus.wordpress.com/2010/02/11/fuck-you-google/">privacy</a> <a href="http://www.businessinsider.com/googles-nice-improvements-to-buzz-dont-correct-major-privacy-flaw-2010-2">failure</a>.</div> <p /><div><b>A path forward?</b></div><p /><div>Failed launches like Newsfeed and Buzz can teach us something about how people think about privacy, and how to design software to be understood and accepted by its users.  Facebook taught us that declarative privacy settings <i>can work</i>.  However, both of these failures highlight two more key issues:</div> <div><ul><li>Computers <i>suck</i> at intent.  Inferring privacy preferences for new software, based on prior actions in old software, is a recipe for failure, and a PR nightmare.</li><li>People assume computers are <i>great</i> at intent.  We publish things to much wider contexts than we intend, and don&#39;t notice or care until new products and features make incorrect inferences based on that.</li> </ul><div>The good news is that smart people are working on these problems.  Let&#39;s just hope they are learning from each other.</div><p /><div><b>In summary</b></div><div><ul><li>Shockingly, these mistakes have been made before</li> <li>Companies like Facebook and Google are only just beginning to understand privacy</li><li>Explicit, declarative privacy settings are good</li><li>Users are loose with their settings, and trust software to &quot;do the right thing&quot;</li> <li>When it comes to social software, computers <i>suck</i> at figuring out what the right thing <i>is</i></li><li>Products can improve if competitors can learn from each other</li></ul></div></div>
	
</p>

<p><a href="http://blog.rosania.org/on-privacy-or-what-buzz-failed-to-learn-from">Permalink</a> 

	| <a href="http://blog.rosania.org/on-privacy-or-what-buzz-failed-to-learn-from#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/400347/86c7478c8cbd09cfb150dcabdab2da22.jpeg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/people/3sINGUH4D8hX</posterous:profileUrl>
        <posterous:firstName>Paul</posterous:firstName>
        <posterous:lastName>Rosania</posterous:lastName>
        <posterous:nickName>Paul</posterous:nickName>
        <posterous:displayName>Paul Rosania</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Wed, 16 Dec 2009 09:10:00 -0800</pubDate>
      <title>Installing Redis on CentOS 4</title>
      <link>http://blog.rosania.org/installing-redis-on-centos-4</link>
      <guid>http://blog.rosania.org/installing-redis-on-centos-4</guid>
      <description>
        <![CDATA[<p>
	<div>TL;DR: CentOS 4 initscript for Redis at: <a href="http://bit.ly/7a23Fe">http://bit.ly/7a23Fe</a></div>
<p />
<div><span style="font-size: large;">Vanity Is Nice</span></div>
<p />
<div>I am a huge fan of <a href="http://vanity.labnotes.org/">Vanity</a>, Assaf Arkin's "Experiment Driven Development" framework. &nbsp;(A/B testing and metric tracking.)&nbsp;&nbsp;"Gem install" to "cap deploy" in under an hour. &nbsp;Talk about reducing the time investment required to get going with data-driven development! &nbsp;It Just Makes Life Easier.</div>
<p />
<div>Vanity uses <a href="http://code.google.com/p/redis/">Redis</a> as its backing store. &nbsp;Redis is fast and lightweight -- no problem there. &nbsp;It builds on CentOS right out of the gate. &nbsp;However, I want to use Redis with Vanity on a production site. &nbsp;If Redis is down, Vanity crashes and takes my app with it. &nbsp;I need it installed at runlevels 345, so it always starts at boot time.&nbsp;(We need adequate monitoring, too, but that's a topic for another post.)</div>
<p />
<div><span style="font-size: large;">CentOS Needs a Friend</span></div>
<p />
<div>There is a Ubuntu initscript floating around, but building dpkg to get the start-stop-service binary is a little heavyweight for my taste. &nbsp;Instead, I've gutted an old Nginx initscript, and it works handily.</div>
<p />
<p>You can find it at: <a href="http://bit.ly/7a23Fe">http://bit.ly/7a23Fe</a></p>
<p />
<div><span style="font-size: large;">If You Came for the Show</span></div>
<p />
<div>How to install Redis on CentOS 4, in 13 easy steps:</div>
<div><ol>
<li>curl <a href="http://redis.googlecode.com/files/redis-1.02.tar.gz">http://redis.googlecode.com/files/redis-1.02.tar.gz</a> | tar zx</li>
<li>cd redis-1.02</li>
<li>make</li>
<li>sudo cp redis-server /usr/local/sbin</li>
<li>sudo cp redis-cli /usr/local/bin</li>
<li>sudo mkdir /var/lib/redis /etc/redis</li>
<li>sudo&nbsp;sed -e "s/^daemonize no$/daemonize yes/" -e "s/^dir \.\//dir \/var\/lib\/redis\//" -e "s/^loglevel debug$/loglevel notice/" -e "s/^logfile stdout$/logfile \/var\/log\/redis.log/" redis.conf&nbsp;&gt; /etc/redis/redis.conf</li>
<li>curl <a href="http://gist.github.com/gists/257849/download">http://gist.github.com/gists/257849/download</a> | tar -zxO &gt; redis-server</li>
<li>chmod u+x redis-server</li>
<li>mv redis-server /etc/init.d</li>
<li>sudo /sbin/chkconfig --add redis-server</li>
<li>sudo /sbin/chkconfig --level 345 redis-server on</li>
<li>sudo /sbin/service redis-server start</li>
</ol>
<div>Congratulations, you have a complete Redis installation!</div>
<div>
<ul>
<li>Config: /etc/redis/redis.conf</li>
<li>Data: /var/lib/redis</li>
<li>Logfile: /var/log/redis.log</li>
<li>PID: /var/run/redis.pid</li>
</ul>
</div>
<div>If you tweak the paths, you'll need to edit redis.conf and/or the redis-server initscript accordingly.</div>
</div>
	
</p>

<p><a href="http://blog.rosania.org/installing-redis-on-centos-4">Permalink</a> 

	| <a href="http://blog.rosania.org/installing-redis-on-centos-4#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/400347/86c7478c8cbd09cfb150dcabdab2da22.jpeg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/people/3sINGUH4D8hX</posterous:profileUrl>
        <posterous:firstName>Paul</posterous:firstName>
        <posterous:lastName>Rosania</posterous:lastName>
        <posterous:nickName>Paul</posterous:nickName>
        <posterous:displayName>Paul Rosania</posterous:displayName>
      </posterous:author>
    </item>
    <item>
      <pubDate>Thu, 03 Dec 2009 14:36:20 -0800</pubDate>
      <title>Pirates Are People Too</title>
      <link>http://blog.rosania.org/pirates-are-people-too</link>
      <guid>http://blog.rosania.org/pirates-are-people-too</guid>
      <description>
        <![CDATA[<p>
	<div class='p_embed p_image_embed'>
<a href="http://posterous.com/getfile/files.posterous.com/paul-m08gc/Q6s4V6sdFMTLmtvtH5zwneW46DC3OoUrz6snIeyv1qOfEM89awNM4MXUOLDg/photo.jpg"><img alt="Photo" height="667" src="http://posterous.com/getfile/files.posterous.com/paul-m08gc/CsBMaLk8HcFZxhFMP5zaIThqwZUDN6PXpoDimLJRmwvhUBP8tUR9tG95mqGi/photo.jpg.scaled.500.jpg" width="500" /></a>
</div>

	
</p>

<p><a href="http://blog.rosania.org/pirates-are-people-too">Permalink</a> 

	| <a href="http://blog.rosania.org/pirates-are-people-too#comment">Leave a comment&nbsp;&nbsp;&raquo;</a>

</p>]]>
      </description>
      <posterous:author>
        <posterous:userImage>http://files.posterous.com/user_profile_pics/400347/86c7478c8cbd09cfb150dcabdab2da22.jpeg</posterous:userImage>
        <posterous:profileUrl>http://posterous.com/people/3sINGUH4D8hX</posterous:profileUrl>
        <posterous:firstName>Paul</posterous:firstName>
        <posterous:lastName>Rosania</posterous:lastName>
        <posterous:nickName>Paul</posterous:nickName>
        <posterous:displayName>Paul Rosania</posterous:displayName>
      </posterous:author>
      <media:content type="image/jpeg" url="http://posterous.com/getfile/files.posterous.com/paul-m08gc/Q6s4V6sdFMTLmtvtH5zwneW46DC3OoUrz6snIeyv1qOfEM89awNM4MXUOLDg/photo.jpg" width="600" height="800">
        <media:thumbnail url="http://posterous.com/getfile/files.posterous.com/paul-m08gc/CsBMaLk8HcFZxhFMP5zaIThqwZUDN6PXpoDimLJRmwvhUBP8tUR9tG95mqGi/photo.jpg.scaled.500.jpg" width="500" height="667"/>
      </media:content>
    </item>
  </channel>
</rss>
