<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:gd="http://schemas.google.com/g/2005" xmlns:georss="http://www.georss.org/georss" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:thr="http://purl.org/syndication/thread/1.0"><id>tag:blogger.com,1999:blog-6930361</id><updated>2024-10-24T03:41:48.802-04:00</updated><category term="Software"/><title type="text"/><subtitle type="html">I'm an agile software developer specializing in Ruby. Read along as I find what works for me.</subtitle><link href="http://daddy.platte.name/feeds/posts/default" rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/" rel="alternate" type="text/html"/><link href="http://pubsubhubbub.appspot.com/" rel="hub"/><link href="http://www.blogger.com/feeds/6930361/posts/default?start-index=26&amp;max-results=25" rel="next" type="application/atom+xml"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><generator uri="http://www.blogger.com" version="7.00">Blogger</generator><openSearch:totalResults>90</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6930361.post-5491527963997534518</id><published>2017-07-05T13:16:00.002-04:00</published><updated>2017-07-05T13:16:33.684-04:00</updated><title type="text">Contained clutter</title><content type="html">Every line of code is that much more technical inventory that carries risk and management burden. How can we make efficient progress without impeding our delivery of features?&lt;br /&gt;
&lt;br /&gt;
I just read an article about dead code. It cited Michael Feathers’s article &lt;i&gt;&lt;a href="http://michaelfeathers.typepad.com/michael_feathers_blog/2011/05/the-carrying-cost-of-code-taking-lean-seriously.html"&gt;The Carrying Cost of Code: Taking Lean Seriously&lt;/a&gt;&lt;/i&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
No, to me, &lt;b&gt;code is inventory&lt;/b&gt;. &amp;nbsp;It is stuff lying around and it has substantial cost of ownership. It might do us good to consider what we can do to minimize it.&lt;/blockquote&gt;
&lt;br /&gt;
Of course it’s best to have no clutter at all. But failing a clutter-free environment, there is a great technique for reducing the risks created by this inventory.&lt;br /&gt;
&lt;br /&gt;
GTD identifies the first step to tackling a chaotic mess as collection of all the open loops, the unanswered questions that each item represents. Subsequent steps organize further…to convert the inventory of clutter to an inventory of next actions. There’s still inventory, but it is vastly more meaningful and valuable.&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://leanpub.com/cbra"&gt;CBRA&lt;/a&gt; makes clutter less expensive. It separates Rails apps into multiple “components” (gems and Rails engines) that all live within the main app's source tree. Unlike vanilla Rails development, CBRA makes it easy to reason about which code does not affect other bits. Some parts of the software are mission-critical and can receive close attention, while other parts can be coded up quickly and mostly forgotten outside whatever narrow supplementary purpose they serve.&lt;br /&gt;
&lt;br /&gt;
Service-oriented architecture addresses this, but there is sizable friction involved in creating a new autonomous service. Whatever we do about the clutter problem has to be a quick and easy experience so that the right path is an easy one.&lt;br /&gt;
&lt;br /&gt;
Gary Bernhardt’s video &lt;a href="https://www.destroyallsoftware.com/screencasts/catalog/functional-core-imperative-shell" style="font-style: italic;"&gt;Functional Core, Imperative Shell&lt;/a&gt;&amp;nbsp;demonstrates how organizing code well reduces the risk of sloppy, hacky experimenting without causing decay in the overall system.&lt;br /&gt;
&lt;br /&gt;
(When searching for Bernhardt’s video, I ran across another page suggesting as an alternative a&amp;nbsp;&lt;a href="http://www.mokacoding.com/blog/functional-core-reactive-shell/" rel="nofollow"&gt;Reactive Shell&lt;/a&gt;.&amp;nbsp;I haven’t explored that link yet, but the title rings true conceptually.)&lt;br /&gt;
&lt;br /&gt;
So we developers can put separate concerns in separate boxes. We know we’re on the right track when&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;a new feature fits inside a new “box”&amp;nbsp;&lt;/li&gt;
&lt;li&gt;the anxiety of deploying the new “box” is low because&lt;/li&gt;
&lt;li&gt;we clearly understand how the outside impacts the new “box” and how the new “box” will affect the outside&lt;/li&gt;
&lt;li&gt;it would be trivially simple to delete the “box” when it’s no longer needed&lt;/li&gt;
&lt;li&gt;our list of “boxes” provides a straightforward readout of what features we’re choosing to keep around&lt;/li&gt;
&lt;/ul&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/5491527963997534518" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/5491527963997534518" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2017/07/contained-clutter.html" rel="alternate" title="Contained clutter" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-1173944946171998256</id><published>2017-06-20T16:30:00.003-04:00</published><updated>2017-06-20T16:30:51.510-04:00</updated><title type="text">Setting WIP limits</title><content type="html">&lt;div class="separator" style="clear: both; text-align: left;"&gt;
Applying Lean methods to optimize the flow of a system, one encounters advice to limit the work in progress (WIP) to help keep things moving. I've wondered whether there's some simple way to take an educated guess as to what WIP limit would be appropriate. I found such a strategy (sources below).&amp;nbsp;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh8ZjB-qHkZcx1-W3zkk_9zUery1p5jJev8L3Rj24C1-VAXeiVy9bV-eTmfz9GqiZGSs8kBIAsP_RWhL1QiL46qV6uWMadrj86s3oS1bIBajjyOJwqlcHE6nwoYRip4UEwlac4Bw/s1600/setting-wip-limits.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" data-original-height="617" data-original-width="1200" height="329" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh8ZjB-qHkZcx1-W3zkk_9zUery1p5jJev8L3Rj24C1-VAXeiVy9bV-eTmfz9GqiZGSs8kBIAsP_RWhL1QiL46qV6uWMadrj86s3oS1bIBajjyOJwqlcHE6nwoYRip4UEwlac4Bw/s640/setting-wip-limits.jpg" width="640" /&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The number of arrivals and departures from a given state should be equal. If they deviate from each other, tuning the WIP limit can bring them into line with each other.&lt;br /&gt;
&lt;br /&gt;
I know enough to know that my understanding of lean is of the "enough to be dangerous" variety, but I'm pretty sure that in summarizing this I've avoided the pitfalls described in these sources:&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://agileramblings.com/2013/01/13/what-should-my-wip-limit-be-super-easy-method-to-find-out/"&gt;https://agileramblings.com/2013/01/13/what-should-my-wip-limit-be-super-easy-method-to-find-out/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://agileramblings.com/2012/12/11/littles-law-its-not-about-the-numbers/"&gt;https://agileramblings.com/2012/12/11/littles-law-its-not-about-the-numbers/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://vimeo.com/52683659"&gt;Daniel Vacanti’s presentation&lt;/a&gt;&amp;nbsp;called "Little's Flaw"&lt;/li&gt;
&lt;li&gt;&lt;a href="http://web.mit.edu/sgraves/www/papers/Little%27s%20Law-Published.pdf"&gt;The Little's Law paper&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/1173944946171998256" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/1173944946171998256" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2017/06/setting-wip-limits.html" rel="alternate" title="Setting WIP limits" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgh8ZjB-qHkZcx1-W3zkk_9zUery1p5jJev8L3Rj24C1-VAXeiVy9bV-eTmfz9GqiZGSs8kBIAsP_RWhL1QiL46qV6uWMadrj86s3oS1bIBajjyOJwqlcHE6nwoYRip4UEwlac4Bw/s72-c/setting-wip-limits.jpg" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-7571074012136278957</id><published>2016-03-17T14:44:00.001-04:00</published><updated>2016-03-17T14:44:24.942-04:00</updated><title type="text">Deleting in batches from PostgreSQL in Ruby</title><content type="html">PostgreSQL doesn't support &lt;code&gt;LIMIT&lt;/code&gt; in &lt;code&gt;DELETE&lt;/code&gt; queries. But it's a bad idea to delete huge numbers of records at a time if the operation will be more than a few seconds. So deleting in small batches can be done like this:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;DELETE FROM mytable WHERE id = ANY(ARRAY(SELECT id from mytable WHERE myfield = 10 LIMIT 10))&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
To use this code from ActiveRecord in Ruby and get the number of affected rows:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;rows_affected_count = ActiveRecord::Base.connection.execute(query).cmd_tuples&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
You can do this in a loop to keep the queries moving through the system without slow queries choking things up. When &lt;code&gt;rows_affected_count&lt;/code&gt; is less than the size of the batch, you're done.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/7571074012136278957" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/7571074012136278957" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2016/03/deleting-in-batches-from-postgresql-in.html" rel="alternate" title="Deleting in batches from PostgreSQL in Ruby" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-4777224432810958331</id><published>2016-01-05T09:14:00.002-05:00</published><updated>2016-01-05T15:12:00.502-05:00</updated><title type="text">How to find a community's pain points</title><content type="html">A business's job is to meet customers' needs. Businesses that find unmet needs and serve them well are rewarded in the marketplace. I want this. But how do I identify these unmet needs?&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Dipping into market ethnography&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
If a representative part of this group meets on the Internet, I want to find places where they meet online. The more expression of their social customs is present, the better. I want to find the places where community members relax and speak their minds. I'm looking for a group whose members have been together long enough that discernible patterns have formed. Alternatively, if I can find one that's been marginalized by society, that is an extremely powerful galvanizing force.&lt;br /&gt;
&lt;br /&gt;
Brandon Savage, a participant in Amy Hoy's &lt;a href="https://30x500.com/academy/"&gt;30x500&lt;/a&gt; class that teaches a method of market ethnography, used blog analytics, Twitter, Quora, Stack Overflow, and other forums to do his research leading to his decision to write &lt;a href="http://masteringobjectorientedphp.com/"&gt;Mastering Object-Oriented PHP&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;div&gt;
When I find this group, I read what members are writing and mine it for key information:&lt;/div&gt;
&lt;div&gt;
&lt;ul&gt;
&lt;li&gt;Cultural themes or issues&lt;/li&gt;
&lt;li&gt;Vocabulary&lt;/li&gt;
&lt;li&gt;Goals and aspirations&lt;/li&gt;
&lt;li&gt;Conflicts within the group, or between group members and others outside the group&lt;/li&gt;
&lt;li&gt;What they currently buy&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
The Wikipedia article on ethnography lists some helpful&amp;nbsp;&lt;a href="https://en.wikipedia.org/wiki/Ethnography#Procedures_for_conducting_ethnography"&gt;procedures for conducting ethnographic studies.&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;Then what?&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
Now I find a need experienced and voiced by people who are spending money in this community, and create a solution to this need. I will systematically search and destroy each objection to a purchase, building trust by teaching members of this group that I understand their problem and can solve it. Sean D'Souza's&amp;nbsp;&lt;a href="http://www.psychotactics.com/products/the-brain-audit-32-marketing-strategy-and-structure/"&gt;Brain Audit&lt;/a&gt;&amp;nbsp;lays out a framework for persuading people of this.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
A pattern that often works to begin serving this community with a solution for their need:&lt;/div&gt;
&lt;div&gt;
&lt;ol&gt;
&lt;li&gt;Each fear or threat becomes a topic that I cover with a blog post and email.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;An email sequence leads users through an overview of the free content, putting it into context and beginning to apply it to the subscriber.&lt;/li&gt;
&lt;li&gt;A small paid work connects the dots, organizing all the information and going deeper into applying it.&lt;/li&gt;
&lt;li&gt;Further services such as workshops, seminars, or kits allow people to pay for thorough solutions.&lt;/li&gt;
&lt;li&gt;A masterclass and/or personal coaching are available for those who want to really nail it.&lt;/li&gt;
&lt;li&gt;I build an ecosystem of products to create recurring, more passive revenue from solving the needs.&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/4777224432810958331" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/4777224432810958331" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2016/01/how-to-find-communitys-pain-points.html" rel="alternate" title="How to find a community's pain points" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-4901586615534950484</id><published>2015-03-12T08:55:00.000-04:00</published><updated>2015-03-12T08:56:31.936-04:00</updated><title type="text">Using more of our brains: visualizing bridge data</title><content type="html">&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdweeZHzoG3kzBO4AcbIaj5DkxtlRuiuNUDHmMz7ulu7W8HkJPWrsv2rn7fPEGcXqom8runBHL25scE6NNMeMCPlH8XssqEegRhFv6XjKtuRD8dV1E3un6WwUQ8X7tvWxteyFBOw/s1600/20150211shen02.jpg" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdweeZHzoG3kzBO4AcbIaj5DkxtlRuiuNUDHmMz7ulu7W8HkJPWrsv2rn7fPEGcXqom8runBHL25scE6NNMeMCPlH8XssqEegRhFv6XjKtuRD8dV1E3un6WwUQ8X7tvWxteyFBOw/s1600/20150211shen02.jpg" height="396" width="640" /&gt;&lt;/a&gt;Lots of bridges need maintenance. We can't fix them all at once. We're already collecting useful data during bridge inspections, but it's hard to interpret in raw form.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
So &lt;a href="http://newsroom.unl.edu/releases/2015/02/11/UNL%20prof's%203-D%20model%20could%20help%20manage%20U.S.%20bridge%20maintenance%20crisis"&gt;this professor was inspired to take advantage of the fact that we're in 2015.&lt;/a&gt; He created a rich document (he used SketchUp) to bring together inspection data, photos, and a simplified 3D model of a bridge. It's immediately obvious how helpful this would be for the vital work of prioritizing infrastructure repair.&lt;br /&gt;
&lt;br /&gt;
Simple but effective. We have to see it to understand it.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/4901586615534950484" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/4901586615534950484" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2015/03/using-more-of-our-brains-visualizing.html" rel="alternate" title="Using more of our brains: visualizing bridge data" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdweeZHzoG3kzBO4AcbIaj5DkxtlRuiuNUDHmMz7ulu7W8HkJPWrsv2rn7fPEGcXqom8runBHL25scE6NNMeMCPlH8XssqEegRhFv6XjKtuRD8dV1E3un6WwUQ8X7tvWxteyFBOw/s72-c/20150211shen02.jpg" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-3172973242513336190</id><published>2014-09-22T14:26:00.001-04:00</published><updated>2014-09-22T14:29:48.695-04:00</updated><title type="text">Capture state of Rails test database</title><content type="html">Ever want to explore the state of the database during a Rails test run? I was recently writing a test to create a seam in some complex legacy code and needed this. Dropping this code in does the job in MySQL:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="line-pre" style="background-color: white; box-sizing: border-box; color: #333333; font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; font-size: 12px; line-height: 16.7999992370605px; width: 812px;"&gt;&lt;div class="line" id="file-dump-rb-LC1" style="box-sizing: border-box;"&gt;
&lt;span class="no" style="box-sizing: border-box; color: teal;"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;::&lt;/span&gt;&lt;span class="no" style="box-sizing: border-box; color: teal;"&gt;Base&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;connection&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;tables&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;each&lt;/span&gt; &lt;span class="k" style="box-sizing: border-box; font-weight: bold;"&gt;do&lt;/span&gt; &lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;|&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;table_name&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;|&lt;/span&gt;&lt;/div&gt;
&lt;div class="line" id="file-dump-rb-LC2" style="box-sizing: border-box;"&gt;
&lt;span class="no" style="box-sizing: border-box; color: teal;"&gt;  ActiveRecord&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;::&lt;/span&gt;&lt;span class="no" style="box-sizing: border-box; color: teal;"&gt;Base&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;connection&lt;/span&gt;&lt;span class="o" style="box-sizing: border-box; font-weight: bold;"&gt;.&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;execute&lt;/span&gt;&lt;span class="p" style="box-sizing: border-box;"&gt;(&lt;/span&gt;&lt;span class="s2" style="box-sizing: border-box; color: #dd1144;"&gt;"select * from &lt;/span&gt;&lt;span class="si" style="box-sizing: border-box; color: #dd1144;"&gt;#{&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;table_name&lt;/span&gt;&lt;span class="si" style="box-sizing: border-box; color: #dd1144;"&gt;}&lt;/span&gt;&lt;span class="s2" style="box-sizing: border-box; color: #dd1144;"&gt; into outfile '/tmp/datadump-&lt;/span&gt;&lt;span class="si" style="box-sizing: border-box; color: #dd1144;"&gt;#{&lt;/span&gt;&lt;span class="n" style="box-sizing: border-box;"&gt;table_name&lt;/span&gt;&lt;span class="si" style="box-sizing: border-box; color: #dd1144;"&gt;}&lt;/span&gt;&lt;span class="s2" style="box-sizing: border-box; color: #dd1144;"&gt;.outfile'"&lt;/span&gt;&lt;span class="p" style="box-sizing: border-box;"&gt;)&lt;/span&gt;&lt;/div&gt;
&lt;div class="line" id="file-dump-rb-LC3" style="box-sizing: border-box;"&gt;
&lt;span class="k" style="box-sizing: border-box; font-weight: bold;"&gt;end&lt;/span&gt;&lt;/div&gt;
&lt;/pre&gt;
&lt;br /&gt;
(or see &lt;a href="https://gist.github.com/replaid/5ed66edef03847e246b5"&gt;this gist&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
That creates a series of tab-separated files in /tmp/. Then LOAD DATA INFILE queries can bring the data back in, or in my case I used Sequel Pro’s import command configured for tab-separated input.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/3172973242513336190" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/3172973242513336190" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/09/capture-state-of-rails-test-database.html" rel="alternate" title="Capture state of Rails test database" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-4644057555934619099</id><published>2014-08-20T12:43:00.001-04:00</published><updated>2014-08-20T12:43:41.165-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Get PHP APC cache uptime in seconds</title><content type="html">I just posted about &lt;a href="http://daddy.platte.name/2014/08/apache-uptime-in-seconds.html"&gt;getting Apache uptime&lt;/a&gt;. For what I’m seeking, I need to compare the system uptime, Apache’s uptime, and the uptime of the PHP APC opcode cache.&lt;br /&gt;
&lt;br /&gt;
Here’s code for a PHP page that will simply output the number of seconds the APC cache has been up.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;?php

$limited = true;
$info = apc_cache_info('', $limited);
print_r(time() - $info['start_time']);

?&amp;gt;&lt;/code&gt;&lt;/pre&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/4644057555934619099" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/4644057555934619099" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/08/get-php-apc-cache-uptime-in-seconds.html" rel="alternate" title="Get PHP APC cache uptime in seconds" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-5738804318229900054</id><published>2014-08-20T12:02:00.003-04:00</published><updated>2014-08-20T12:08:17.994-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Apache uptime in seconds</title><content type="html">I’m looking at some interesting anomalies on a cPanel VPS I administer, and wanted to add Apache uptime graphing. Building on this ServerFault solution, here is a way to get the number of seconds Apache has been up. Whitespace/line breaks added for clarity.&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;ps -eo comm,etime | &lt;br /&gt;
grep httpd | &lt;br /&gt;
ruby -ne 'sec, min, hour, day = $_.split(/ /).last.chomp.split(/[-:]/).reverse; &lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;p day.to_i*24*60*60 + hour.to_i*60*60 + min.to_i*60 + sec.to_i' | &lt;br /&gt;
sort -nr | &lt;br /&gt;
head -n1&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
And without the whitespace, for ease of copy/pasting:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;ps -eo comm,etime | grep httpd | ruby -ne 'sec, min, hour, day = $_.split(/ /).last.chomp.split(/[-:]/).reverse; p day.to_i*24*60*60 + hour.to_i*60*60 + min.to_i*60 + sec.to_i' | sort -nr | head -n1&lt;/code&gt;</content><link href="http://www.blogger.com/feeds/6930361/posts/default/5738804318229900054" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/5738804318229900054" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/08/apache-uptime-in-seconds.html" rel="alternate" title="Apache uptime in seconds" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-8625684193247409940</id><published>2014-07-28T14:39:00.002-04:00</published><updated>2014-08-20T12:04:42.891-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Package boundaries are a big deal</title><content type="html">Classes and objects are useful tools for working with low-level abstractions. They can express high-level abstractions, too, but it's easy to suppose a given class is more abstract or general than it is.&lt;br /&gt;
&lt;br /&gt;
Instead we can compose software from services and modules (packages—in the Ruby world these are gems) and reason about the interaction between those.&lt;br /&gt;
&lt;br /&gt;
A Facebook developer who works on the &lt;a href="https://facebook.github.io/react/"&gt;React&lt;/a&gt; project shared some &lt;a href="http://www.reddit.com/r/javascript/comments/1oo1y8/i_know_angularjs_are_there_any_reasons_i_should/cfsn41z"&gt;insights about package boundaries&lt;/a&gt; in a conversation about dependency injection. They isolate their tests at package boundaries rather than at a finer level. This matches the reality of code interactions better than pretending a test is always a first-class client of the code under test.&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
In my experience, DI is useful but has a cost in terms of code complexity. So we should only use it where appropriate. I think that for stuff that actually has multiple implementations (think a plugin system) it should be used (in fact, we use explicit DI in the React core for our &lt;a href="https://github.com/facebook/react/blob/master/src/browser/ReactDefaultInjection.js"&gt;pluggable rendering backends&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
But with testing I think DI is overkill. Whitebox testing, where you're testing the interface as well as the internals, tends to catch more bugs, but when you change the internals the test tends to change as well. So DI doesn't make much sense here, since part of the point of DI is to isolate parts of the implementation that don't change. So if you're doing it just for testing, you're effectively just over-engineering everything.&lt;br /&gt;
&lt;br /&gt;
Instead, we basically mock at a per-module level (sometimes called "service locator"). So for a given test run you can say that require('moduleA') should actually load moduleA-mock (dig around&amp;nbsp;&lt;a href="https://github.com/facebook/react/search?q=mock-modules&amp;amp;type=Code"&gt;mock-modules&lt;/a&gt;&amp;nbsp;to see what I mean).&lt;br /&gt;
&lt;br /&gt;
This has the advantage of not requiring refactoring of the production code just for testing. I've found that the "refactoring to support DI makes your code better" is a bunch of baloney in practice when you're trying to ship products (at least based on my experience at Facebook, where we DI'd all of our PHP tests starting in late 2011 and are now trying to dig ourselves out of the pit).&lt;br /&gt;
&lt;br /&gt;&lt;/blockquote&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/8625684193247409940" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/8625684193247409940" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/07/package-boundaries-are-big-deal.html" rel="alternate" title="Package boundaries are a big deal" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-4072970582856843973</id><published>2014-07-22T08:57:00.000-04:00</published><updated>2014-07-22T08:57:03.193-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Diversity vs. monoculture in systems…Linux systems</title><content type="html">Rachel Kroll explains potential pitfalls of oversimplifying when we automate. She advocates &lt;a href="https://rachelbythebay.com/w/2013/11/03/conf/"&gt;letting a few different solutions coexist and compete.&lt;/a&gt; There's some amount of waste that results; there's also a sizable amount of risk mitigation in a depth that would be truly hard to implement "on purpose" in a fully central plan.&lt;br /&gt;
&lt;br /&gt;
Diversity is healthy in any system—this applies equally to agriculture, education, and software teams as well as Linux system administration.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/4072970582856843973" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/4072970582856843973" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/07/diversity-vs-monoculture-in.html" rel="alternate" title="Diversity vs. monoculture in systems…Linux systems" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-7021255381438653710</id><published>2014-07-09T13:14:00.000-04:00</published><updated>2014-07-21T10:36:07.804-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Load path for a per-app namespace à la Corey Haines</title><content type="html">Corey Haines, an exponent of dependency-free testing in Rails apps, has suggested that all custom app logic be moved into its own namespace, and that namespace get its own directory under &lt;span style="font-family: Courier New, Courier, monospace;"&gt;app/&lt;/span&gt;. So a custom class &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Baz&lt;/span&gt; in an app called &lt;span style="font-family: Courier New, Courier, monospace;"&gt;foobar&lt;/span&gt; would be namespaced as &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Foobar::Baz&lt;/span&gt;, and the code would live in &lt;span style="font-family: Courier New, Courier, monospace;"&gt;app/foobar/baz.rb&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
A slightly non-obvious consequence of this is that while Rails picks up all subdirectories of &lt;span style="font-family: Courier New, Courier, monospace;"&gt;app/ &lt;/span&gt;in its class loading, it's expecting that any namespacing will occur &lt;i&gt;inside&lt;/i&gt;&amp;nbsp;those directories, not be expressed by those directory names themselves. If we just throw code in &lt;span style="font-family: Courier New, Courier, monospace;"&gt;app/foobar/baz.rb&lt;/span&gt;, it will expect a top-level &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Baz&lt;/span&gt; class to be there, not &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Foobar::Baz&lt;/span&gt;.&lt;br /&gt;
&lt;br /&gt;
One solution is to add a second &lt;span style="font-family: Courier New, Courier, monospace;"&gt;foobar&lt;/span&gt; subdirectory, so the code would now live in &lt;span style="font-family: Courier New, Courier, monospace;"&gt;app/foobar/foobar/baz.rb&lt;/span&gt;. That seems suboptimal.&lt;br /&gt;
&lt;br /&gt;
Instead we can add &lt;span style="font-family: Courier New, Courier, monospace;"&gt;app/ &lt;/span&gt;itself to &lt;span style="font-family: Courier New, Courier, monospace;"&gt;config.autoload_paths&lt;/span&gt; in &lt;span style="font-family: Courier New, Courier, monospace;"&gt;config/application.rb&lt;/span&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: Courier New, Courier, monospace;"&gt;config.autoload_paths += %W( #{config.root}/app )&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Then &lt;span style="font-family: Courier New, Courier, monospace;"&gt;app/foobar&lt;/span&gt; becomes eligible to house code in the &lt;span style="font-family: Courier New, Courier, monospace;"&gt;Foobar&lt;/span&gt; namespace.&lt;br /&gt;
&lt;br /&gt;
Maxim Chernyak has a &lt;a href="http://hakunin.com/rails3-load-paths"&gt;concise cheatsheet on Rails load paths&lt;/a&gt; that walks through the various gotchas lurking there.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/7021255381438653710" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/7021255381438653710" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/07/load-path-for-per-app-namespace-la.html" rel="alternate" title="Load path for a per-app namespace à la Corey Haines" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-3977371119159379630</id><published>2014-06-03T16:20:00.000-04:00</published><updated>2014-06-03T16:20:50.649-04:00</updated><title type="text">Getting past “what do I do?”</title><content type="html">It opens powerfully:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
A number of years ago the abbot of a monastery answered my question of vocation — whether I should get married or become a monk — with the startling words, “God doesn’t care.” He then added, “God only cares that you seek first his kingdom.”&lt;/blockquote&gt;
Still in the introduction it continues into very tough questions for anyone seeking to apply the Christian gospel:&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
Indeed, as Jesus instructs his disciples, we are not even to ask the questions “What shall we eat?” or “What shall we drink?” or “What shall we wear?” If we recognize that these questions are simply variations of the question “What shall we do?”, then we must face the notion that, according to Jesus, this kind of questioning is born out of anxiety and is not compatible with a life of discipleship. Regarding food, drink, clothing — and vocation — Jesus says clearly: seek first the Father’s kingdom and his righteousness and all these things shall be yours as well.&lt;/blockquote&gt;
And that’s only getting started. The article is &lt;a href="http://www.hchc.edu/studentlife/vocation/octev_resources/229"&gt;“Seek First His Kingdom”&lt;/a&gt;, by John Barnet of St. Vladimir’s Orthodox Theological Seminary.&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;
&lt;div id="stcpDiv" style="left: -1988px; position: absolute; top: -1999px;"&gt;
A
 number of years ago the abbot of a monastery answered my question of 
vocation — whether I should get married or become a monk — with the 
startling words, “God doesn’t care.” He then added, “God only cares that
 you seek first his kingdom.”
 - See more at: 
http://www.hchc.edu/studentlife/vocation/octev_resources/229#sthash.CJfy7CFo.dpuf&lt;/div&gt;
&lt;/blockquote&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/3977371119159379630" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/3977371119159379630" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/06/getting-past-what-do-i-do.html" rel="alternate" title="Getting past “what do I do?”" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-4854800466347115664</id><published>2014-06-03T15:20:00.000-04:00</published><updated>2014-06-03T16:04:50.883-04:00</updated><title type="text">Saint John of Kronstadt on reprimanding subordinates</title><content type="html">This makes excellent parenting advice, for only one application of such deeply insightful advice. I am seeking to apply it. At this writing the journey sounds long, but it will surely be worthwhile.&lt;br /&gt;
&lt;blockquote class="tr_bq"&gt;When reprimanding your subordinates for their faults, carefully  restrain yourself from anger, irritation, and disturbance, and be  gentle, full of love, dignified and quiet. If the subordinate you have  to correct takes offence, gently observe to him that you have no  intention of offending and irritating him, that you sincerely wish him  well, and that he should be orderly in his work, and that it is not him  that you are annoyed with, but the disorder that he occasions. Do not  offend his pride and dignity by exalting yourself in his eyes and  lowering him. If you have this weakness (pride) yourself, better leave the correction of another and first cure yourself: “First cast out the  beam out of thine own eye; and then shalt thou see clearly to cast out  the mote out of thy brother’s eye.” &lt;sup id="fnr1-2014-06-03t15"&gt;&lt;a href="#fn1-2014-06-03t15"&gt;1&lt;/a&gt;&lt;/sup&gt; In the opposite case you will only irritate your brother, and not do him any moral good. Be gentle and indulgent to others when you hear of their faults, remembering that you, too, have similar or greater faults. You reprove another, for  instance, for drunkenness; but if you drink yourself, or even if you do not drink, but indulge yourself with dainties, are given to gluttony, surfeiting, then you sin as much as he does. Correct yourself of your gluttony, and then you will be able to speak strongly against drunkenness in others. You accuse another of negligence in his service, but perhaps you yourself are also negligent. “Physician, heal  thyself.” &lt;sup id="fnr2-2014-06-03t15"&gt;&lt;a href="#fn2-2014-06-03t15"&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;footer&gt;&lt;cite&gt;Saint John of Kronstadt, &lt;a href="http://livingorthodoxfaith.blogspot.com/2009/11/on-pride-by-st-john-of-kronstadt.html"&gt;&lt;em&gt;On Pride&lt;/em&gt;&lt;/a&gt;&lt;/cite&gt;&lt;/footer&gt;&lt;/blockquote&gt;&lt;hr /&gt;&lt;div class="footnotes"&gt;&lt;ol&gt;&lt;li id="fn1-2014-06-03t15"&gt;St. Matthew 7:5.&amp;nbsp;&lt;a class="footnoteBackLink" href="#fnr1-2014-06-03t15" title="Jump back to footnote 1 in the text."&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;li id="fn2-2014-06-03t15"&gt;St. Luke 4:23.&amp;nbsp;&lt;a class="footnoteBackLink" href="#fnr2-2014-06-03t15" title="Jump back to footnote 2 in the text."&gt;↩&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;</content><link href="http://www.blogger.com/feeds/6930361/posts/default/4854800466347115664" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/4854800466347115664" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/06/saint-john-of-kronstadt-on-reprimanding.html" rel="alternate" title="Saint John of Kronstadt on reprimanding subordinates" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-8952708764337351772</id><published>2014-05-30T16:34:00.000-04:00</published><updated>2014-07-21T10:36:07.818-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Displaying a byline in Facebook shares</title><content type="html">In an effort to improve a site’s social media postings, I needed to simplify headlines (page titles) while maintaining credit for articles by authors outside the news team.&lt;br /&gt;
&lt;br /&gt;
I fooled around with schema.org &lt;code&gt;itemprop="creator"&lt;/code&gt;&amp;nbsp;and HTML5 &lt;code&gt;rel="author"&lt;/code&gt;, but they were both oriented toward hyperlinks rather than simply saying “here is the name of this article’s author”, which I need for this case.&lt;br /&gt;
&lt;br /&gt;
I noticed that New York Times articles bear their author’s names when posted to Facebook, so I endeavored to work out what Facebook looked at. Interestingly, I found this:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&amp;lt;meta name="byl" content="Fr. John Jillions"&amp;gt;&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
You can see the author attribution on &lt;a href="https://www.facebook.com/ryan.platte.7/posts/339410872876622"&gt;this Facebook post&lt;/a&gt; sharing such an article:&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://www.facebook.com/ryan.platte.7/posts/339410872876622"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja88b0O3VFZKrnziPQvebJ6JtgMa1Qw9fZJsKyHqfQUZcd3_35IV_ENXPg83Jkr0GerwNiN8iyx94WyXglqAustJm10YtL6sVPLLS_Aju4-8gmoS1FQi618Df_WHGyelA0kPt5CQ/s1600/Screen+Shot+2014-05-30+at+4.20.19+PM.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Thought I’d share, since I required original research to solve the problem. The only place I saw discussing this was an old &lt;a href="http://open.blogs.nytimes.com/2007/10/23/messing-around-with-metadata/"&gt;2007 NYT tech blog posting&lt;/a&gt;, and that only after I had the solution in place.&lt;br /&gt;
&lt;br /&gt;
Interestingly, I noticed an apparent Facebook A/B test take effect as I worked, changing the appearance of this article (and removing the byline). For a few minutes I didn’t have a way to see this author attribution, then within 5 minutes it was back. Life on the cutting edge.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/8952708764337351772" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/8952708764337351772" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/05/displaying-byline-in-facebook-shares.html" rel="alternate" title="Displaying a byline in Facebook shares" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEja88b0O3VFZKrnziPQvebJ6JtgMa1Qw9fZJsKyHqfQUZcd3_35IV_ENXPg83Jkr0GerwNiN8iyx94WyXglqAustJm10YtL6sVPLLS_Aju4-8gmoS1FQi618Df_WHGyelA0kPt5CQ/s72-c/Screen+Shot+2014-05-30+at+4.20.19+PM.png" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-3021572603658976837</id><published>2014-05-23T16:29:00.000-04:00</published><updated>2014-07-21T10:36:07.784-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">HN Retreat</title><content type="html">&lt;a href="https://news.ycombinator.com/news"&gt;Hacker News&lt;/a&gt; presents such wonderful and diverse articles, and its commenters are certainly&amp;nbsp;&lt;i&gt;sincere,&lt;/i&gt;&amp;nbsp;but sometimes I just want the articles and don’t want to get into the crowdsourced reaction.&lt;br /&gt;
&lt;br /&gt;
So I made a quick Chrome extension called&amp;nbsp;&lt;a href="https://chrome.google.com/webstore/detail/hn-retreat/lhoolldfedfpifkbahepgmijoagfpfko?utm_source=rpplatdad"&gt;HN Retreat&lt;/a&gt;. It turns off the comments on the home page of Hacker News.&lt;br /&gt;
&lt;br /&gt;
Aaron Patterson, a notably optimistic hacker I want to be more like when I grow up, actually &lt;i&gt;complained&lt;/i&gt;&amp;nbsp;on Twitter about his recent visit to Hacker News. &lt;a href="https://twitter.com/coreyhaines/status/469876596778995712"&gt;Corey Haines replied&lt;/a&gt; with a &lt;a href="https://gist.github.com/coreyhaines/4458959"&gt;bookmarklet&lt;/a&gt; that disables the second line of each post on the page. I tried it and liked it so much I thought I’d wrap it up. It turned out that I could implement the feature with a tiny snippet of CSS, so the extension doesn’t need any permissions beyond being allowed to run when the user visits Hacker News.&lt;br /&gt;
&lt;br /&gt;
It was fun seeing how fast I could turn around an idea to deployed product in an environment I’d never developed for before. Most of the time was spent on the packaging, so I’ll leave you with the artwork I cooked up.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://chrome.google.com/webstore/detail/hn-retreat/lhoolldfedfpifkbahepgmijoagfpfko?utm_source=rpplatdadimg"&gt;&lt;img alt="HN Retreat" border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBMf0RUTaFN06yOdHCuRN4vV2s3S0iczScvpyHe-7Yy8bRI0zXd4RGyU8cao755B95UwW-wYI4zPI8zQQMRdsbpu40x_kw3X06LNl4q2T1kkT2kojjfHerHeuOZlAK3cDJrO-wQA/s1600/hn_retreat_small_promo.png" height="137" title="" width="400" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;span id="goog_1660112449"&gt;&lt;/span&gt;&lt;span id="goog_1660112450"&gt;&lt;/span&gt;&lt;br /&gt;
And in some sort of strange self-referential completeness, &lt;a href="https://news.ycombinator.com/item?id=7791016"&gt;here’s the HN comment thread&lt;/a&gt; to discuss this extension. Of course, at this writing, it’s empty.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/3021572603658976837" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/3021572603658976837" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/05/hn-retreat.html" rel="alternate" title="HN Retreat" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiBMf0RUTaFN06yOdHCuRN4vV2s3S0iczScvpyHe-7Yy8bRI0zXd4RGyU8cao755B95UwW-wYI4zPI8zQQMRdsbpu40x_kw3X06LNl4q2T1kkT2kojjfHerHeuOZlAK3cDJrO-wQA/s72-c/hn_retreat_small_promo.png" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-3319876493807127759</id><published>2014-05-14T10:51:00.000-04:00</published><updated>2014-07-21T10:36:07.787-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">An elegant page header</title><content type="html">As I rekindle my lifelong interest in design, I’m keeping my eyes peeled for refreshing, effective visual approaches. Last thing I want to do is mindlessly parrot The Look of the Moment and become part of the problem.&lt;br /&gt;
&lt;br /&gt;
I enjoyed this header on Nicholas Nethercote’s blog. Logical, just enough white space, nice priority of attention, no frills…and Bodoni.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOs2YcgONxjegQqCcOMQvVY-J1wXRGeuABDLXASdl46au8bt11ThinAHFkOkkIsqsyTFLs7Hg5fS11r8DYA4zkJH_NoZGcIw53uT5XEwhjvan7pr2wl3Ie-DVAJW3SFCqjJ_pgNQ/s1600/Screen+Shot+2014-05-14+at+10.36.35+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOs2YcgONxjegQqCcOMQvVY-J1wXRGeuABDLXASdl46au8bt11ThinAHFkOkkIsqsyTFLs7Hg5fS11r8DYA4zkJH_NoZGcIw53uT5XEwhjvan7pr2wl3Ie-DVAJW3SFCqjJ_pgNQ/s1600/Screen+Shot+2014-05-14+at+10.36.35+AM.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
It’s a minor but excellent departure from the default Helvetica in Automattic’s &lt;i&gt;Coraline&lt;/i&gt;&amp;nbsp;theme—the delicate serifs pair better with that theme’s photo.&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;
&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4D8Slno24XJCW4ospKtFfkXAY3tvXoM4UzrvxZR3NfEZtHOMXyAn2MjwBa_UqDe5ubDYVuuq4ghQ0W5dj_sUS_63h7ETAGKkYz1pgRcjzcbwbSxI6qfZck9HsJHDI9jU0Rf8Wg/s1600/Screen+Shot+2014-05-14+at+10.48.00+AM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4D8Slno24XJCW4ospKtFfkXAY3tvXoM4UzrvxZR3NfEZtHOMXyAn2MjwBa_UqDe5ubDYVuuq4ghQ0W5dj_sUS_63h7ETAGKkYz1pgRcjzcbwbSxI6qfZck9HsJHDI9jU0Rf8Wg/s1600/Screen+Shot+2014-05-14+at+10.48.00+AM.png" /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class="separator" style="clear: both; text-align: left;"&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/3319876493807127759" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/3319876493807127759" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/05/an-elegant-page-header.html" rel="alternate" title="An elegant page header" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOs2YcgONxjegQqCcOMQvVY-J1wXRGeuABDLXASdl46au8bt11ThinAHFkOkkIsqsyTFLs7Hg5fS11r8DYA4zkJH_NoZGcIw53uT5XEwhjvan7pr2wl3Ie-DVAJW3SFCqjJ_pgNQ/s72-c/Screen+Shot+2014-05-14+at+10.36.35+AM.png" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-7652205286681193060</id><published>2014-05-03T08:24:00.002-04:00</published><updated>2014-05-03T08:24:55.753-04:00</updated><title type="text">Who put Kurzweil in charge of Google Docs?</title><content type="html">So I peek into a publicly-shared Google document, and I see this:&lt;br /&gt;
&lt;br /&gt;
&lt;table cellpadding="0" cellspacing="0" class="tr-caption-container" style="margin-left: auto; margin-right: auto; text-align: center;"&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style="text-align: center;"&gt;&lt;a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB8MDsI6A8RGe0oJXF5zBhVXx9nbHDbeyRvF2TnbKSC8rOQiU8FkoK9L7TmyE9ZNmMLI6ofuP2mwfLhVOzbeiXJ58Vhph5nIXKrUqbLIo_oMUPeCHqAU7e3dU3oiretfZ8zL2Cxg/s1600/Screen+Shot+2014-05-03+at+8.11.52+AM.png" imageanchor="1" style="clear: left; margin-bottom: 1em; margin-left: auto; margin-right: auto;"&gt;&lt;img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB8MDsI6A8RGe0oJXF5zBhVXx9nbHDbeyRvF2TnbKSC8rOQiU8FkoK9L7TmyE9ZNmMLI6ofuP2mwfLhVOzbeiXJ58Vhph5nIXKrUqbLIo_oMUPeCHqAU7e3dU3oiretfZ8zL2Cxg/s1600/Screen+Shot+2014-05-03+at+8.11.52+AM.png" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class="tr-caption" style="text-align: center;"&gt;On hover, these are named "Anonymous Coyote", "Anonymous Ibex", etc.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
Being a human exceptionalist, of the firm persuasion that coyotes and ibexes etc. are lower life forms that cannot e.g. use spreadsheets, this not-very-subtle push of &lt;a href="https://en.wikipedia.org/wiki/Ray_Kurzweil#Encouraging_futurism_and_transhumanism"&gt;Google's transhumanist agenda&lt;/a&gt; leaves a nasty taste in my mouth.&lt;br /&gt;
&lt;br /&gt;
Just as people are not mere "resources", people should not be labeled as animals involuntarily. This is a shared service and isn't an appropriate place for someone's creed to be imposed on another. Fix it, Google.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/7652205286681193060" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/7652205286681193060" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/05/who-put-kurzweil-in-charge-of-google.html" rel="alternate" title="Who put Kurzweil in charge of Google Docs?" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" height="72" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgB8MDsI6A8RGe0oJXF5zBhVXx9nbHDbeyRvF2TnbKSC8rOQiU8FkoK9L7TmyE9ZNmMLI6ofuP2mwfLhVOzbeiXJ58Vhph5nIXKrUqbLIo_oMUPeCHqAU7e3dU3oiretfZ8zL2Cxg/s72-c/Screen+Shot+2014-05-03+at+8.11.52+AM.png" width="72"/></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-3105647656860261079</id><published>2014-04-16T10:00:00.000-04:00</published><updated>2014-04-16T10:00:07.266-04:00</updated><title type="text">Study: facts don't get much say</title><content type="html">&lt;a href="http://www.alternet.org/media/most-depressing-discovery-about-brain-ever"&gt;This phenomenon&lt;/a&gt;&amp;nbsp;must be why it's so unproductive to argue about controversial facts.&lt;br /&gt;
&lt;br /&gt;
An alternative way of looking at this is that it's a natural defense against disinformation. If people's different perspectives suddenly vanished as soon as all information sources agreed, we'd miss opportunities for local adaptation and disruptive innovation.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/3105647656860261079" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/3105647656860261079" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/04/study-facts-dont-get-much-say.html" rel="alternate" title="Study: facts don't get much say" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-3428222618869369278</id><published>2014-04-15T16:24:00.000-04:00</published><updated>2014-04-18T09:34:04.405-04:00</updated><title type="text">Calculating position of the sun</title><content type="html">I'm studying permaculture design. Its goal is to set up virtuous, sustainable ecological cycles that work to the benefit of everyone. One of the basic pieces of information that's needed is direction of the sun during the course of the year.&lt;br /&gt;
&lt;br /&gt;
I'd looked at this before and eventually figured it out, but Vladimir Agafonkin has given the world a wonderful site called SunCalc that overlays sunlight information on a Google map.&lt;br /&gt;
&lt;br /&gt;
For an example,&amp;nbsp;&lt;a href="http://www.suncalc.net/#/43.021,-77.5742,19/2014.03.20/12:00"&gt;here's a nearby park at noon this past vernal equinox.&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
With the use of that plus &lt;a href="http://planetcalc.com/1875/"&gt;this shadow length calculator,&lt;/a&gt; I was able to figure out a lot about sunlight and shade on my property.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/3428222618869369278" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/3428222618869369278" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/04/calculating-position-of-sun.html" rel="alternate" title="Calculating position of the sun" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-953967898446466428</id><published>2014-04-15T09:04:00.001-04:00</published><updated>2014-04-15T09:04:12.533-04:00</updated><title type="text">Teenagers deleting all but their latest post on Facebook</title><content type="html">I'd seen this before and wanted to save it:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://www.zephoria.org/thoughts/archives/2010/11/08/risk-reduction-strategies-on-facebook.html"&gt;Risk Reduction Strategies on Facebook&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
It describes some interesting online behavior in teenagers and other groups, including:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;deactivating their accounts as a kind of "super-logoff" (putting the user in control of their online interactions)&lt;/li&gt;
&lt;li&gt;deleting posts and comments as a kind of "inbox zero" that limits the exposed surface area (averting jealousy and various kinds of attacks)&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
With this it's important to note that on Facebook, as in many places, the delete functionality &lt;a href="http://news.bbc.co.uk/2/hi/8060407.stm"&gt;doesn't mean the data isn't kept.&lt;/a&gt;&amp;nbsp;What interests me is that these teens had further reasons for their cautious actions.&lt;/div&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/953967898446466428" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/953967898446466428" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2014/04/teenagers-deleting-all-but-their-latest.html" rel="alternate" title="Teenagers deleting all but their latest post on Facebook" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-552654598489497993</id><published>2012-12-14T08:22:00.001-05:00</published><updated>2012-12-14T08:22:53.174-05:00</updated><title type="text">Lutheran pastor defending the title “Mother of God”</title><content type="html">This was good to see. He even covers the incorrect title &lt;i&gt;Christotokos&lt;/i&gt;.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/552654598489497993" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/552654598489497993" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2012/12/lutheran-pastor-defending-title-mother.html" rel="alternate" title="Lutheran pastor defending the title “Mother of God”" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-6995080089511922700</id><published>2012-09-06T15:40:00.003-04:00</published><updated>2014-07-21T10:36:07.801-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Setting viewport size with WebPagetest</title><content type="html">One of the pitfalls of responsive web design is that it’s easy to create mobile sites that are simplified for small screens and touch interaction but aren’t any lighter on bandwidth and memory than their full-size relatives.&lt;br /&gt;
&lt;br /&gt;
There’s an &lt;a href="http://www.webpagetest.org/forums/showthread.php?tid=11046"&gt;undocumented&lt;/a&gt; option in &lt;a href="http://www.webpagetest.org/"&gt;WebPagetest&lt;/a&gt; to check page loads at arbitrary viewport sizes.&lt;br /&gt;
&lt;br /&gt;
From slide 50 of the same &lt;a href="http://www.slideshare.net/guypod/performance-implications-of-mobile-design"&gt;slide deck&lt;/a&gt; I mentioned in my last post:&lt;br /&gt;
&lt;blockquote&gt;
&lt;h2&gt;
Run webpagetest script with resizing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use Chrome as agent (not supported on other browsers)&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Sample script (tab delimited):&lt;br /&gt;
&lt;code&gt;&lt;pre&gt;setviewportsize   320  480
navigate http://example.com/&lt;/pre&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
</content><link href="http://www.blogger.com/feeds/6930361/posts/default/6995080089511922700" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/6995080089511922700" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2012/09/setting-viewport-size-with-webpagetest.html" rel="alternate" title="Setting viewport size with WebPagetest" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-7809660994308823458</id><published>2012-09-06T15:29:00.000-04:00</published><updated>2014-07-21T10:36:07.811-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">What does “mdot” mean?</title><content type="html">Reviewing an excellent slide deck about &lt;a href="http://www.slideshare.net/guypod/performance-implications-of-mobile-design"&gt;how to improve the performance of responsive web sites,&lt;/a&gt; I encountered the term “mdot” and was mystified.&lt;br /&gt;
&lt;br /&gt;
It refers to the “&lt;code&gt;m.&lt;/code&gt;” that often begins the URLs of mobile-only websites.&lt;br /&gt;
&lt;br /&gt;
Most folks who mention it out there just use it without defining it. I just had to try a lot of searches to figure this one out, so I thought I'd try to help by telling Google explicitly.</content><link href="http://www.blogger.com/feeds/6930361/posts/default/7809660994308823458" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/7809660994308823458" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2012/09/what-does-mdot-mean.html" rel="alternate" title="What does “mdot” mean?" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-6984273084975805164</id><published>2012-06-26T14:07:00.000-04:00</published><updated>2014-07-21T10:36:07.798-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">Notes from the Velocity conference</title><content type="html">I am so delighted that O'Reilly is making a live stream of talks at the Velocity conference. I can't justify the expense yet but I and my clients have many of the same needs as the folks in the room there.&lt;br /&gt;
&lt;br /&gt;
Here's a number of wonderful bits I picked up from what I've been able to watch:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;The 99th percentile, or another percentile "deep into the long tail", is much more responsive to condition changes than is the median. Monitor that when possible.&lt;/li&gt;
&lt;li&gt;There's a lot of time between when a user begins to express their intention (by typing the URL or their search query) and when they act on it, so that idle time is a potential moment we can use to improve load speeds if we can figure out how to use it. Google Chrome uses prerendering with both Omnibox and Google search result pages. It sounds like a very good idea to help Firefox, Chrome, and any other browser that clues in on this with some &lt;a href="https://developers.google.com/chrome/whitepapers/prerender"&gt;&amp;lt;link rel="prefetch"&amp;gt; and &amp;lt;link rel="prerender"&amp;gt; tags&lt;/a&gt; when we have a strong hint where the user will go next.&lt;/li&gt;
&lt;li&gt;There's a &lt;a href="https://developers.google.com/chrome/whitepapers/pagevisibility"&gt;Page Visibility API.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;IE now exposes information about a "restarted tokenizer", offering insight into how to make it better able to load things earlier. The speaker said that the IE Blog has more info; it looks like that might be referring to &lt;a href="http://blogs.msdn.com/b/ieinternals/archive/2011/07/18/optimal-html-head-ordering-to-avoid-parser-restarts-redownloads-and-improve-performance.aspx?PageIndex=2"&gt;this post&lt;/a&gt; or perhaps&amp;nbsp;&lt;a href="http://blogs.msdn.com/b/fiddler/archive/2011/02/10/fiddler-is-better-with-internet-explorer-9.aspx"&gt;this one about the Fiddler tool.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;WebPageTest has iPhone testing and ever-deeper tooling, including downloading detailed Chrome timeline information. Thanks to Akamai for open-sourcing the Blaze.io code that makes this possible!&lt;/li&gt;
&lt;li&gt;Google PageSpeed Insights has a Critical Path Explorer that traces asset loading to its cause, documenting what the blocking elements are.&lt;/li&gt;
&lt;li&gt;The book "How Complex Systems Fail" is reportedly critical reading. "Resilience engineering."&lt;/li&gt;
&lt;/ul&gt;</content><link href="http://www.blogger.com/feeds/6930361/posts/default/6984273084975805164" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/6984273084975805164" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2012/06/notes-from-velocity-conference.html" rel="alternate" title="Notes from the Velocity conference" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry><entry><id>tag:blogger.com,1999:blog-6930361.post-2184205580766073173</id><published>2012-06-07T18:26:00.002-04:00</published><updated>2014-07-21T10:36:07.778-04:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Software"/><title type="text">(Ab)using Google Analytics user timings to track SQL queries</title><content type="html">A client has been suffering unstable system load. One big root cause is that lot of overly-complex queries fire off for each page. We're improving matters, but we wanted to grab some metrics to prioritize our efforts.&lt;br /&gt;
&lt;br /&gt;
We tried custom variables, but found it frustrating that they didn't let us link to the right page, and dealt with our values as strings rather than numbers.&lt;br /&gt;
&lt;br /&gt;
So we're using the new user timings so we can sort pages by their number of queries and get a ranked list of which pages are causing the most load. We just pretend each query is a millisecond when we call Google Analytics:&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-ident" style="box-sizing: border-box; color: black;"&gt;_gaq&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;.&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-ident" style="box-sizing: border-box; color: black;"&gt;push&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;([&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-string" style="box-sizing: border-box; color: #c41a16;"&gt;'_trackTiming'&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;,&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-string" style="box-sizing: border-box; color: #c41a16;"&gt;'Other Metrics'&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;,&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-string" style="box-sizing: border-box; color: #c41a16;"&gt;'Database Queries'&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;,&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-number" style="box-sizing: border-box; color: #1c00cf;"&gt;&amp;lt;?= // number of queries here ?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;,&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-ident" style="box-sizing: border-box; color: black;"&gt;window&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;.&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-ident" style="box-sizing: border-box; color: black;"&gt;location&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;.&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;&lt;span class="webkit-javascript-ident" style="box-sizing: border-box; color: black;"&gt;pathname&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="-webkit-text-size-adjust: none; font-family: Menlo, monospace; font-size: 11px; white-space: pre;"&gt;])&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Then we get a nice list of URIs sortable by the average number of queries that render each page. The number tracks over time, so you can drill down to a particular page to see if the number is changing over time.&lt;br /&gt;
&lt;br /&gt;
We plan to add New Relic monitoring into the mix sometime soon, but it was fun to try it this way.&lt;br /&gt;
&lt;br /&gt;
I was really surprised at how poorly the various metrics integrate in Google Analytics. I really expected to have a way to toss a value on a pageview and be able to treat it like just another data point, but it really doesn't work that way at all. It didn't look like event values were going to solve it either, though maybe those would work just like this wound up working—I thought of the window.location.pathname bit last (I'd been hoping to key off the underlying view file instead, but couldn't make that work quickly).</content><link href="http://www.blogger.com/feeds/6930361/posts/default/2184205580766073173" rel="edit" type="application/atom+xml"/><link href="http://www.blogger.com/feeds/6930361/posts/default/2184205580766073173" rel="self" type="application/atom+xml"/><link href="http://daddy.platte.name/2012/06/abusing-google-analytics-user-timings.html" rel="alternate" title="(Ab)using Google Analytics user timings to track SQL queries" type="text/html"/><author><name>Unknown</name><email>noreply@blogger.com</email><gd:image height="16" rel="http://schemas.google.com/g/2005#thumbnail" src="https://img1.blogblog.com/img/b16-rounded.gif" width="16"/></author></entry></feed>