Pablo's blog

A bit of this, a bit of that and a lot about computers

Dancing

Couple dancing

Photo by mattcornock

I started taking dancing lessons recently. It was something that’s been on my to-do list for maybe half my life… but that’s another story. I went for ballroom and latin dancing lessons at The Dance of Life Studio. I think the teacher, Angelo, is great.

Angelo shows us a move, first to the gents and then to the ladies or the other way around. We practice it by ourselves for a little while and then the expected but also dreaded time comes: to try it out with a partner.

I walk to a partner, take her right hand with my left and set into position. It’s like walking to the edge of a cliff and peek down. The excitement! The expectation! 2… 3… 4… we jump! Most of the time, we crash. Sometimes even literally!

But sometimes, we fly! Together we rise above the horizon and I wish we would never land again. It’s magic!

Thanks for reviewing this post to: Daniel Magliola and Romina Roca.

Strange experience when viewing a flat

I recently moved to London and I’m looking for a flatshare close to the office. I went to see one and after we did the usual tour of the whole house and we sat down for a little chat, something unexpected happened… the lights went off.

A big dark house

Picture by Ben Gilman

The lights and everything. Total black out. The woman receiving me quickly confirmed that it was the whole block. I suppose we both felt better about it. It wasn’t something wrong at the house.

I used the flashlight… or should I say torch? in my phone and she was glad we got some light. The situation was less than ideal… but some laugh, light some candles and it would have been alright. Something else happened.

The alarm… that alarm that is installed at the house but nobody uses and it’s supposedly disabled. That alarm started to making a loud horrible noise. What a pain! We tried calling the numbers in the alarm box but those lines were disconnected. When I left it was still hauling. So weird.

Moving to London, joining a startup

The Palace of Westminster at night seen from the south bank of the River Thames.

London by Jim Trodel

I’m making a lot of changes in my life. I’m moving to London… tomorrow. I’m really excited about it. I wanted to live in London for a while already. In that topic, do you know anyone that wants to share a flat in the London Bridge area?

Also, I’m changing jobs. In London I’m joining a startup called Watu. Well, I’m part of the founding team and I’ll be the CTO, which for now, it’s just an overly fancy way to say the coder, but I like it. We are solving the problem of managing employees from publishing the open positions at a company to interviewing, to paying salaries, to assigning and managing shifts. The whole deal. I’m really excited about it and I’m looking forward to it.

Learning to shoot a handgun

Finally I managed to go to a course to learn to shoot a handgun. Generally I would prefer to spend money on things. For the price of the course I could have bought a great airgun, but happier people spend money on experiences, not on things. I’m trying to learn.

The first lesson was with a .22 handgun. The teacher lent me his own CZ 122 of which I took a picture:

Picture of CZ 122 Sport, part black and silver, with the slider open

CZ 122 Sport, the one I shot with.

I loved shooting with that one. It worked really well. Much better than the other really used up guns for beginners. On the second lesson we went up in calibre to a Bersa Thunder 9:

Stock picture of a pistol Bersa Thunder 9, black

Bersa Thunder 9.

I learned something very important. The teacher told us to load 5 rounds and shoot them. I did that, put down the gun and moved the target back to me. I counted 4 holes. I doubt I missed the target completely because those four holes were very close to the center. Then I looked down to the table and the gun: it was still loaded, there was still one round in the chamber and ready to fire. In my mind that gun was unloaded; but it wasn’t. I obviously treated it as loaded even when I believed it wasn’t because of… well… this.

Me, shooting in a very controlled environment, knowing I had to count the shots, and I miscounted. I’ll never laugh again at anybody for not counting the number of shots correctly. It’s so easy to make a mistake. And always, always treat every gun as loaded… they might be.

Thanks for reading a draft of this to Ethan Blanton.

Uptime: 100%

Balance by Tony Roberts

This is the first time I see this:

-------------------------------------
pupeno.com
Service: pupeno.com
Outages: 0
Downtime: 0 hrs, 0 mins
Uptime: 100.00%
-------------------------------------

It was always above 98%, often above 99% and I was proud of that because it was my own crappy server doing it. But now I’m proud of not caring about it, letting someone else solve a problem I’m not interested in and focus on what I am interested in. 100% uptime provided by WordPress.com.

You think airline food sucks?

Vegetarian Meal #3 by James Perkins

You think airline food sucks? Try being vegetarian. I’m not a spoiled whiner, I truly appreciate being able to cross an ocean over night and I’m fine with the mass produced food they serve in airplane. Everybody complains about the food, but when you are vegetarian, you go into a new level of pain.

The first part of the pain: requesting it. I request the vegetarian food several times. I already had requests lost, ignored, not honored, whatever. I request it on the web, by phone, by carrier pigeon, etc. Several times each. Even then, there’s no guarantee.

Then it comes the second part: the crew. I just finished my breakfast in a flight from Madrid to Buenos Aires (yes, I wrote this on the airplane) with the best and the worst of the crew. I’ll describe both to be fair.

One flight attendant gave me the special food. She said “You ordered special food? ” and I replied “Yes, vegetarian “, and she handed me the long yellow box. I opened it and found little pieces of burned carcasses of chicken. I checked the label… definitely not vegetarian.

When another flight attendant came I told him about my food and they had a short conversation. Basically all non-standard food was distributed equally. Someone who should have gotten chicken was eating my vegetarian food. This is the norm. The crew will screw it up. In my experience almost always. I very rarely get an uneventful flight.

The flight attendant to whom I reported the issue was a little bit upset about the other messing up and here’s the good part: he went and picked vegetarian food from other meals and built a special box for me. To that guy, J. M. Anton: Thank you, I really appreciate what you did… you turned a terrible flight and a lot of anger into a pleasurable experience (loved the little piece of chocolate).

Should everything go well you still have to deal with the food. You may think that when everybody gets a cheese and ham sandwich you’d get a cheese sandwich. WRONG. You may imagine that when everybody gets spaghetti with meatballs you’d get plain spaghetti. WRONG. You get an insipid salad (for breakfast) or some gooey boiled vegetables. On this flight I was lucky to get some rice (next to the gooey vegetables). Who chooses this food? It’s terrible. It’s a torture. Compared to this, the food is got at the hospital is a 5 star gourmet meal.

Changing my pictures workflow

Canon camera by Kazuhiko Teramoto

I been using iPhoto for a few years right now and I like it a lot. Before using iPhoto I was manually marking who was in each picture and where it was taken, so when I saw iPhoto could do it almost automatically I bought a mac. Yes, iPhoto was a big part of buying a mac.

Some time afterwards, I got a DSLR, starting shooting in raw, and as usual, shooting a lot. I rarely remove pictures. I don’t see a reason, my hard drives get bigger faster than I take pictures. My collection has around 35000 pics, at least, and lot’s of raw too. This is not what iPhoto is designed for.

I looked around and Apple’s Aperture is the only pro photo management software that keeps all the features I need and like from iPhoto (faces and places mostly). Since the latest iPhoto is not very robust (it actually crashed on me once and I had to restore everything from backups), I decided to migrate to Aperture.

Something that surprised me about Aperture is that it doesn’t prompt me to delete the pictures after importing. I searched on the interwebs about this and apparently, it’s a feature. When people asked how to delete pictures, people replied: “Don’t! If you delete pictures after importing, your pictures are in only one place, if something happens to them, they are lost.”

One should be careful when getting advice on how to use an Apple product as the Apple fanboys will defend whatever Apple believes we should do even if it makes no sense and kills kittens in the process. But this actually makes sense. I had my computer crash during the import procedure and take all the pics with it. I’m glad iPhoto didn’t get to delete the pictures in the camera when that happened. Both Aperture and iPhoto are capable of ignoring duplicates when importing and I would expect any other useful picture management program to do the same.

I decided to embrace the workflow, I bought a bigger memory card for my camera and now I don’t delete the pics from the camera until a couple of days later, when my several backups solutions managed to backup the new pictures.

Another reason to do it this way, and delete pictures by formatting the memory card, is that it’s the only way to ensure there are no extraneous files on the card, taking space, that neither the camera nor any program need or understand.

What do you think about polls?

Full URL in Rails’ logs

I find myself needing to have the full URLs in Rails’ logs. Normally you get something like:

Started GET "/" for 127.0.0.1 at 2011-08-27 13:13:10 +0200

but I needed

Started GET "http://foo.bar:3000/" for 127.0.0.1 at 2011-08-27 13:13:10 +0200

because the app does different things depending on the domain and when it fails, I have to know which URL was hit. The solution I ended up with was adding this in an initializer:

class Rails::Rack::Logger << ActiveSupport::LogSubscriber
  protected

  def before_dispatch(env)
    request = ActionDispatch::Request.new(env)
    info "\n\nStarted #{request.request_method} \"#{request.url}\" for #{request.ip} at #{Time.now.to_default_s}"
  end
end

That’s monkey-patching Rails’ own logger. Credit for the solution goes to numbers1311407.

My question for the people using Rails, do you think having a configurable logger in Rails would be useful or nice? If so, I could make a patch for Rails but I have made patches before that failed to gather the needed popularity and thus were ignored. I’m not wasting my time like that again.

How to use Lobos with Heroku

Lobos is a Clojure library to create and alter tables which also supports migrations similar to what Rails can do. I like where Lobos is going but it’s a work in progress, so the information here might be out of date soon, beware!

Let’s imagine a project called px (for Project X of course) with the usual Leiningen structure. In the src directory you you need to create a lobos directory and inside there let’s get started with config.clj which contains the credentials and other database information:

(ns lobos.config)

(def db
  {:classname "org.postgresql.Driver"
   :subprotocol "postgresql"
   :subname "//localhost:5432/px"})

then we create a simple migration in lobos/migrations.clj that creates the users table:

(ns lobos.migrations
  (:refer-clojure :exclude [alter defonce drop bigint boolean char double float time])
  (:use (lobos [migration :only [defmigration]] core schema) lobos.config))

(defmigration create-users
  (up [] (create (table :users
                   (integer :id :primary-key)
                   (varchar :email 256 :unique))))
  (down [] (drop (table :users))))

You run a REPL, load the migrations and run them (using the joyful Clojure example code convention):

(require 'lobos.migrations)
;=> nil
(lobos.core/run)
;=> java.lang.Exception: No such global connection currently open: :default-connection, only got [] (NO_SOURCE_FILE:0)

and you get an error because you didn’t open the connection yet, so, let’s do that:

(require 'lobos.connectivity)
;=> nil
(lobos.connectivity/open-global lobos.config/db)
;=> {:default-connection {:connection #<Jdbc4Connection org.postgresql.jdbc4.Jdbc4Connection@2ab600af>, :db-spec {:classname "org.postgresql.Driver", :subprotocol "postgresql", :subname "//localhost:5432/px"}}}

and now it works:

(lobos.core/run)
; create-users
;=> nil

and you can also rollback:

(lobos.core/rollback)
; create-users
;=> nil

You might be tempted to open the global connection in your config.clj and that might be fine for some, but I found it problematic that the second time I load the file, I get an error: “java.lang.Exception: A global connection by that name already exists (:default-connection) (NO_SOURCE_FILE:0)”.

My solution was to write a function called open-global-when-necessary that will open a global connection only when there’s none or when the database specification changed, and will close the previous connection in that case, leaving a config.clj that looks like:

(ns lobos.config
  (:require lobos.connectivity))

(defn open-global-when-necessary
  "Open a global connection only when necessary, that is, when no previous
  connection exist or when db-spec is different to the current global
  connection."
  [db-spec]
  ;; If the connection credentials has changed, close the connection.
  (when (and (@lobos.connectivity/global-connections :default-connection)
             (not= (:db-spec (@lobos.connectivity/global-connections :default-connection)) db-spec))
    (lobos.connectivity/close-global))
  ;; Open a new connection or return the existing one.
  (if (nil? (@lobos.connectivity/global-connections :default-connection))
    ((lobos.connectivity/open-global db-spec) :default-connection)
    (@lobos.connectivity/global-connections :default-connection)))

(def db
  {:classname "org.postgresql.Driver"
   :subprotocol "postgresql"
   :subname "//localhost:5432/px"})

(open-global-when-necessary db)

That works fine locally, so let’s move to Heroku. To get started with Clojure on Heroku I recommend you read:

  1. Getting Started With Clojure on Heroku/Cedar
  2. Building a Database-Backed Clojure Web Application

I took the code used to extract the database specification from DATABASE_URL but I modified it so I don’t depend on that environment variable existing on my local computer and I ended up with the following config.clj:

(ns lobos.config
  (:require [clojure.string :as str] lobos.connectivity)
  (:import (java.net URI)))

(defn heroku-db
  "Generate the db map according to Heroku environment when available."
  []
  (when (System/getenv "DATABASE_URL")
    (let [url (URI. (System/getenv "DATABASE_URL"))
          host (.getHost url)
          port (if (pos? (.getPort url)) (.getPort url) 5432)
          path (.getPath url)]
      (merge
       {:subname (str "//" host ":" port path)}
       (when-let [user-info (.getUserInfo url)]
         {:user (first (str/split user-info #":"))
          :password (second (str/split user-info #":"))})))))

(defn open-global-when-necessary
  "Open a global connection only when necessary, that is, when no previous
  connection exist or when db-spec is different to the current global
  connection."
  [db-spec]
  ;; If the connection credentials has changed, close the connection.
  (when (and (@lobos.connectivity/global-connections :default-connection)
             (not= (:db-spec (@lobos.connectivity/global-connections :default-connection)) db-spec))
    (lobos.connectivity/close-global))
  ;; Open a new connection or return the existing one.
  (if (nil? (@lobos.connectivity/global-connections :default-connection))
    ((lobos.connectivity/open-global db-spec) :default-connection)
    (@lobos.connectivity/global-connections :default-connection)))

(def db
  (merge {:classname "org.postgresql.Driver"
          :subprotocol "postgresql"
          :subname "//localhost:5432/px"}
         (heroku-db)))

(open-global-when-necessary db)

After you push to Heroku, you can run heroku run lein repl, load lobos.config and run the migrations just as if they were local.

Thanks to Daniel Magliola and Nicolas Buduroi for reading drafts of this.

Post Navigation

Follow

Get every new post delivered to your Inbox.

Join 320 other followers

%d bloggers like this: