tag:blogger.com,1999:blog-73191575029893698512024-03-13T03:03:12.243-07:00BehemothTikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.comBlogger136125tag:blogger.com,1999:blog-7319157502989369851.post-7496708173717099892016-10-17T06:47:00.000-07:002016-10-17T06:55:27.653-07:00Graceful exit for NodeJS web servers on bare-metal vs containers<!DOCTYPE html><html><head><meta charset="utf-8"><title>Graceful exit for NodeJS web servers on bare-metal vs containers.md</title><style></style></head><body id="preview">
<h3><a id="Motivation_0"></a>Motivation</h3>
<p>Recently when experimenting with <a href="http://socket.io">socket.io</a> and express, I decided to use <code>docker-compose</code> to manage the environment. It made development much easier as I would simply make changes and run <code>docker-compose up</code> for sanity testing. But the longer I kept at it, the more obvious it became that the webserver was taking much longer to shut down in its containerized form than it did when I ran it directly on bare-metal with <code>node server.js</code></p>
<h3><a id="Trials_and_Observations_3"></a>Trials and Observations</h3>
<ol>
<li>I spent some time rereading the differences in <code>CMD</code> vs. <code>ENTRYPOINT</code> for docker to see if the interrupt (<code>ctrl+c</code>) wasn’t making it to the webserver inside the container. Switched over to using <code>ENTRYPOINT</code> but it didn’t seem to make a difference in practice.
<ol>
<li>The webserver container with only express would shutdown 10 to 20 seconds earlier than the webserver container with both express and <a href="http://socket.io">socket.io</a></li>
</ol>
</li>
<li>Active <a href="http://socket.io">socket.io</a> connections may not be disposed of even after receiving the interrupt so I rewrote the code to listen for various signals as outlined in this <a href="https://medium.com/@gchudnov/trapping-signals-in-docker-containers-7a57fdda7d86#.fjy8y81ru">blog</a> to close the open websocket connections but it didn’t seem to work either.</li>
<li>Decided that my code might be flawed so found libraries such as <a href="https://github.com/thedillonb/http-shutdown">http-shutdown</a> and <a href="https://github.com/emostar/express-graceful-exit">express-graceful-exit</a>
<ol>
<li><code>express-graceful-exit</code> seemed better as its documentation directly mentioned cleanup for <a href="http://socket.io">socket.io</a></li>
</ol>
</li>
<li>I started to suspect that the interrupts/signals weren’t being received by nodejs processes so I added <code>console.log</code> statements which never showed up! I couldn’t say if it was because <code>docker-compose</code> cuts off log aggregation upon <code>ctrl+c</code> or if the node processes were genuinely not receiving the interrupts.</li>
<li>I switched back to bare-metal with all the graceful exit code still intact and realized that <code>ctrl+c</code> would kill off the webserver with both express and <a href="http://socket.io">socket.io</a> instantly despite active websocket connections … and there still weren’t any logs generated from:<pre><code>process.on('SIGTERM', function() {
console.log('shutting down...');
...
});
</code></pre>
so I gave up! It seemed too much of a rabbit hole to troubleshoot at the moment but perhaps these notes will help myself or someone else (who finds it critical resolve this) to form a better experiment and deduct the correct approach.</li>
</ol>
</body></html>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-73821507697134858202016-08-20T08:05:00.003-07:002016-08-20T14:53:20.554-07:00Multiple logins for Docker Hub<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
Features like teams and groups for DockerHub have been slow to get added and even slower for DockerCloud. This means multiple hub accounts - one for you as a developer and one for managing the repos of your workplace.<br />
<br />
And you may often end up wondering:<br />
<blockquote>
How to use `docker login` to register multiple usernames so if one doesn't work for the repo you're trying to upload, it uses another one?</blockquote>
The answer is that its currently not possible!
<br />
<br />
If you look inside the config file (`cat ~/.docker/config.json`)
<br />
<script src="https://gist.github.com/pulkitsinghal/d13e1c9a4a488ef62cc9f0e109ea9527.js"></script>
You will realize that `index.docker.io` corresponds to the key for your login to dockerhub and there isn't a clever way in the framework right now for it to distiguish between multiple usernames. That is to say the value of that key is not an array but just an object. In the future if we can get something like:
<br />
<script src="https://gist.github.com/pulkitsinghal/524c557ac73814064f81bfd4018420d2.js"></script>
... notice the additional [] symbols indicating an array ... then there may be a possibility for such a feature.
<br />
<br />
There are references to <a href="https://docs.docker.com/engine/reference/commandline/login/#/credentials-store" target="_blank">alternative credential stores</a> in the docs but it is not clear if such <a href="https://github.com/docker/docker-credential-helpers" target="_blank">docker-credential-helpers</a> understand multiple logins for the same site or not. Perhaps is would be best to setup teams and groups properly with permissions rather than focusing energy into managing multiple logins.
</div>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com1tag:blogger.com,1999:blog-7319157502989369851.post-61938441599966678272015-05-30T10:13:00.001-07:002015-05-30T10:17:15.899-07:00Awesome Tech Companies<h4 id="summary">Summary</h4>
<p>I’ll evaluate and rate the best technology companies that caught my eye, either as an investment opportunity <em>or</em> an interesting place to work. This does <em>not</em> imply that the companies in my list are hiring or seeking investment. It just means that I’m interested in them.</p>
<table>
<thead>
<tr>
<th>*Company</th>
<th>*Like to Invest In</th>
<th>*Like to Work At</th>
<th>*<em>NO</em> Qs Asked</th>
<th>*Some Qs Asked</th>
<th>*Points</th>
</tr>
</thead>
<tbody><tr>
<td>Bitnami</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>9=4+3+2</td>
</tr>
<tr>
<td>OAuth.io</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>9=4+3+2</td>
</tr>
<tr>
<td>Gitter.im</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>9=4+3+2</td>
</tr>
<tr>
<td>Zapier</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>9=4+3+2</td>
</tr>
<tr>
<td>Resin.io</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>8=4+3+1</td>
</tr>
<tr>
<td>WIOMW</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>6=4+2</td>
</tr>
<tr>
<td>Runnable</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>5=4+1</td>
</tr>
<tr>
<td>Stackedit</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>5=4+1</td>
</tr>
<tr>
<td>Wistia</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>5=4+1</td>
</tr>
<tr>
<td>Matchist</td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>4=3+1</td>
</tr>
<tr>
<td>Mashape</td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>-</td>
<td><a href=""><img src="https://cdn4.iconfinder.com/data/icons/ionicons/512/icon-checkmark-circled-32.png" alt="" title=""></a></td>
<td>4=3+1</td>
</tr>
<tr>
<td><em>TBD…</em></td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
</tbody></table>
<p><a href="icon.com"><img src="icon.png" alt="" title=""></a></p>
<p>Rows are sorted high-to-low by sum of the weight for each checkbox … once again, here’s my <strong>evaluation criteria</strong>: <br>
* Who would I back, no questions asked? (4 points) <br>
* Who would I back, <u><em>some</em></u> questions asked? (3 points) <br>
* Places I’d like to work, no questions asked? (2 points) <br>
* Places I’d like to work, <u><em>some</em></u> questions asked? (1 point)</p>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-71008067471381776602014-01-29T13:41:00.001-08:002014-01-29T13:45:57.549-08:00How to count total attachments in a CouchDB database<div dir="ltr" style="text-align: left;" trbidi="on">
<br/>
You can watch the <u><i>screencast</i></u> here: <a href="http://www.screencast.com/t/TaSrCUvO">How to count total attachments in a CouchDB database</a>
<br/>
<br/>
And here's the source code for easy copy/paste:
<script src="https://gist.github.com/pulkitsinghal/8697809.js"></script>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-52235657100794925302014-01-09T20:47:00.001-08:002014-01-09T21:03:49.417-08:00Scheduling java unit tests as cron jobs in Heroku<div dir="ltr" style="text-align: left;" trbidi="on">
Most folks use Heroku for more than just one application. At any given time, you may have one production application running (with more than one dyno) while tinkering with other dev apps (only one dyno) that are nearing maturity and require regular upkeep for demos to customers.
<br />
<br />
Heroku will put any dev instances (only one dyno) to sleep after one hour of inactivity and when you start a demo, your first few requests may timeout and customers will be left with a poor impression of how your app performs.
<br />
<br />
So how do you keep your dev apps awake and available until you have enough market traction to scale them up?
<br />
<ol style="text-align: left;">
<li>Since you can only have one process named <b>web</b> that gets HTTP requests routed to it, it is impossible to host two war files (prod-war and dev-war) side-by-side without merging them into one war with a common web.xml, spring configuration files, and non-conflicting URL endpoints. This is a lot of work.</li>
<li>A neat workaround that I like to employ is using the <a target="_blank" href="https://addons.heroku.com/scheduler">Heroku Scheduler</a> from my production instances to run functional unit tests against my dev instances to keep them alive.</li>
</ol>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEcGoT_ezTYKOf8XHh59NkSjMspGz-jPJLzh-MoX9erC5wnsrjjYX8Rd33rT57fs9PGheopBvN1hBnnShgsA1EGt2i8QdlnNgwSTTb-adWLhKTwJCJu4EyqKo1NwevCBtlg-HakAVrXCY/s1600/Screen+Shot+2014-01-09+at+10.04.13+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEcGoT_ezTYKOf8XHh59NkSjMspGz-jPJLzh-MoX9erC5wnsrjjYX8Rd33rT57fs9PGheopBvN1hBnnShgsA1EGt2i8QdlnNgwSTTb-adWLhKTwJCJu4EyqKo1NwevCBtlg-HakAVrXCY/s1600/Screen+Shot+2014-01-09+at+10.04.13+PM.png" height="147" width="640" /></a>
</div>
<ol>
<li>Anything that you can run as a one-off task in Heroku via: <b>heroku run 'some command'</b> ... can be run via this scheduler. Simply place <b>'some command'</b> in the text input field under the task column and change the frequency to hourly.</li>
<li>It may take some trial & error to figure out the right classpath for running your unit tests so I would advise utilizing <b>heroku run 'some command'</b> to figure out what it is that will work for you, before putting anything in the scheduler. Here's a sample:
<blockquote>
heroku run 'java -DunitTestNeedsSomeArg1=value_1 -DunitTestNeedsSomeArg2="complex value 2" -cp target/test-classes:target/myProjectName/WEB-INF/classes:"target/dependency/*":"target/myProjectName/WEB-INF/lib/*" org.junit.runner.JUnitCore com.my.test.TestRestRequest'</blockquote>
<ul><li>You may also realize that certain jars are available locally but missing from Heroku because you defined them as test-scoped in your maven project's pom.xml file ... you will need to remove the scope limitation in order to get the unit tests working on the Heroku side.</li><li>Once you have something working, then just cut/paste the content inside the single-quotes as the scheduled task to run hourly.</li></ul>
</li>
<li>When looking through the logs, any lines spit out by the hourly one-off task will be prefixed like so:
<script src="https://gist.github.com/pulkitsinghal/8347152.js"></script>
</li>
</ol>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-51573041695717287542013-12-29T15:27:00.002-08:002014-01-09T10:04:16.854-08:00Dangers of mixing artifact versions across maven modules<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr0CFr4MUgT7vGbQqiwkckR4OqbqJwmsoz_jQLRCN-PsQHHc4G2Q0i54ME1B8QO_BzGFh_ffK9u5OhqtpOXSYvkSzUcszhW0Y7cBmSuTGLLognLYh8IqI-st6y7T8UXhn_sSCWqmwta4c/s1600/Screen+Shot+2013-12-29+at+5.11.33+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgr0CFr4MUgT7vGbQqiwkckR4OqbqJwmsoz_jQLRCN-PsQHHc4G2Q0i54ME1B8QO_BzGFh_ffK9u5OhqtpOXSYvkSzUcszhW0Y7cBmSuTGLLognLYh8IqI-st6y7T8UXhn_sSCWqmwta4c/s1600/Screen+Shot+2013-12-29+at+5.11.33+PM.png" /></a></div>
<br />
Sometimes when a quickfix is urgently required, we are tempted to branch off and make it happen on our own until the authors of the original branch release their latest version. I found myself in such a situation and decided to only use the patched version for a small~ish maven module/artifact known in my project as "commons". What could go wrong? Well I ran into the following error at runtime:<br />
<blockquote class="tr_bq">
java.lang.NoSuchMethodError:
org.springframework.amqp.core.AmqpAdmin.declareQueue(Lorg/springframework/amqp/core/Queue;)Ljava/lang/String;</blockquote>
Turns out that my "commons" module was expecting to use a slightly different method signature than what was available in my main project:<br />
<blockquote class="tr_bq">
// method signature from spring-amqp-1.3.0.BUILD-SNAPSHOT<br />
String declareQueue(Queue queue); <br />
<br />
// method signature from spring-amqp-1.2.0M1 <br />
void declareQueue(Queue queue);</blockquote>
So ... lesson learned :) push the authors to release quicker ;)</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-65035753334707205432013-12-28T12:31:00.000-08:002013-12-28T12:31:12.541-08:00Maven plugins & extensions for working with WSDLs, XSDs and POJOs<div dir="ltr" style="text-align: left;" trbidi="on">
My favorite plugin for generating a webservice from a WSDL file (<a href="http://cxf.apache.org/docs/developing-a-service.html#DevelopingaService-WSDLFirstDevelopment" target="_blank">WSDL-first-approach</a>) is <a href="http://cxf.apache.org/docs/why-cxf.html" target="_blank">Apache CXF</a> because it loops in Spring, JAX-WS and other standards and implementations to make it happen.<br />
<br />
Before CXF became by BFF I had gone looking for a maven archetype/template that would bring everything together for me in Eclipse. I did some <a href="http://cxf.apache.org/docs/jax-rs-maven-plugins.html#JAX-RSMavenPlugins-Archetypes" target="_blank">templates</a> but none that used the <a href="http://cxf.apache.org/docs/developing-a-service.html#DevelopingaService-WSDLFirstDevelopment" target="_blank">WSDL-first-approach</a> to generate a sample project for me. So I gave up on looking for archetypes and instead followed a mix of instructions from the following links:<br />
<ul style="text-align: left;">
<li><a href="http://joemorrison.org/blog/2008/10/23/cxf-wsdl-first/">http://joemorrison.org/blog/2008/10/23/cxf-wsdl-first/</a></li>
<li><a href="https://mvnwls.wordpress.com/2011/02/01/contract-first-cxf/">https://mvnwls.wordpress.com/2011/02/01/contract-first-cxf/</a></li>
</ul>
Anyway, CXF is awesome for the following reasons:<br />
<ul style="text-align: left;">
<li>It is easy to configure <a href="http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html">cxf-codegen-plugin</a> for generating a Java webservice code from a WSDL file.</li>
<li>It is easy to configure <a href="http://cxf.apache.org/cxf-xjc-plugin.html">cxf-xjc-plugin</a> for generating POJO (plain-old-java-objects) classes from a XSD (schema) file.</li>
<li>Other maven extensions can be used to enhance the cxf-xjc-plugin's schema to POJO conversion process: </li>
<ul>
<li>Lets say you want to use something like a builder-pattern which makes your written code more beautiful. You can do that by configuring the <a href="http://stackoverflow.com/questions/20489211/is-there-a-jaxb-plugin-which-generates-builders">jaxb-fluent-api</a> extension!</li>
<li>If some of your POJOs share the same methods then not being able to categorize all those POJOs under a common interface can lead to duplicate code. For example, lets say you have a method named: performCommonTaskOnIncomingObject(ClassName argument) ... now you may need to have multiple such method with different names because you'll need to change the argument's classname everytime to match the object you're passing in!</li>
<ul>
<li>So can we get the code-generator to implement interfaces on POJOs for us without messing with the schema? Yes!</li>
<li>Just <a href="https://gist.github.com/pulkitsinghal/8163296">configure</a> the <a href="http://confluence.highsource.org/display/J2B/JAXB2+Basics+Plugins">jaxb2-basics</a>'s <a href="http://confluence.highsource.org/display/J2B/Inheritance+plugin">inheritance-extension</a> as you see fit.</li>
</ul>
</ul>
</ul>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-49076017753798111792013-08-10T15:55:00.002-07:002013-08-10T15:56:34.321-07:00Setup continuous integration (CI) with Jenkins / Hudson for TestFlight<div dir="ltr" style="text-align: left;" trbidi="on">
Steps taken between Nov 12, 2012 and Mar 7, 2013 to finally get it going:
<ol>
<li>Started with a <a target="_blank" href="http://blog.shinetech.com/2011/06/23/ci-with-jenkins-for-ios-apps-build-distribution-via-testflightapp-tutorial/">tutorial</a>.
</li>
<li>Then went <a target="_blank" href="http://jenkins-ci.org/content/thank-you-downloading-os-x-installer">here</a> to download Jenkins for mac.</li>
<li>I tried 5 builds so far via Jenkins, all resulted in failure, solved a few configuration issues to resolve problems, and now I'm facing an issue that has to do with keychains. Tried to follow <a target="_blank" href="http://stackoverflow.com/questions/9245149/jenkins-on-os-x-xcodebuild-gives-code-sign-error">this thread</a> to figure out the appropriate action.</li>
<li>Decided to uninstall Jenkins using these <a target="_blank" href="http://stackoverflow.com/questions/11608996/how-to-uninstall-jenkins">instructions</a></li>
<li>Instead used a <a target="_blank" href="https://github.com/stisti/jenkins-app">new installer</a> that circumvents the keychain access issues.</li>
<li>
I let it checkout my project into its workspace once at:
<blockquote>/Users/pulkitsinghal/.jenkins/jobs/my_project/workspace</blockquote>
But afterwards I deleted that workspace and soft-linked it with the actual directory which I already have setup for development:
<blockquote>
cd /Users/pulkitsinghal/.jenkins/jobs/my_project<br/>
ln -s ~/dev/my_project/ ./workspace
</blockquote>
And I completely turned off the git checkout process in the Jenkin's job configuration just to be safe ... although I should have been able to get away by simply ignoring submodules too but why checkout when I don't need to.</li>
<li>
Then I bumped my head on this:
<blockquote>
fatal error: 'RestKit/RestKit.h' file not found<br/>
#import <RestKit/RestKit.h><br/>
^<br/>
1 error generated.
</blockquote>
</li>
<li>It should have already been working based on the directions from the RestKit website:
Add the following Header Search Paths (including the quotes):
<blockquote>"$(BUILT_PRODUCTS_DIR)/../../Headers"</blockquote>
But I suppose for some reason that meant one thing to Xcode and something entirely different to jenkins-xcode-plugin.
So through trial and error and watching the logs, I figured out that I needed to add:
<blockquote>"$(BUILT_PRODUCTS_DIR)/../my_project/Build/Headers</blockquote>
in order for jenkins-xcode-plugin to pick it up and work with it properly.</li>
<li>Ran into another road-block ... posted <a target="_blank" href="http://stackoverflow.com/questions/13372566/jenkins-xcode-plugin-how-to-resolve-library-search-path-issues">question</a> to stackoverflow.</li>
<li>Then got stuck due to <a target="_blank" href="https://issues.jenkins-ci.org/browse/JENKINS-15941">this issue</a>.
<ul>
<li>
Agreed to <a target="_blank" href="http://www.freedomsponsors.org/core/offer/147/xcode-plugin-cant-properly-build-an-ipa-when-the-infoplist-file-build-setting-contains-a-variable?alert=SPONSOR&c=s">pay $5 bucks to fast-forward</a> the resolution of this bug on Jenkins.
</li>
<li>While waiting ... I simply removed the <a target="_blank" href="https://gist.github.com/pulkitsinghal/6202511">following</a> because the jenkins xcode plugin could not process it: <div class="separator" style="clear: both; text-align: center;"><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFf3AZZ10_uDzIJCe9mhS-wfvnxo5E8Psl2oVaMgnYa39wEXYo_i0nhb9kFLNw9eWrRFzP9LvwyGBIyiXokIlNwBdq9xeef5wTXXrPI2gfBUPaiG5tHs4paYY216Y3f5eLwOANHh1kWQc/s1600/Screen+Shot+2013-03-07+at+11.34.26+PM.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFf3AZZ10_uDzIJCe9mhS-wfvnxo5E8Psl2oVaMgnYa39wEXYo_i0nhb9kFLNw9eWrRFzP9LvwyGBIyiXokIlNwBdq9xeef5wTXXrPI2gfBUPaiG5tHs4paYY216Y3f5eLwOANHh1kWQc/s1600/Screen+Shot+2013-03-07+at+11.34.26+PM.png" /></a></div>
</li>
</ul>
</li>
</ol>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-89911089537091091032013-04-29T09:48:00.001-07:002013-04-29T09:48:48.098-07:00Mac tools and tips<div dir="ltr" style="text-align: left;" trbidi="on">
<p>This list will surely grow:
<ul>
<li>
TextWrangler
<ul><li>Useful for comparing folders on mac via its "Search > Find Differences..." menu option.</li></ul>
</li>
</ul>
</p>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-13223604828286339932013-04-28T12:23:00.004-07:002013-04-28T12:32:53.335-07:00Generating recommendations via CouchDB - Part 1<head>
<style media="screen" type="text/css">
.gist {
width:590px;
}
</style>
</head>
<div dir="ltr" style="text-align: left;" trbidi="on">
<ul style="list-style-type: none; padding: 0;">
<li>I set out to build a solution in CouchDB with a simple usecase in mind:
<blockquote>
<i>Given a product being browsed, we want to provide suggestions based on what others have purchased in the past.</i>
</blockquote>
</li>
<li>
I've already discussed the strategies for breaking down a single sale/receipt/invoice in <a href="http://pulkitsinghal.blogspot.com/2013/04/generating-recommendations-via.html" target="_blank">Generating recommendations via Elasticsearch - Part 1</a>, so I decided to employ them for CouchDB as well. The difference being that instead of generating multiple documents for each sale:
<blockquote>(total # of lineitems) * (total # of lineitems-1)</blockquote>
</li>
<li>
I found it simpler to store the sale documents themselves and generate keys that represented product pairs, via the <a href="https://gist.github.com/pulkitsinghal/5477903#file-map-js" target="_blank"><i>MAP</i></a> function in CouchDB. <i>If you're unfamiliar with the core concept of map/reduce, you can watch this five minute screencast: <a href="http://pulkitsinghal.blogspot.com/2012/05/understanding-map-reduce-with-couchdb.html" target="_blank">Understanding map reduce with CouchDB</a></i>.
</li>
<li>
Here's what the results of the map operation look like:<br/>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLOrtD59Gf0JbDAbgATXbPrqxPKDAnSZlO7_AJqGnOnKtEXYgQwsPtuQBH-cNDg_tYlpvfBjxsdMgNqGh5DcVRYvF09besqRLJtBPXJ5Sk8F7NGW0jnxT7a6cXBS6uIq_AODIGfYVOKmg/s1600/Screen+Shot+2013-04-28+at+1.51.46+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLOrtD59Gf0JbDAbgATXbPrqxPKDAnSZlO7_AJqGnOnKtEXYgQwsPtuQBH-cNDg_tYlpvfBjxsdMgNqGh5DcVRYvF09besqRLJtBPXJ5Sk8F7NGW0jnxT7a6cXBS6uIq_AODIGfYVOKmg/s640/Screen+Shot+2013-04-28+at+1.51.46+PM.png" /></a>
</li>
<li>
Applying the <a href="https://gist.github.com/pulkitsinghal/5477903#file-reduce-js" target="_blank"><i>REDUCE</i></a> function yields rows that tell us which product was bought together with another and how many times. This result is similar to the facets created by Elasticsearch.<br/>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYGiPirB9VzIIyqryj8HK7Hf6UFuyTO6cu89pJOQJdy-rDHlbGfhTHYKZ4RZA2THCdA-j-H3Vb3fh7sCZnrlF2dvWPuTaS3Q_U3WGSoCwloBSXn02dHf7zSO2g2oGfclOvsOgu-vGje10/s1600/Screen+Shot+2013-04-28+at+1.41.15+PM.png" imageanchor="2"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYGiPirB9VzIIyqryj8HK7Hf6UFuyTO6cu89pJOQJdy-rDHlbGfhTHYKZ4RZA2THCdA-j-H3Vb3fh7sCZnrlF2dvWPuTaS3Q_U3WGSoCwloBSXn02dHf7zSO2g2oGfclOvsOgu-vGje10/s640/Screen+Shot+2013-04-28+at+1.41.15+PM.png" /></a>
</li>
<li>
So what's lacking for a complete implementation?
<ol>
<li>We need a query that fetches results from this map/reduce view for the product being browsed by a consumer, for ex: <b>T-shirt (demo)</b></li>
<li>Next, we need to discern which products have the highest count.</li>
<li>Next, we need to retrieve the product's ID in order to fetch more information about it ... for the users to view.
<ul>
<li>Where & how to store this information in the current map/reduce view ... so that we may fetch it as part of a query itself ... is an <b><u><i>open question</i></u></b> for now.</li>
<li>Maybe its something that cannot even be accomplished via CouchDB? Would it require an alternate implementation with secondary indexes such as the ones <a target="_blank" href="https://cloudant.com/for-developers/views/">Cloudant</a> provides?</li>
</ul>
</li>
</ol>
</li>
</ul>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-54163372267680210812013-04-27T11:46:00.000-07:002013-04-27T11:52:58.929-07:00Why do most desktop blog editors suck?<div dir="ltr" style="text-align: left;" trbidi="on">
<ul>
<li>First, what are they truly good for:
<ul>
<li>You won't lose your content due to keyboard muscle-memory which differs between windows and mac users or because of hotkey mappings which often differ between browsers like Firefox and Safari. What am I talking about?
<ul>
<li>I'm talking about the tears I've shed when I tried to undo my last change via (ctrl+z or cmd+z) inside blogger/blogspot's web editor and it blew away ALL of my content! Was it safari, firefox, mac or windows conflicting key mappings that caused this? I don't know ... but its an evil concoction that I don't care for.</li>
</ul>
<li>Worst of all is the mapping for the backspace key. It move you back to the previous page in your browser when you are editing your blog instead of simply deleting a character ... thus causing you to lose all your work!</li>
</li>
<li>Just having the comfort of knowing that your content won't be lost because of a dumb keystroke ... is just about the only thing that these desktop blog editors are good for.</li>
</ul>
</li>
<li>Onwards & upwards ... lets look at all the reasons desktop blog editor <i>SUCK</i> ... which pretty much boils down to the fact that you still have to manually edit HTML because the simplest usecases aren't automatically handled. What are these usecases? Images and embeds!
<ul>
<li>Is it really that hard for the desktop-blog-editor <i>manufacturing industry</i> (yes that is sarcasm) to grasp the fact that folks might want their images to float to the right or left and their content/text to simply flow around them? There's not a single tool that handles this via a WYSIWYG toolbar.</li>
<li>Embeds mean different things to different people. For a developer, it means embedding code-blocks (gists for example) which will have their own space and your own content would flow around and not clash/overlap with them.</li>
<li>Seriously, the desktop blog editors out there today (year 2013) are just a big disappointment :(</li>
</ul>
</li>
</ul>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-6196806631277453902013-04-26T13:16:00.000-07:002013-04-28T11:18:47.532-07:00Generating recommendations via Elasticsearch - Part 1<html>
<head>
<style media="screen" type="text/css">
.gist {
width:500px;
}
</style>
</head>
<body>
<p>Let's look at what it entails to roll your own recommendation engine with Elasticsearch.</p>
<p>A simple use case: Given a product being browsed, we want to provide suggestions based on what others have purchased in the past.</p>
<p>In order to accomplish this we will break down the steps required:</p>
<ol>
<li>Index the past sale data, invoices or receipts in Elasticsearch.</li>
<li>Run a query that narrows down the results to a product that consumers are browsing and then returns suggestions for other items that are most frequently purchased together with it.</li>
</ol>
<ul style="list-style-type:none;padding:0;">
<div class="separator" style="clear: both; text-align: center;">
<img style="clear:right; float:right; margin-left:1em; margin-bottom:1em" title="photo 1.JPG" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4s60Ri80XVnuXmNmgPnJCzh7Fx0rdnA2QcxweqCFHmdn4IYUeucyPRHjwGEWNj8Dyn1I8dMBQepukNq75vk-UVyYI3h6B8OsX-Kvty5OHnGDTb1cakHaNwjk1Xw3yHF6_P1l8cJSurSg/?imgmax=800" alt="Photo 1" width="200" height="196" border="0" />
<!--<iframe style="clear:left; float:left; margin-top:1em; border:0; width:65%;" src="http://www.purplegene.com/script?url=https://gist.github.com/pulkitsinghal/5464989.js?file=overlyOptimisticStructure_1.json"></iframe>-->
</div>
<li>
<p>Here's an example of a sale but what's the correct structure for the JSON document which we should index into Elasticsearch, in order run the type of query which will yield the results for our use case?</p>
<p>One optimistic way to do this is to simply store the receipt itself as a JSON document:
<!--<iframe style="border:0; width:65%; height:75%;" src="http://www.purplegene.com/script?url=https://gist.github.com/pulkitsinghal/5464989.js?file=overlyOptimisticStructure_1.json">
</iframe>-->
<script src="https://gist.github.com/pulkitsinghal/5464989.js?file=overlyOptimisticStructure_1.json"></script>
</p>
<p>But that just won't work because there isn't any query (known to me at least) that can make heads or tails of that one document alone and deliver aggregated results of items most frequently bought together.</p>
</li>
<div class="separator" style="clear: both; text-align: center;">
<img style="clear:right; float:right; margin-left:1em; margin-bottom:1em" title="photo 2.JPG" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga3-JG4ho4h5nMn65IPNL2Z7UzMDLyCqTtv_evZ3C-tAkzyytGGa-Vozsgz7n2ppNuJ95IbA8PT_86GpssGOZ_GtkYql3NJLchmON9Wse1QNk1XZHa6UrURPDbc7-zcG60_L0X0e_oHpA/?imgmax=800" alt="Photo 2" width="250" height="232" border="0" />
</div>
<li>
<p>We could generate one document to represent each item for which a query might come in and then add lineitems from various sales to it as a multi value field and this data could be what we facet upon to deliver aggregated results of items most frequently bought together.</p>
<p>Lets keep our focus on Apples and rest of the sibling lineitems will become recommendations for someone who comes looking for Apples:
<script src="https://gist.github.com/pulkitsinghal/5464989.js?file=overlyOptimisticStructure_2.1.json"></script>
</p>
<p>Any additional sales will add to the number of elements in recorded lineitems:
<script src="https://gist.github.com/pulkitsinghal/5464989.js?file=overlyOptimisticStructure_2.2.json"></script>
</p>
<p>But this doesn't work because the facet query will report that there is one Orange, one Lemon etc. It will not count Oranges as <em>2</em> but rather as <em>1</em> inside the lineitems field. This is because the facet query is meant to count the number of <span style='text-decoration:underline;'>documents</span> that have the term "Oranges" but not the number of times a term (such as Oranges) appears per document or field.
</p>
</li>
<div class="separator" style="clear: both; text-align: center;">
<img style="clear:right; float:right; margin-left:1em; margin-bottom:1em" title="photo 3.JPG" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmKIGx-kCfNJeIsJZMtSxpfhOH6EOimG6fxVCTLnnNO251Z_Yr69XdsJz3QjUVwOwKVNnPWnLqGTDF_Fb-A1KW_lY7AEJWNzmsY6PfEAfvpFp-Milfwvxb8tiuemEhjQSoOQFFpxtTboQ/?imgmax=800" alt="Photo 3" width="300" height="145" border="0" />
</div>
<li>
<p>What next?</p>
<p>We can break apart the receipt into (total # of lineitems) * (total # of lineitems-1) documents as pairs. This way when a new sale appears, similar pairs can be identified and the facet query can accurately count them because they are all separate/individual documents.
<script src="https://gist.github.com/pulkitsinghal/5464989.js?file=overlyOptimisticStructure_3.json"></script>
</p>
</li>
<div class="separator" style="clear: both; text-align: center;">
<img style="clear:right; float:right; margin-left:1em; margin-bottom:1em" title="photo 4.JPG" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGS8xVcR5g1KcDGBQv0X5lGUOVjzrE1V_0vCxHyGyWRFSxeJTNmpk1n6y1t-fWHZy7MI5tGrfKVultMfg0SksjKO9DPFY68UxAuBcJpJxtFxGgrHFIhheOTBdUS0R-TUUzBegkktJJO8Q/?imgmax=800" alt="Photo 4" width="250" height="174" border="0" />
</div>
<li>
<p>Now we can see that the documents (one lineitem pair per document) from Sale1 and Sale2 can finally be used by a facet query to suggest that Apples are most often bought together with oranges and vice-versa.
<script src="https://gist.github.com/pulkitsinghal/5464989.js?file=facetQuery.json"></script>
</p>
</li>
</ul>
</body>
</html>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com1tag:blogger.com,1999:blog-7319157502989369851.post-31438509111263979432013-04-18T18:55:00.000-07:002013-04-18T19:00:42.862-07:00How to invoke update handler with Cradle?<div dir="ltr" style="text-align: left;" trbidi="on">
Invoking an update handler via a Cradle nodejs client should be a simple task but I felt like I spent 10 minutes too many, piecing together documentation on it, since its not explicitly documented in the <a target="_blank" href="https://github.com/cloudhead/cradle/blob/master/README.md">README.md</a> file.
<br/><br/>
Based on the comments in the <a target="_blank" href="https://github.com/cloudhead/cradle/pull/31">pull request</a> where this functionality was added, <i>here's a sample</i>:
<br/>
<script src="https://gist.github.com/pulkitsinghal/5417562.js"></script>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-30744915284018079062013-04-17T17:46:00.000-07:002013-04-17T17:46:12.698-07:00Wiring Vend POS with CouchDB - Part 2<div dir="ltr" style="text-align: left;" trbidi="on">
<script src="https://gist.github.com/pulkitsinghal/5408964.js"></script>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-2878545079709559012013-03-19T11:30:00.000-07:002013-03-19T13:21:00.218-07:00Wiring Vend POS with CouchDB<div dir="ltr" style="text-align: left;" trbidi="on">
<h4>Motivation:</h4>
<ul>
<li><a target="_blank" href="http://www.vendhq.com/">Vend</a> is a pretty awesome point-of-sale (POS) that resides in the cloud and has an even awesome~er developer API.</li>
<li>
You can easily create and query views in CouchDB (common hosts: <a target="_blank" href="http://cloudant.com">Cloudant</a> and <a target="_blank" href="http://www.iriscouch.com">IrisCouch</a>).
<ul>
<li>
This can be especially helpful if you want to build towards a Full Text Search capability on top of the <a target="_blank" href="http://docs.vendhq.com/index.html">Vend APIs</a>.
<ul>
<li>
You can use <a target="_blank" href="https://github.com/rnewson/couchdb-lucene">Lucene</a> (Cloudant offers it <a target="_blank" href="https://cloudant.com/for-developers/search/">out-of-the-box</a>), or
</li>
<li>
ElasticSearch (<a target="_blank" href="https://github.com/elasticsearch/elasticsearch-river-couchdb">connects to CouchDB</a> via a concept know as "<a target="_blank" href="http://www.elasticsearch.org/blog/2010/09/28/the_river.html">The River</a>")
</li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>Steps:</h4>
<ol>
<li>
Get all the products from your Vend store and upload them to CouchDB.
<ul>
<li>
Some standalone code be written to pull all the products and upload them. So many ways to do this, depending on what has the best utilities to cobble together something in a hurry: curl or Java or javascript (run via Node.JS) etc.
<ul>
<li>
I'm partial to Node.JS because all of Vend's data is in JSON-format and there are some excellent libraries like <a target="_blank" href="https://github.com/cloudhead/cradle">Cradle</a> which make it simpler to talk with CouchDB.
</li>
</ul>
</li>
<li>
For the upload to CouchDB, it should be possible to leverage the <a target="_blank" href="http://wiki.apache.org/couchdb/HTTP_Bulk_Document_API">bulk document API</a> and finish it off in one shot.
</li>
</ul>
</li>
<li>
Going forward, keep everything up to date in real-time by utilizing <a target=_"blank" href="http://docs.vendhq.com/webhooks.html">Vend's webhooks</a> to call into <a href="http://wiki.apache.org/couchdb/Document_Update_Handlers">CouchDB's update handlers</a>.
<ul>
<li>
Create a design document in CouchDB with update handlers that can parse the payload delivered by a Vend webhook like a product update.
<ul>
<li>
When writing <a target="_blank" href="https://gist.github.com/pulkitsinghal/5199005">an update handler for receiving a product update</a>, I mimicked the <a target="_blank" href="https://github.com/iriscouch/stripe_kanso">Stripe Kanso</a> project.
<ul>
<li>
I didn't really write the upload script yet. I simply tried to point Vend's product webhook at the URL for my update handler and I was able to get a document populated in CouchDB.
<br/>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhshxNUbftFFfU-Wk-nLgt-KaSXob13qMfU9migOz8OSYnwsXTW7kGACyV0v9LioaHpmCx1gTtj4xFiN-om0s9X7uSSOQSdLKx-E37HkP18B1ABrrsMGXCJOV9hgNzg4AjlLYjf4UCUL9I/s1600/Screen+Shot+2013-03-19+at+2.12.36+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhshxNUbftFFfU-Wk-nLgt-KaSXob13qMfU9migOz8OSYnwsXTW7kGACyV0v9LioaHpmCx1gTtj4xFiN-om0s9X7uSSOQSdLKx-E37HkP18B1ABrrsMGXCJOV9hgNzg4AjlLYjf4UCUL9I/s320/Screen+Shot+2013-03-19+at+2.12.36+PM.png" /></a>
<br/>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjffDqf5MGbHiII9yVNqKFt65sDqw9YET3OukyydmDa_ZikpSXHM7zOoBhYhBfEMOfY_Cvu1u4CbWty9oXaiK5CxJ0JHeqMVozMaWNX7hrOqVOOyAnxQICQQkfmOm_iqiTzF16XMfXIP6Y/s1600/Screen+Shot+2013-03-19+at+2.12.53+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjffDqf5MGbHiII9yVNqKFt65sDqw9YET3OukyydmDa_ZikpSXHM7zOoBhYhBfEMOfY_Cvu1u4CbWty9oXaiK5CxJ0JHeqMVozMaWNX7hrOqVOOyAnxQICQQkfmOm_iqiTzF16XMfXIP6Y/s320/Screen+Shot+2013-03-19+at+2.12.53+PM.png" /></a>
</li>
<li>
For an actual product update (not just a new one), I haven't quite figured out the code, it fails right now. Just need to spend more time reading up on update handlers, I suppose.
<script src="https://gist.github.com/pulkitsinghal/5199170.js"></script>
<ul>
<li>
Because the Vend API sends the update via a payload that is form urlencoded, I was left wondering where to look for the data and how to grab it inside CouchDB's update handler .. but those questions were easily tackled when I found <a target="_blank" href="http://wiki.apache.org/couchdb/Working_with_Forms#A_basic_update_handler">documentation on handling form-style-submission of data with CouchDB</a>.
</li>
<li> I did send an email to the CouchDB mailing-list to ask for some advice on actual updates:
<blockquote>
1) I have a 3rd-party-webhook API calling into my update handler and there's nothing I can do to make it pass the document ID in the URL.<br/>
2) That means the CouchDB server cannot provide the update function with the most recent version of that document.<br/>
3) But the request does provide a payload from which I can pull out the document ID ... but by this time I'm inside the update handler function.<br/>
4) So my question is: If CouchDB did not provide a doc, is there still a way for me to:<br/>
a) either, fetch the latest version of the doc myself?<br/>
b) or, override the existing document with another document formed with my request payload ... without running into a revision conflict?<br/>
<br/>
I know that I can probably route the request through a proxy that parses the payload, sets the document ID onto the request URL and sends it own its way ... but I'd rather leave that as a last resort.<br/>
<br/>
Thoughts?
</blockquote>
</li>
<li>
One more challenge to keep in mind is authentication. If anyone figures out the URL endpoint for the CouchDB and the respective update handler, they could make false additions and updates.
<ul>
<li>
It would be worth looking into any username/password BASIC authn provided by CouchDB to secure the update handler endpoint.
</li>
<li>
A quick fix would be to provide a unique token (?token=ABCDEF123) as part of the endpoint URL you specify for the webhook (product.update: https://couchdb.com/myDB/_design/doc/_update/productHandler?token=ABCDEF123) and since the query params are also encrypted in a request, your token would travel over a secure channel and then be validated on the CouchDB side to see if it matches what you expected.
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ol>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-15470855917811986522013-03-01T11:31:00.000-08:002013-03-01T11:31:43.144-08:00Multiline config for Procfile and .env in Foreman<div dir="ltr" style="text-align: left;" trbidi="on">
<ul>
<li>
Can we spread out our configuration in a .env file for Foreman across multiple lines?
<ul>
<li>
At first I thought that <a target="_blank" href="https://github.com/ddollar/foreman/pull/250">this</a> fix to Foreman allowed me break long confugrations across multiple lines the way that I wanted:
<blockquote>
JAVA_OPTS=-Xmx384m -Xss512k \ <br/>
-XX:+UseCompressedOops <br/>
MAVEN_OPTS=-Xmx384m -Xss512k -XX:+UseCompressedOops
</blockquote>
<li>
But that's not the case as I found out via trial & error. Now I think its simply not supported.
</li>
</ul>
</li>
<li>
Can we spread out our configuration in a Procfile file for Foreman across multiple lines?
<ul>
<li>
Nope, trial & error resulted in the same deal as above.
</li>
<li>
BUT ... I found a nifty clue <a target="_blank" href="https://github.com/ddollar/foreman/issues/172#issuecomment-5061710">here</a>, which allowed me to setup a workaround like this:
<blockquote>
# contents of Procfile <br/>
web: ./webapp-runner.sh <br/>
<br/>
# contents of webapp-runner.sh <br/>
java $JAVA_OPTS \ <br/>
-Djavax.net.ssl.trustStore="cacerts.jks" \ <br/>
-jar target/dependency/webapp-runner.jar --port $PORT target/*.war
</blockquote>
</li>
</ul>
</li>
</ul>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-23332200716865319852013-02-28T20:46:00.000-08:002013-02-28T20:46:58.100-08:00Correlating foreman version and features<div dir="ltr" style="text-align: left;" trbidi="on">
<ul>
<li>How do I find out if the version of <a target="_blank" href="https://toolbelt.heroku.com/">Foreman installed by Heroku-Toolbelt</a> has the feature that I spotted on <a target="_blank" href="https://github.com/ddollar/foreman">Foreman's GitHub website</a>?
<ul>
<li> What version are you running?
<blockquote>
$ foreman --version <br/>
0.60.0 <br/>
</blockquote>
</li>
<li>
Head on over to the <a target="_blank" href=" https://github.com/ddollar/foreman/blob/master/Changelog.md">changelog</a> and search the web page with keywords of the feature you're looking for. For example: When was an export for launchd introduced? I found out that it was present here, here & here:
<div float="right">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRcxuiWOdBAYzB1OD0i5zO_zOPh3A0Q1hT61HsrzIMrcPCrtaw-UHNk0AewMGoHGddyVNZWf6oL1Bzui9NZiwO-emKLzSysxHbIjZZbjn9X7PYnUYyhkF_ZilHrJ7-EOnCdoo3RthnRNg/s1600/Screen+Shot+2013-02-28+at+10.40.40+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRcxuiWOdBAYzB1OD0i5zO_zOPh3A0Q1hT61HsrzIMrcPCrtaw-UHNk0AewMGoHGddyVNZWf6oL1Bzui9NZiwO-emKLzSysxHbIjZZbjn9X7PYnUYyhkF_ZilHrJ7-EOnCdoo3RthnRNg/s320/Screen+Shot+2013-02-28+at+10.40.40+PM.png" />
</a>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZQXQhrHjUNMcYAMxMR-Bjq6fIUZtHk3FTdyCb-tnlR7tHFKqsJ3wFoyqfTJsp6QSabWiSl5oSQQrr-VuY-HrcPuQ5CUr8pef-YOzeE2yKqLBKfGd3TIuf-vrc9GZ164rDZyFJUtepBcg/s1600/Screen+Shot+2013-02-28+at+10.41.00+PM.png" imageanchor="1" ><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZQXQhrHjUNMcYAMxMR-Bjq6fIUZtHk3FTdyCb-tnlR7tHFKqsJ3wFoyqfTJsp6QSabWiSl5oSQQrr-VuY-HrcPuQ5CUr8pef-YOzeE2yKqLBKfGd3TIuf-vrc9GZ164rDZyFJUtepBcg/s320/Screen+Shot+2013-02-28+at+10.41.00+PM.png" />
</a>
</div>
</li>
<li>
All of these were mentioned in versions lower than 0.60.0 so I assume that I have it.
</li>
</ul>
</li>
</ul>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-89942674466879503192012-10-15T21:21:00.000-07:002012-10-30T06:52:51.763-07:00Fast Forward<div dir="ltr" style="text-align: left;" trbidi="on">
<i>Fast Forward</i> is a initiative/project that I cooked up & named while reading <a href="http://www.amazon.com/Startup-Communities-Building-Entrepreneurial-Ecosystem/dp/1118441540" target="_blank">Startup Communities</a> by <b>Brad Feld</b>. <i>I'm still reading through it by the way.</i>
<br />
With <i>Fast Forward</i>, the local talent from <b>Oklahoma City</b>'s tech community will be invited to participate in a three-week program where <i>aspiring founders</i> will pitch their ideas to these skilled individuals. Folks will be free to join any team, as they see fit to invest their time.
<br />
<ul>
<li>What's in it for the <i><u>aspiring founders</u></i>? How do you qualify as one?
<ul>
<li><u>The What</u>
<ol>
<li><u>Team Building</u> - Every good startup needs a great set of people behind it. Contacts made at <i>Fast Forward</i> should serve to provide direct access and future leads to talented people.
</li>
</ol>
</li>
<li><u>The Who</u> - Pitching directly to folks that have the skills needed to help you make your startup ideas into a reality is good enough to qualify as an <i><u>aspiring founder</u></i>.
</li>
</ul>
</li>
<li>What's in it for the <i><u>talent</u></i>? Who exactly are the participants?
<ul>
<li><u>The What</u> <i>(updated: Oct 30, 2012)</i>
<ol>
<li><u>Job Opportunities</u> - <i>Fast Forward</i> should serve as proving grounds where your work speaks for your skills.
<li><u>Wet Feet</u> - Its tough to understand the nuances of the startup scene. Even more so, for folks that have gained experience with the status-quo workforce and aren't quite sure if they have the kind of high-risk, high-reward appetite required for staying motivated through a startup. Worse still, most people undersell themselves and are convinced that they wouldn't be able to make the cut or learn new thing fast enough. Participating in the 3-week cohorts, should help talented people get acclimated.
</li>
</ol>
</li>
<li><u>The Who</u> - Designers, developers, students & anyone willing to work and provide meaningful leverage to those pitching their ideas.
</li>
</ul>
</li>
<li>When do the investors march in? <i>(updated: Oct 30, 2012)</i>
<ul>
<li>I hope to network and actively bring in other Entrepreneurs as <i><u>leaders</u></i> to help run <i>Fast Forward</i> and with them should (no doubt) come their extensive network of backers to tap into. <i>B U T</i> keep in mind that <i>Fast Forward</i> has the goal of <i>NOT</i> taking a cut out of anyone's pocket. So there should be a clear separation between what the program does and the leads that <i><u>aspiring founders</u></i> follow up on.
</li>
<li>Oklahoma City is fortunate to have accelerators like <a target="_blank" href="http://bp4b.com">Blueprint for Business (BP4B)</a> and <a target="_blank" href="http://venturespur.com">VentureSpur</a> in place. <i>Fast Forward</i> graduates should be able to carry their momentum forward by applying to such great programs. (DISCLAIMER: There is no affiliation between the accelerators and <i>Fast Forward</i> as of now. I'm just mentioning them because they exist.)
</li>
</ul>
</li>
</ul>
</div>
Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com2tag:blogger.com,1999:blog-7319157502989369851.post-46389678658869305052012-08-30T13:01:00.000-07:002012-08-30T13:01:43.383-07:00Prioritize ethernet over wifi in macbook air<ol>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXnt5BzweEH0zoA8A93idWODZtogzEy-uJyMqM295rNuXsI8AOh87TH_Ut3gUB3c2zdns84s7YxaMxXE_nuQHuskvwdIH-hmH-vDN4FUhKZkBqXYiitxLzDUXzVqFzkLHyvwaxdPKnDUs/s1600/macbook+air.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"><img border="0" height="284" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXnt5BzweEH0zoA8A93idWODZtogzEy-uJyMqM295rNuXsI8AOh87TH_Ut3gUB3c2zdns84s7YxaMxXE_nuQHuskvwdIH-hmH-vDN4FUhKZkBqXYiitxLzDUXzVqFzkLHyvwaxdPKnDUs/s320/macbook+air.png" />
</a>
</div>
<li>
<b>System Preferences > Network</b>
</li>
<li>
Simply drag & drop to reorder
</li>
</ol>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-11317993497061837642012-08-20T10:56:00.000-07:002012-08-20T10:56:25.754-07:00Recovering Git Projects from Time Machine<ul>
<li>
Recently I lost my development machine due to an upgrade to Mountain Lion. Sadly I had not backed up before performing the upgrade but I did backup before taking the machine to have its OS fixed. Even after three trips to the Apple Store's "Genius Bar" ... it continued to be an epic failure because recovering from the time machine backups yielded the same unusable experience once again.
</li>
<li>
I decided to recover the data piece by piece starting with my Git projects. I loaded the time machine file as a hard drive and copied the projects whole by dragging & dropping them into a similar file system location.
</li>
<li>
But when I performed a simple integrity check such as "<b>git status</b>" it led to messages like: "<b>fatal: Not a git repository git repository</b>"
</li>
<li>
Some basic searches led me to realize that I had to take a closer look at the .git directory in question:
<ul>
<li><a target="_blank" href="http://stackoverflow.com/questions/5283262/what-is-a-git-work-tree-why-have-i-never-needed-to-set-this-as-an-env-var-why#answer-5283457">http://stackoverflow.com/questions/5283262/what-is-a-git-work-tree-why-have-i-never-needed-to-set-this-as-an-env-var-why#answer-5283457</a></li>
<li><a target="_blank" href="http://stackoverflow.com/questions/1386291/git-git-dir-not-working-as-expected#answer-1386350">http://stackoverflow.com/questions/1386291/git-git-dir-not-working-as-expected#answer-1386350</a></li>
</ul>
</li>
<li>
First thing I realized was that my submodule that was causing trouble did not have a <b>.git directory</b> but had a <b>.git file</b> instead! Inside this file was a <b>gitdir</b> key and a path which redirected to a location in the parent git project.
<br/>
<blockquote>gitdir: /Users/olduser/gitProjects/myParentProject/.git/modules/myChildProjectModule</blockquote>
</li>
<li>
Afterwards, the solution was simple. The path for gitdir had an old username in it, which did not represent the current folder structure. Simply correcting the username in the path of the recovered file to the current one, fixed the issue.
<br/>
<blockquote>gitdir: /Users/<b>currentUser</b>/gitProjects/myParentProject/.git/modules/myChildProjectModule</blockquote>
</li>
</ul>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-52598909877959707712012-08-14T08:13:00.000-07:002012-08-14T08:17:11.432-07:00Replacing X11 with XQuartz on Mountain Lion<ol>
<li>
It is a bit of a surprise to realize that X11 is missing from your system after an upgrade to Mountain Lion. Apple does a <a target="_blank" href="http://support.apple.com/kb/HT5293">good job of pointing the user</a> to XQuartz but something critical is lacking!
</li>
<li>
Apparently the <a target="_blank" href="http://xquartz.macosforge.org/landing/">installation</a> (X11 2.7.2 - 2012.06.01 - First release supported on Mountain Lion) needs to be run twice in order for it to be successful.
</li>
<li>
The first time it asks for a system restart after which the programs which are supposed to pick-up on and start using it are still asking dumb question like "Where is X11?"
</li>
<li>
If you run the installation a second time though, it will now place an app called XQuartz in your system and you can launch it from Spotlight.
</li>
<li>
Afterwards, you are no longer asked the question: "Where is X11?" ... the dependent applications simply work :)
</li>
</ol>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-22588723323604145782012-08-09T13:11:00.000-07:002012-09-17T12:29:19.564-07:00Upgrade mountain lion, macports, xcode (4.3 to 4.4)<ul>
<li>
Some leads on google led me to realize how easy it was to upgrade XCode command line tools as shown in the snapshot, afterwards the macports updates went through just fine:
<ul>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7hMGorffIkuJCiaLsnTj9NAIjFVDB6t9L7stVMvupd2lTbFeRxD9bowk8u6FHEu3kNCja6CvTBEAYytiF7Yn72opi5ZoPAQML4rjaHxtj8gSPAWnzIFlbaaHLY_w0QEreQCy1KGQ1yW8/s1600/Screen+Shot+2012-08-09+at+3.04.28+PM.png" imageanchor="1" style="clear:right; float:right; margin-left:1em; margin-bottom:1em"><img border="0" height="238" width="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7hMGorffIkuJCiaLsnTj9NAIjFVDB6t9L7stVMvupd2lTbFeRxD9bowk8u6FHEu3kNCja6CvTBEAYytiF7Yn72opi5ZoPAQML4rjaHxtj8gSPAWnzIFlbaaHLY_w0QEreQCy1KGQ1yW8/s320/Screen+Shot+2012-08-09+at+3.04.28+PM.png" />
</a>
</div>
<li>
<a href="http://scotty-t.com/2012/02/19/os-x-10-8-mountain-lion-preview-macports/">http://scotty-t.com/2012/02/19/os-x-10-8-mountain-lion-preview-macports/</a>
</li>
<li>
<a href="https://discussions.apple.com/thread/4135259?start=0&tstart=0">https://discussions.apple.com/thread/4135259?start=0&tstart=0</a>
</li>
</ul>
</li>
</ul>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-80488909067033061172012-08-09T07:26:00.001-07:002012-08-09T07:27:52.249-07:00Upgrade Eclipse to WTP<ul>
<li>
Upgrading eclipse to its WTP (Web Tools Platform) counterpart can often be quite a painful process as you can run into compatibility issues when Eclipse is done calculating the dependencies. Often when this happens its an indication that you need to figure out the exact release of your Eclipse installation and then add the corresponding WTP url that will allow for downloads matching that version.
</li>
<li>
I went to look in the <b>About</b> section of Eclipse but that only told me <b>Eclipse SDK Version: 3.7.2</b> and I didn't find that very helpful for Google searches. But then I noticed that on the splash page, which launches before Eclipse comes up, it said <b>Indigo</b>.
</li>
<li>
This quickly led me to perform a Google search and add the appropriate URL <u>http://download.eclipse.org/webtools/repository/indigo/</u> for downloading and installing WTP platform. Afterwards with only that URL selected as the repository for the upgrade, there were no dependency errors at all :)
</li>
</ul>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-9329984942729935882012-07-18T06:02:00.001-07:002012-07-18T06:02:38.549-07:00Scan line indicator for ZBar overlaysZbar is a great tool but I often struggle with adding intuitive graphics to the overlay screens in order to clue-in the users to the fact that scanning has already begun in video mode and they just need to point their camera at a barcode.
To that end, I've decided that a red colored line dragging up and down on the screen is a great way to get the point across. And the code applies to any scanning framework that lets you mixin an overlay, not just ZBar.
<script src="https://gist.github.com/3136074.js"> </script>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com0tag:blogger.com,1999:blog-7319157502989369851.post-89945621824046736182012-06-15T12:37:00.000-07:002014-02-21T07:38:16.480-08:00How to use named functions with Async waterfall in node.jsLets start with a real world example where you want to create a user in CouchDB. This is a two step process that involves asking for a unique uuid and then creating a user based on that.
<ul>
<li>
The <a href="javascript:togglecomments('cm1')">following code (+/-)</a> abstracts out each individual step:
<div class="commenthidden" id="cm1">
<script src="https://gist.github.com/2938316.js?file=abstracted_methods.js">
</script>
</div>
</li>
<li>
But once you have the abstracted methods, how do you chain their results? This is where the <a target="_blank" href="https://github.com/caolan/async#waterfall">waterfall</a> approach from the <a target="_blank" href="https://github.com/caolan/async">Async</a> NPM package comes in.
</li>
<li>
Since you've already abstracted your methods, you may try something <a href="javascript:togglecomments('cm2')">like this (+/-)</a> to make them a little more waterfall friendly:
<div class="commenthidden" id="cm2">
<div id="waterfall_friendly_methods"></div>
</div>
</li>
<li>
And then you may try the simplest way you can think of asking waterfall to run:
<div id="does_not_work"></div>
</li>
<li>
But that will fail to run because the syntax of the sentence has ended up being written in a manner where callback must be a variable that is already defined and ready to be used. Making an anonymous method here and bringing up the entire code bodies of the abstracted named-methods would defeat the readability and reuseability that we have been trying to achieve. Here's a tweak that will make it happen:
<div id="works"></div>
</li>
</ul>
<style type="text/css">
.commenthidden {display:none}
.commentshown {display:inline}
</style>
<script type="text/Javascript">
function togglecomments (postid)
{
var whichpost = document.getElementById(postid);
if (whichpost.className=="commentshown")
{
whichpost.className="commenthidden";
}
else
{
whichpost.className="commentshown";
}
}
</script>
<script
src="http://code.jquery.com/jquery-1.6.4.min.js"
type="text/javascript"
charset="utf-8">
</script>
<script
src="https://raw.github.com/iamnoah/writeCapture/master/writeCapture.js"
type="text/javascript"
charset="utf-8">
</script>
<script
src="https://raw.github.com/iamnoah/writeCapture/master/plugin/jquery.writeCapture.js"
type="text/javascript"
charset="utf-8">
</script>
<script type="text/javascript">
$(document).ready(
function() {
var $captured1 = $('#waterfall_friendly_methods');
$captured1.writeCapture().html(
'<scrip'+'t src="https://gist.github.com/2938316.js?file=waterfall_friendly_methods.js"> </s'+'cript>',
function() {
$('#LC1, #LC12, #LC18, #LC34', $captured1).css({'background-color': 'yellow',
'color': 'green'});
}
);
var $captured2 = $('#does_not_work');
$captured2.writeCapture().html(
'<scrip'+'t src="https://gist.github.com/2938316.js?file=does_not_work.js"> </s'+'cript>',
function() {
$('.line', $captured2)
.slice(2, 4)
.css({'background-color': 'yellow',
'color': 'green'});
}
);
var $captured3 = $('#works');
$captured3.writeCapture().html(
'<scrip'+'t src="https://gist.github.com/2938316.js?file=works.js"> </s'+'cript>',
function() {
$('.line', $captured3)
.slice(2, 8)
.css({'background-color': 'yellow',
'color': 'green'});
}
);
});
</script>Tikluphttp://www.blogger.com/profile/01430974801934581545noreply@blogger.com3