JavaScript Evaluation for Erlang Applications

If you are an Erlang developer you are likely familiar with the Riak storage engine, and how the MapReduce feature can evaluate arbitrary JavaScript expressions. Can you use this same code to do your own JavaScript evaluations for your Erlang projects? Yes, and it turns out to be surprisingly easily.

Getting your development environment running erlang_js is the first order of business. I’ve done all of my testing on a Mac OS X system, both Lion (10.7) and Mavericks (10.9). I use Erlang R14B04 for these tests, since that version is what we primarily target at the office.

If you want to manage multiple versions of Erlang on your OS X system, I highly recommend the erlbrew utility as a quick and easy way to maintain multiple versions. We’ve recently made it support R14 builds on OS X Mavericks, so there’s no excuse not to use it!

Assuming you have a working Erlang and OS X command-line development tools active, execute the following to checkout the erlang_js project and build it locally:

git clone git://github.com/basho/erlang_js.git
cd erlang_js; make all test

One of the most compelling uses of a JavaScript engine from another language like Erlang is the ability to pass arbitrarily deep objects as JSON so they can be evaluated. This allows your application to use JavaScript as a general-purpose expression language even if the objects are backed by an Erlang term. This is effectively what you get with Riak when using the MapReduce feature.

As an example, let’s imagine a deeply nested data structure that represents a server configuration. We’d like to execute a JavaScript expression against that data to find the first active network interface. Here’s an example of how you’d do it using erlang_js:

% Start the erlang_js application and driver.
ok = application:start(erlang_js).
{ok, JSDriver} = js_driver:new().
 
% Create a deeply-nested data structure to evaluate
ServerObj = {struct, [
    {<<"id">>,<<"foobar.example.org">>},
    {<<"type">>,<<"linux">>},
    {<<"interfaces">>, [
        {struct, [
            {<<"name">>,<<"eth0">>},
            {<<"ipaddress">>,<<"192.168.1.101">>},
            {<<"enabled">>,true}
        ]},
        {struct, [
            {<<"name">>,<<"eth1">>},
            {<<"ipaddress">>,<<"192.168.1.102">>},
            {<<"enabled">>,true}
        ]},
        {struct, [
            {<<"name">>,<<"bridge0">>},
            {<<"enabled">>,false}
        ]}
    ]}
]}.
 
% Evaluate our object with an arbitrary JavaScript expression
JSFun = <<"function is_any_interface_enabled(Server) { for (var i = 0; i < Server.interfaces.length; i++) { if (Server.interfaces[i].enabled) return true; } return false; }">>.
 
js:call(JSDriver, JSFun, [ServerObj]).

The real trick is building your Erlang data structure properly so that the custom version of mochijson2 can encode the object as JSON. As you see from the examples, use tuples with a struct atom as the first member to specify an object. Arrays are just arrays.

I have noticed that it is very easy to confuse a single instance of the js_driver object and it is hosed until a new one is created, so consider that in how you structure your driver usage.

 

URL Shortening for Mac OS X and iOS

Today I’m releasing version 1.0.0 of URLKit, a library to find and shorten URLs for Mac OS X and iOS applications.

URLKit was written to order to provide URL shortening services to messaging applications where users may be providing multiple URLs in a single input buffer. I needed the ability to shorten multiple URLs at once and to do so without slowing down the main user interface.

URLKit is implemented using Grand Central Dispatch’s operation queues, so your main UI queue is never blocked by URL shortening operations.

Using URLKit is easy:

@interface MyController : NSObject
@end
 
@implementation MyController
 
- (void)doSomethingAwesome
{
    const URLShortener *shortener = [URLShortener defaultURLShortener];
 
    const NSString *text = @"hello, this is cool: http://newoldage.blogs.nytimes.com/2013/02/01/caregiving-laced-with-humor/?hp but this one isn't that cool http://religion.blogs.cnn.com/2013/01/29/poll-quarter-of-americans-say-god-influences-sporting-events/";
 
    [shortener shortenTextWithURLs:text observer:self];
}
 
- (void)textWithURLsShortened:(NSString *)text
{
    ...
}
 
@end

URLKit can be found at https://github.com/dcgibbons/URLKit and is licensed using the Apache 2.0 license. Comments and patches are welcome!

Project Dependencies and Include Files in Xcode

I have read a lot of how-to guides on blogs over the past few years on how to set it up Xcode sub-projects so you can build your project, a dependent sub-project, and have all the header files and libraries be found. Invariably, this involves changing Xcode project settings both in your main application, and in the sub-project so that everything works out. This is wrong!

The proper way to build sub-projects is that a user of your sub-project does not have to do anything but:

  1. Include the .xcodeproj project file.
  2. Add the project to the top project’s dependencies.
  3. Link against the proper library.

If you are having to do more, then the sub-project was not designed correctly.

As it turns out, Xcode already does this right, but the proliferation of how-to guides usually get it wrong and make developers go through more hoops than they need to. Let’s walk through doing it the right way. Note: this post was written with Xcode 4.4 and 4.5 in mind, so older versions may have had different ways of doing things.

For the purposes of this example we need something simple. Let’s just write a Hello World application that uses an external framework to get the text – it will demonstrate all that we need. Also, we will only cover projects targeted for iOS within this post, but look for a follow-up post that discusses extending these projects to work on Mac OS X as well.
Continue reading Project Dependencies and Include Files in Xcode

Lessons Learned on using Chef from Development to Production

Over the past six-months, my team at Alert Logic started and deployed a project where we made heavy use of the Chef infrastructure automation tool. We decided to use Chef from the ground up in our development cycle, from initial coding and testing all the way through final production deployment. Here are some important lessons we learned from the experience.