All > Coding

  • Profiling a Slow Elixir Test

    I noticed that a couple of tests in my current Elixir project were a little slow, so I set out to find a way to profile them… I quickly found this this helpful blog post (thanks, Joseph Kain!), and tried out ExProf — but afterward, like Joseph said, “At this point I was a little confused by the results.”

    So I kept reading Joseph’s post, wherein he tried out Erlang’s fprof. This looked better (as he says) because fprof supports display of call chains, providing a lot more useful context. Better still, I found his followup post that taught me about how recent versions of Elixir come with a Mix task (mix profile.fprof) for profiling that produces friendlier output.

    The Mix task didn’t give me an easy way to wrap a slow test, though: it’s good for measuring an easily-isolatable bit of code like a single function, but sometimes tests involve setup that’s harder to isolate… so I cooked up this little macro and dropped it into my project’s test/test_helper.exs:

    defmodule FProf do
      defmacro profile(do: block) do
        content = quote do
          Mix.Tasks.Profile.Fprof.profile(fn -> unquote(block) end,
            warmup: false, sort: "acc", callers: true)
        end
        Code.compile_quoted(content)
      end
    end
    
    … (read more)
  • A Nerves tidbit

    I’ve been working on learning the Elixir programming language for the last several months, and after returning from ElixirConf a few weeks ago, I was inspired to try a small project with Nerves, a platform for building Elixir applications on small devices like the Raspberry Pi.

    Nerves provides a toolchain for building on the Mac which results in it writing a bootable microSD card that I boot in the Pi to try out my code. There’s a lot of complexity in what Nerves is doing for me, but one little bit (not Nerves’ fault!) annoyed me: I had to enter my login password every few minutes when Nerves wanted to write to the microSD card.

    I just found a way around this. The build command I use, every time I want to make a change, is this (I’ve broken it onto multiple lines for clarity) –

    (cd apps/project &&              # switch into my app
    MIX_ENV=prod mix firmware &&     # build the disk image
    
    (until [ -d /Volumes/BOOT ];     # wait for me to reinsert the card
     do sleep 1;
    done) &&
    
    sudo chmod go+rw /dev/rdisk2 &&  # Make the raw disk image writable
    
    MIX_ENV=prod mix firmware.burn -d /dev/rdisk2 &&  # write to the SD card
    
    sync &&                          # flush changes - I'm paranoid
    sleep 1)
    

    That sudo chmod command is the point of this post: without it, every time I did a new build, I had to enter my password, because Nerves invokes a tool called fwup to write the image, and fwup uses authopen to get authenticated access to the raw file. This permissions fix has to be done every time the microSD card is reinserted. (I’ve already set up my /etc/sudoers file to allow me to use sudo without entering my password each time.)

    … (read more)
  • RubyMine, Firefox, and Exception Backtraces

    I use RubyMine and Firefox for most of my day-to-day Ruby on Rails development, and in spite of my best efforts, I sometimes get exceptions that result in the display of Ruby backtraces instead of the web page I asked for.

    … (read more)
  • Quicker WEBrick startup

    Despite its popularity WEBrick has gained some notoriety since the code is completely undocumented.

    Wikipedia’s WEBrick page

    WEBrick is the little web server in the Ruby standard library, and I’ve used it several times when I’ve needed to embed a little server in a project. I noticed a couple of problems in my latest little program: it took a few seconds to start up, and always included a TCPServer Error: Address already in use - bind(2) warning in its startup messages.

    … (read more)
  • Older Posts

  • Rails 2.3.3 + mocha = confusion

  • Automatic wireless goodness

  • Fixing a little VPN annoyance

  • The Android fonts on my desktop are beautiful

  • Android AIDL regeneration

  • Clearing apt-cacher's cache

  • Rails script/performance/request needed a little help

  • named_scope, joins, & includes

  • Basking in benefits of connectedness

  • Hiding in plain sight

  • Festival Fanatic is finally useful

  • Happy Birthday, FestivalFanatic (and Macintosh)

  • Remote debugging with Wing

  • My Chumby transit widget

  • Horrible hack to work around a RubyGems bug

  • So why Rails?

  • Long time no post

  • RailsConf? But what about Chandler?

  • How quickly daft jumping zebras vex

  • This one time, at DCamp...

  • A thousand words later