<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Regarding Rebecca Regarding Things]]></title>
  <link href="http://re-becca.org//atom.xml" rel="self" />
  <link href="http://re-becca.org/" />
  <updated>2019-04-14T18:35:51-07:00</updated>
  <id>http://re-becca.org/</id>
  <author>
    <name><![CDATA[Rebecca Turner]]></name>
    <email><![CDATA[me@re-becca.org]]></email>
  </author>
  <generator uri="https://github.com/jmacdotorg/plerd">Plerd</generator>


  <entry>
    <title type="html"><![CDATA[Welcome back old friend]]></title>
    <link href="http://re-becca.org/2018-08-11-welcome-back-old-friend.html"/>
    <published>2018-08-11T20:29:14-07:00</published>
    <updated>2018-08-11T20:29:14-07:00</updated>
    <id>http://re-becca.org/2018-08-11-welcome-back-old-friend.html</id>
    <content type="html"><![CDATA[<p>It’s been well over three years since I had a real blog post on this domain,
but it’s time to come back and maybe be something better.  I’ve ported over
all of the real posts from the old Wordpress blog.  Going forward this site
is running <a href="http://jmac.org/plerd/">Plerd</a>, by the always worth watching
<a href="http://jmac.org/">Jason McIntosh</a>.  It’s Yet Another static blog from
markdown genertor, but it’s intended workflow mathes cleanly with mine and
I like its default themes.  You can give his blog a follow at
<a href="http://fogknife.com/">Fogknife</a>.</p>

<p>I use <a href="https://www.resilio.com/">Resilio Sync</a> to copy the
generated site up to my VPS, where I serve the static content.  (Think
Dropbox, but only going to your own systems.)</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Publish-Only Shrinkwrap]]></title>
    <link href="http://re-becca.org/2015-01-12-publish-only-shrinkwrap.html"/>
    <published>2015-01-12T16:22:00-08:00</published>
    <updated>2018-08-11T20:27:19-07:00</updated>
    <id>http://re-becca.org/2015-01-12-publish-only-shrinkwrap.html</id>
    <content type="html"><![CDATA[<p><em>Edit: It’s worth pointing out that freezing versions in libraries is not generally recommended (though this is a matter of community contention).  Further publishing anything to the public registry with a shrinkwrap causes problems for people with private registry mirrors as the shrinkwrap encodes the public registry url. Obviously, if your organization has decided to freeze its libraries then publishing shrinkwraps to your own <a href="https://www.npmjs.com/enterprise">private registry like npme</a> or as <a href="https://www.npmjs.com/private-npm">private modules</a> is quite alright.</p>

<p>Some people also feel that shrinkwraps MUST be checked into git, so that you can recreate published archives from the git repository. Some do not. Obviously you need to fit things to your workflow and your release practices.</em></p>

<p>npm’s shrinkwrap feature provides a key benefit when it comes to supporting published code– it fixes all of the dependency versions for all of your dependencies AND THEIR dependencies.  This means that you can be sure that your end users are using exactly the same software as you are.</p>

<p>But shrinkwrap can also be frustrating to use because as long as the npm-shrinkwrap.json file is laying around npm won’t behave the same as it usually does.</p>

<p>What this does, is only include the npm-shrinkwrap.json in the published artifact. This means that your development will get newer versions of your dependencies to test, while your users will get exactly what you tested with at the time you published.</p>

<h3>How To</h3>

<p>“`
$ npm install -g npm-script
…
$ npm install —save-dev in-publish rimraf
…
$ npm-script set prepublish “in-publish &amp;&amp; npm shrinkwrap || in-install”
set: prepublish
$ npm-script set postpublish “rimraf npm-shrinkwrap.json”
set: postpublish
$ npm publish</p>

<blockquote>
  <p>your-module@1.0.0 prepublish …
  in-publish &amp;&amp; npm shrinkwrap || in-install</p>
</blockquote>

<p>npm WARN shrinkwrap Excluding devDependency: in-publish
npm WARN shrinkwrap Excluding devDependency: rimraf
wrote npm-shrinkwrap.json
+ your-module@1.0.0</p>

<blockquote>
  <p>your-module@1.0.0 postpublish .
  rimraf npm-shrinkwrap.json</p>
</blockquote>

<p>“`</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Multi-stage installs and a better npm]]></title>
    <link href="http://re-becca.org/2014-09-23-multi-stage-installs-and-a-better-npm.html"/>
    <published>2014-09-23T06:00:00-07:00</published>
    <updated>2018-08-11T20:27:19-07:00</updated>
    <id>http://re-becca.org/2014-09-23-multi-stage-installs-and-a-better-npm.html</id>
    <content type="html"><![CDATA[<p><em>(Originally posted to the <a href="http://blog.npmjs.org/post/98233700815/multi-stage-installs-and-a-better-npm">npm blog</a>, the <a href="https://github.com/iarna/essays/blob/master/complete/npm-multi-stage-install.md">source is on Github</a>.)</em></p>

<p>Hi everyone! I’m the new programmer at npm working on the CLI. I’m really excited that my first major project is going to be a substantial refactor to how npm handles dependency trees.  We’ve been calling this thing <a href="https://github.com/npm/npm/milestones/multi-stage%20install">multi-stage install</a> but really it covers more than just installs.</p>

<p>Multi-stage installs will touch and improve all of the actions npm takes relating to dependencies and mutating your node_modules directory.  This affects <a href="https://www.npmjs.org/doc/cli/npm-install.html">install</a>, <a href="https://www.npmjs.org/doc/cli/npm-uninstall.html">uninstall</a>, <a href="https://www.npmjs.org/doc/cli/npm-dedupe.html">dedupe</a>, <a href="https://www.npmjs.org/doc/cli/npm-shrinkwrap.html">shrinkwrap</a> and, obviously, <a href="https://www.npmjs.org/doc/files/package.json.html#dependencies">dependencies</a> (including <a href="https://www.npmjs.org/doc/files/package.json.html#optionaldependencies">optionalDependencies</a>, <a href="https://www.npmjs.org/doc/files/package.json.html#peerdependencies">peerDependencies</a>, <a href="https://www.npmjs.org/doc/files/package.json.html#bundleddependencies">bundledDependencies</a> and <a href="https://www.npmjs.org/doc/files/package.json.html#devdependencies">devDependencies</a>).</p>

<p>The idea is simple enough: Build an in-memory model of how we want the node_modules directories to look.  Compare that model to what’s on disk, producing a list of steps to change the disk version into the memory model. Finally, we execute the steps in the list.</p>

<p>The refactor gives several needed improvements: It gives us knowledge of the dependency tree and what we need to do prior to touching your node_modules directory.  This means we can give simple errors, earlier, much improving the experience of this failure case.  Further, deduping and recursive dependency resolution are then easy to include.  And by breaking down the actual act of installing new modules into functional pieces, we eliminate the opportunity for many of the race conditions that have plagued us recently.</p>

<p>Breaking changes: The refactor will likely result in a new major version as we will almost certainly be tweaking <a href="https://www.npmjs.org/doc/misc/npm-scripts.html">lifecycle script</a> behavior.  At the very least, we’ll be running each lifecycle step as its own stage in the multi-stage install.</p>

<p>But wait, there’s more! The refactor will make implementing a number of oft-requested features a lot easier– some of the issues we intend to address are:</p>

<ul>
<li>Progress bars! <a href="https://github.com/npm/npm/issues/1257">#1257</a>, <a href="https://github.com/npm/npm/issues/5340">#5340</a></li>
<li>Automatic/intrinsic dedupe, across all module source types <a href="https://github.com/npm/npm/issues/4761">#4761</a>, <a href="https://github.com/npm/npm/issues/5827">#5827</a></li>
<li>Errors if we can’t find compatible versions MUCH earlier, before any changes to your node_modules directory have happened <a href="https://github.com/npm/npm/issues/5107">#5107</a></li>
<li>Better diagnostics when peerDependencies produce impossible to resolve scenarios.</li>
<li>Better use of bundledDependencies</li>
<li>Recursively resolving missing dependencies <a href="https://github.com/npm/npm/issues/1341">#1341</a></li>
<li>Better shrinkwrap <a href="https://github.com/npm/npm/issues/2649">#2649</a></li>
<li>Fixes some icky edge cases [#3124], <a href="https://github.com/npm/npm/issues/5698">#5698</a>, <a href="https://github.com/npm/npm/issues/5655">#5655</a>, <a href="https://github.com/npm/npm/issues/5400">#5400</a></li>
<li>Better shrinkwrap support, including updating of shrinkwrap file when you use —save on your installs and uninstalls <a href="https://github.com/npm/npm/issues/5448">#5448</a>, <a href="https://github.com/npm/npm/issues/5779">#5779</a></li>
<li>Closer to transactional installs <a href="https://github.com/npm/npm/issues/5984">#5984</a></li>
</ul>

<p>So when will you get to see this? I don’t have a timeline yet– I’m still in the part of the project where everything I look at fractally expands into yet more work.  You can follow along with progress on what will be its <a href="https://github.com/npm/npm/pull/6191">pull request</a></p>

<p>If you’re interested in that level of detail, you may also be interested in reading <a href="https://twitter.com/izs">@izs</a>’s and <a href="https://twitter.com/othiym23">@othiym23</a>’s <a href="https://github.com/npm/npm/issues/5919">thoughts</a>.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Abraxas– A node.js Gearman client/worker/admin library]]></title>
    <link href="http://re-becca.org/2014-06-30-abraxas-a-nodejs-gearman-clientworkeradmin-library.html"/>
    <published>2014-06-30T03:20:00-07:00</published>
    <updated>2018-08-11T20:27:19-07:00</updated>
    <id>http://re-becca.org/2014-06-30-abraxas-a-nodejs-gearman-clientworkeradmin-library.html</id>
    <content type="html"><![CDATA[<p>Abraxas is an end-to-end streaming Gearman client and worker library for Node.js. (Server implementation coming soon.)</p>

<p><a href="https://www.npmjs.org/package/abraxas">https://www.npmjs.org/package/abraxas</a></p>

<p>Standout features:</p>

<ul>
    <li>Support for workers handling multiple jobs at the same time over a single connection. This is super useful if your jobs tend to be bound by external resources (eg databases).</li>
    <li>Built streaming end-to-end from the start, due to being built on <a href="https://www.npmjs.org/package/gearman-packet">gearman-packet</a>.</li>
    <li>Most all APIs support natural callback, stream and promise style usage.</li>
    <li>Support for the gearman admin commands to query server status.</li>
    <li>Delayed background job execution built in, with recent versions of the C++ gearmand.</li>
</ul>

<p>Things I learned on this project:</p>

<ul>
    <li>Nothing in the protocol stops clients and workers from sharing the same connection. This was imposed by arbitrary library restrictions.</li>
    <li>In fact, the plain text admin protocol can be included cleanly on the same connection as the binary protocol.</li>
    <li>Nothing stops workers from handling multiple jobs at the same time, except, again, arbitrary library restrictions.</li>
    <li>The protocol documentation on gearman.org is out of date when compared to the C++ gearmand implementation– notably, SUBMIT_JOB_EPOCH has been implemented. I’ve begun updating the protocol documentation here:
<a href="https://github.com/iarna/gearman-packet/blob/master/PROTOCOL.md">https://github.com/iarna/gearman-packet/blob/master/PROTOCOL.md</a></li>
</ul>

<p>Because everything is a stream, you can do things like this:</p>

<pre class="lang:js decode:true">process.stdin.pipe(client.submitJob('toUpper')).pipe(process.stdout);
</pre>

<p>Or as a promise:</p>

<pre class="lang:js decode:true">client.submitJob('toUpper', 'test string').then(function (result) {
    console.log("Upper:", result);
});</pre>

<p>Or as a callback:</p>

<pre class="lang:js decode:true">client.submitJob('toUpper', 'test string', function(error, result) {
    if (error) console.error(error);
    console.log("Upper:", result);
});</pre>

<p>Or mix and match:</p>

<pre class="lang:js decode:true">process.stdin.pipe(client.submitJob('toUpper')).then(function(result) {
    console.log("Upper:", result);
});</pre>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[MySQL ROUND considered harmful]]></title>
    <link href="http://re-becca.org/2014-05-22-mysql-round-considered-harmful.html"/>
    <published>2014-05-22T11:57:00-07:00</published>
    <updated>2018-08-11T20:27:19-07:00</updated>
    <id>http://re-becca.org/2014-05-22-mysql-round-considered-harmful.html</id>
    <content type="html"><![CDATA[<p>MySQL’s ROUND has different behavior for DECIMALs than it does for FLOATs and DOUBLEs. </p>

<p>This <em>is</em> <a href="https://dev.mysql.com/doc/refman/5.0/en/mathematical-functions.html#function_round">documented</a>. The reason for this is not discussed but it’s important.  ROUND operates by altering the type of the expression to have the number of decimal places that it was passed. And this matters because the type information associated with a DOUBLE will bleed… it taints the rest of the expression:</p>

<p>We’re going to start with some simple SQL:</p>

<pre class="lang:mysql decode:true">mysql&gt; SELECT 2.5 * 605e-2;
+--------------+
| 2.5 * 605e-2 |
+--------------+
|       15.125 |
+--------------+
1 row in set (0.00 sec)</pre>

<p>Here 2.5 is a DECIMAL(2,1) and 605e-2 a DOUBLE, and the result is a DOUBLE.  That’s all well and good…</p>

<p>But let’s try rounding 605e-2.</p>

<pre class="lang:mysql decode:true">mysql&gt; SELECT 2.5 * ROUND(605e-2,2);
+-----------------------+
| 2.5 * ROUND(605e-2,2) |
+-----------------------+
|                 15.12 |
+-----------------------+
1 row in set (0.00 sec)</pre>

<p>So… what’s going on here? The round part of the expression shouldn’t have changed its value.  And in fact, it hasn’t, calling <code>ROUND(605e-2,2)</code> returns 6.05 as expected.  The problem here is that the type of <code>ROUND(605e-2,2)</code> is <code>DOUBLE(19,2)</code> and when that’s multiplied by 2.5 the resulting expression is still <code>DOUBLE(19,2)</code>.  But the number of decimals on a float is for display purposes only– internally MySQL keeps full precision… we can prove that this way:</p>

<pre class="lang:mysql decode:true">mysql&gt; SELECT ROUND(2.5 * ROUND(605e-2,2),3);
+--------------------------------+
| ROUND(2.5 * ROUND(605e-2,2),3) |
+--------------------------------+
|                         15.125 |
+--------------------------------+
1 row in set (0.00 sec)</pre>

<p>So yeah… MySQL let’s you increase precision with ROUND– Postgres is looking mighty fine right now.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Survey of node.js Gearman modules]]></title>
    <link href="http://re-becca.org/2014-04-02-survey-of-nodejs-gearman-modules.html"/>
    <published>2014-04-02T10:54:00-07:00</published>
    <updated>2018-08-11T20:08:44-07:00</updated>
    <id>http://re-becca.org/2014-04-02-survey-of-nodejs-gearman-modules.html</id>
    <content type="html"><![CDATA[<p>Here’s a brief survey of node.js Gearman modules.  I’ll have some analysis based on this later.</p>

<p><style> 
 #survey { border-spacing: 0; border-collapse: collapse; border: solid black 1px; } 
 #survey th { text-decoration: underline; } 
 #survey td.note { font-style: italic; font-size: 90%; border-top: none } 
 #survey .issues { text-align: right; } 
 #survey th,td { 
 border-top: solid black 1px; 
 border-left: solid black 1px; 
 border-right: solid black 1px; 
 padding: .3em; 
 } 
 #survey tr:last-child td { border-bottom: solid black 1px; } 
 #survey .last-commit { min-width: 6em; }
</style> </p>

<div style="overflow: scroll"> 
<table id="survey"> 
 <thead> 
<tr><th>Module</th><th>Github</th><th>Author</th><th>Last<br>Commit</th><th>Open<br>Issues</th><th>Tests</th><th>Docs</th><th>Client</th><th>Worker</th><th>Multi<br>Server</th><th>Streams</th><th>Errors</th><th>Timeouts</th></tr> 
 </thead> 
 <tbody> 
<tr><td><a href="https://www.npmjs.org/package/gearman">gearman</a></td><td><a href="https://github.com/gofullstack/gearman-node">gofullstack/gearman-node</a></td><td><a href="https://www.npmjs.org/~smith">smith</a>, <a href="https://www.npmjs.org/~gearmanhq">gearmanhq</a></td><td class="last-commit">2011-05-02</td><td class="issues">4</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☐</td><td>☐</td><td>☑</td><td>☐</td></tr> 
<tr><td><a href="https://www.npmjs.org/package/gearman-stream">gearman-stream</a></td><td><a href="https://github.com/Clever/gearman-stream">Clever/gearman-stream</a></td><td><a href="https://www.npmjs.org/~azylman">azylman</a>, <a href="https://www.npmjs.org/~templaedhel">templaedhel</a></td><td class="last-commit">2014-03-21</td><td class="issues">0</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☑</td><td>☐</td><td>☐</td></tr> 
<tr><td class="note" colspan=3>Previously named gearman_stream, uses gearman-coffee</td><td colspan=10></td></tr> 
<tr><td><a href="https://www.npmjs.org/package/gearnode">gearnode</a></td><td><a href="https://github.com/andris9/gearnode">andris9/gearnode</a></td><td><a href="https://www.npmjs.org/~andris">andris</a></td><td class="last-commit">2013-02-25</td><td class="issues">1</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☑</td><td>☐</td></tr> 
<tr><td><a href="https://www.npmjs.org/package/gearmanode">gearmanode</a></td><td><a href="https://github.com/veny/GearmaNode">veny/GearmaNode</a></td><td><a href="https://www.npmjs.org/~veny">veny</a></td><td class="last-commit">2014-03-20</td><td class="issues">4</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☑</td><td>☑</td></tr> 
<tr><td><a href="https://www.npmjs.org/package/nodegears">nodegears</a></td><td><a href="https://github.com/enmand/nodegears">enmand/nodegears</a></td><td><a href="https://www.npmjs.org/~enmand">enmand</a></td><td class="last-commit">2013-12-07</td><td class="issues">1</td><td>☐</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☐</td><td>☐</td><td>☐</td></tr> 
<tr><td><a href="https://www.npmjs.org/package/que">que</a></td><td><a href="https://github.com/vdemedes/que">vdemedes/que</a></td><td><a href="https://www.npmjs.org/~vdemedes">vdemedes</a></td><td class="last-commit">2012-07-02</td><td class="issues">0</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☐</td><td>☐</td><td>☐</td></tr> 
<tr><td class="note" colspan=3>Uses node-gearman</td><td colspan=10></td></tr> 
<tr><td><a href="https://www.npmjs.org/package/gearman-js">gearman-js</a></td><td><a href="https://github.com/mreinstein/gearman-js">mreinstein/gearman-js</a></td><td><a href="https://www.npmjs.org/~mreinstein">mreinstein</a></td><td class="last-commit">2013-11-03</td><td class="issues">4</td><td>☐</td><td>☐</td><td>☑</td><td>☑</td><td>☐</td><td>☐</td><td>☐</td><td>☐</td></tr> 
<tr><td><a href="https://www.npmjs.org/package/gearman2">gearman2</a></td><td><a href="https://github.com/sazze/gearman-node">sazze/gearman-node</a></td><td><a href="https://www.npmjs.org/~ksmithson">ksmithson</a></td><td class="last-commit">2013-09-17</td><td class="issues">0</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☐</td><td>☐</td><td>☑</td><td>☐</td></tr> 
<tr><td class="note" colspan=3>Fork of gearman with no changes except name</td><td colspan=10></td></tr> 
<tr><td><a href="https://www.npmjs.org/package/node-gearman">node-gearman</a></td><td><a href="https://github.com/andris9/node-gearman">andris9/node-gearman</a></td><td><a href="https://www.npmjs.org/~andris">andris</a></td><td class="last-commit">2013-08-13</td><td class="issues">2</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☑</td><td>☑</td><td>☑</td></tr> 
<tr><td><a href="https://www.npmjs.org/package/node-gearman-ms">node-gearman-ms</a></td><td><a href="https://github.com/nachooya/node-gearman-ms">nachooya/node-gearman-ms</a></td><td><a href="https://www.npmjs.org/~nachooya">nachooya</a></td><td class="last-commit">2013-11-18</td><td class="issues">0</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td></tr> 
<tr><td class="note" colspan=3>Fork of node-gearman</td><td colspan=10></td></tr> 
<tr><td><a href="https://www.npmjs.org/package/gearman-coffee">gearman-coffee</a></td><td><a href="https://github.com/Clever/gearman-coffee">Clever/gearman-coffee</a></td><td><a href="https://www.npmjs.org/~rgarcia">rgarcia</a>, <a href="https://www.npmjs.org/~azylman">azylman</a>, <a href="https://www.npmjs.org/~jonahkagan">jonahkagan</a></td><td class="last-commit">2013-03-19</td><td class="issues">2</td><td>☑</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☐</td><td>☑</td><td>☐</td></tr> 
<tr><td><a href="https://www.npmjs.org/package/"></a></td><td><a href="https://github.com/magictoolbox/node-gearman">magictoolbox/node-gearman</a></td><td><a href="https://www.npmjs.org/~oleksiyk">oleksiyk</a></td><td class="last-commit">2012-12-03</td><td class="issues">0</td><td>☑</td><td>☐</td><td>☑</td><td>☑</td><td>☑</td><td>☐</td><td>☑</td><td>☑</td></tr> 
 </tbody> 
</table>
</div>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Using cron with “every”]]></title>
    <link href="http://re-becca.org/2013-10-16-using-cron-with-every.html"/>
    <published>2013-10-16T09:55:00-07:00</published>
    <updated>2018-08-11T20:09:00-07:00</updated>
    <id>http://re-becca.org/2013-10-16-using-cron-with-every.html</id>
    <content type="html"><![CDATA[<p>The “every” command is that I wrote, inspired by the unix “at” command.  It adds command to your crontab for you, using an easier to remember syntax.  You can find it on github, here: <a title="App::Every" href="https://github.com/iarna/App-Every">https://github.com/iarna/App-Every</a></p>

<p>I was reminded because of this article on cron for perl programmers who are unix novices:</p>

<p><a title="How to schedule Perl scripts using cron" href="http://perltricks.com/article/43/2013/10/11/How-to-schedule-Perl-scripts-using-cron">http://perltricks.com/article/43/2013/10/11/How-to-schedule-Perl-scripts-using-cron</a></p>

<p>Here’s how you’d write their examples using “every”:</p>

<pre class="lang:shell decode:true">
$ every minute perl /path/to/Beacon.pl
SHELL=/bin/bash
PATH=/home/rebecca/bin:/opt/perl5/bin:/opt/perl5/perls/perl-5.16.2/bin:/opt/node/bin:/usr/local/bin:/usr/bin:/bin
*/1 * * * * cd "/home/rebecca";  perl /path/to/Beacon.pl

$ every 5 minutes perl /path/to/Beacon.pl
SHELL=/bin/bash
PATH=/home/rebecca/bin:/opt/perl5/bin:/opt/perl5/perls/perl-5.16.2/bin:/opt/node/bin:/usr/local/bin:/usr/bin:/bin
*/5 * * * * cd "/home/rebecca";  perl /path/to/Beacon.pl

$ every hour perl /path/to/Beacon.pl
SHELL=/bin/bash
PATH=/home/rebecca/bin:/opt/perl5/bin:/opt/perl5/perls/perl-5.16.2/bin:/opt/node/bin:/usr/local/bin:/usr/bin:/bin
49 */1 * * * cd "/home/rebecca";  perl /path/to/Beacon.pl

$ every 12 hours perl /path/to/Beacon.pl
SHELL=/bin/bash
PATH=/home/rebecca/bin:/opt/perl5/bin:/opt/perl5/perls/perl-5.16.2/bin:/opt/node/bin:/usr/local/bin:/usr/bin:/bin
49 */12 * * * cd "/home/rebecca";  perl /path/to/Beacon.pl
</pre>

<p>What’s more, there’s no need to specify the path to Perl, because unlike using crontab straight up, it will maintain your path.  Even better, you can use relative paths to refer to your script, eg:</p>

<pre class="lang:shell decode:true">$ every monday perl Beacon.pl</pre>

<p>This works because every ensures that it executes from the place you set it up.  Just like “at” it uses all of the same context as your normal shell.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Easy ad-hoc publishing on a machine with Apache]]></title>
    <link href="http://re-becca.org/2012-09-24-easy-ad-hoc-publishing-on-a-machine-with-apache.html"/>
    <published>2012-09-24T12:22:00-07:00</published>
    <updated>2018-08-11T20:09:00-07:00</updated>
    <id>http://re-becca.org/2012-09-24-easy-ad-hoc-publishing-on-a-machine-with-apache.html</id>
    <content type="html"><![CDATA[<h3><a href="https://github.com/iarna/webify-dir">webify-dir</a></h3>

<p>This is just a little hack of mine to make it trivial for me to reflect any directory on my server as a website, either with a name I specify or a hash. Handy for all sorts of things, I initially created it to give myself an easy way to view remote coverage reports that generated to HTML. It’s also a nice way to view HTML docs bundled with a package, or any other random HTML you come across.</p>

<h3>How it works</h3>

<p>As part of setup, we create a file based <a href="http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewritemap">apache rewrite map</a> that rewrites <a href="http://en.wikipedia.org/wiki/Slug_%28web_publishing%29">slugs</a> off of our domain based on rules from a text file. These text files are super simple, just the slug followed by a space and then what to rewrite to.</p>

<p>With the setup out of the way, we have a very simple shell script that uses Perl to figure out the absolute path from your relative one and uses openssl to generate a hash from that. It uses the hash as the slug if you don’t specify one.  Once it’s appended these to the rewritemap file it tells you what your new URL is.</p>

<p>The example in the repo obviously isn’t generic, it refers to a host I control, but that’s easily editable.  This is less software package and more stupid sysadmin hack.</p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[Android Ports for Corporate Firewalls]]></title>
    <link href="http://re-becca.org/2012-08-23-android-ports-for-corporate-firewalls.html"/>
    <published>2012-08-23T09:45:00-07:00</published>
    <updated>2018-08-11T20:09:00-07:00</updated>
    <id>http://re-becca.org/2012-08-23-android-ports-for-corporate-firewalls.html</id>
    <content type="html"><![CDATA[<p>Beyond the standard 80 and 443 to handle web traffic, Android also needs 5222 (Jabber) and 5228 (allegedly Google Marketplace, but needed for a phone to fully connect to the network and have functioning Google Talk).</p>

<p>Mail is also likely needed too of course, with SMTP 25 and 995, POP 110 and 993, and IMAP 143 and 465. For some setups you may also need LDAP, 389 and 636.  Exchange needs 135 and in some esoteric configurations, NNTP with 119 and 563. </p>
]]></content>
  </entry>

  <entry>
    <title type="html"><![CDATA[AnyEvent::Capture - Synchronous calls of async APIS]]></title>
    <link href="http://re-becca.org/2012-08-03-anyeventcapture-synchronous-calls-of-async-apis.html"/>
    <published>2012-08-03T03:39:00-07:00</published>
    <updated>2018-08-11T20:50:09-07:00</updated>
    <id>http://re-becca.org/2012-08-03-anyeventcapture-synchronous-calls-of-async-apis.html</id>
    <content type="html"><![CDATA[<p><img alt="Cage7.jpg" src="/content/uploads/2012/08/Cage7-thumb-300x225-874.jpg" width="300" height="225" style="float:right" />
I’ve been a busy little bee lately, and have published a handful of new CPAN modules— I’ll be posting about all of them, but to start things off, I bring you: <a href="https://metacpan.org/module/AnyEvent::Capture">AnyEvent::Capture</a></p>

<p>It adds a little command to make calling async APIs in a synchronous, but non-blocking manner easy.  Let’s start with an example of how you might do this without my shiny new module:</p>

<pre class="lang:perl decode:true"> use AnyEvent::Socket qw( inet_aton );

 my $cv = AE::cv;
 inet_aton( 'localhost', sub { $cv-&gt;send(@_) });
 my @ips = $cv-&gt;recv;
 say join ".", unpack("C*") for @ips;
</pre>

<p>The above is not an uncommon pattern when using <a href="https://metacpan.org/module/AnyEvent">AnyEvent</a>, especially in libraries, where your code should block, but you don’t want to block other event listeners.  <a href="https://metacpan.org/module/AnyEvent::Capture">AnyEvent::Capture</a> makes this pattern a lot cleaner:</p>

<pre class="lang:perl decode:true">use AnyEvent::Capture;
use AnyEvent::Socket qw( inet_aton );

my @ips = capture { inet_aton( 'localhost', shift ) };
say join ".", unpack("C*") for @ips;
</pre>

<p>The <a href="https://metacpan.org/module/AnyEvent::DBus">AnyEvent::DBus</a> documentation provides another excellent example of just how awkward this can be:</p>

<pre class="lang:perl decode:true">use AnyEvent;
use AnyEvent::DBus;
use Net::DBus::Annotation qw(:call);

my $conn = Net::DBus-&gt;find; # always blocks :/
my $bus  = $conn-&gt;get_bus_object;

my $quit = AE::cv;

$bus-&gt;ListNames (dbus_call_async)-&gt;set_notify (sub {
   for my $name (@{ $_[0]-&gt;get_result }) {
      print "  $name\n";
   }
   $quit-&gt;send;
});

$quit-&gt;recv;
</pre>

<p>With <a href="https://metacpan.org/module/AnyEvent::Capture">AnyEvent::Capture</a> this would be:</p>

<pre class="lang:perl decode:true">use AnyEvent;
use AnyEvent::Capture;
use AnyEvent::DBus;
use Net::DBus::Annotation qw(:call);

my $conn = Net::DBus-&gt;find; # always blocks :/
my $bus  = $conn-&gt;get_bus_object;

my $reply = capture { $bus-&gt;ListNames(dbus_call_async)-&gt;set_notify(shift) };
for my $name (@{ $reply-&gt;get_result }) {
   print "  $name\n";
}
</code></pre>

<p>We can also find similar examples in the <a href="https://metacpan.org/module/Coro">Coro</a> documentation, where  rouse_cb/rouse_wait replace condvars:</p>

<pre class="lang:perl decode:true">sub wait_for_child($) {
    my ($pid) = @_;

    my $watcher = AnyEvent-&gt;child (pid =&gt; $pid, cb =&gt; Coro::rouse_cb);

    my ($rpid, $rstatus) = Coro::rouse_wait;
    $rstatus
}
</pre>

<p>Even still, for the common case, <a href="https://metacpan.org/module/AnyEvent::Capture">AnyEvent::Capture</a> provides a much cleaner interface, especially as it will manage the guard object for you.</p>

<pre class="lang:perl decode:true">sub wait_for_child($) {
    my ($pid) = @_;

    my($rpid, $rstatus) = capture { AnyEvent-&gt;child (pid =&gt; $pid, cb =&gt; shift) };

    $rstatus
}
</pre>
]]></content>
  </entry>


</feed>
