For WeatherSupermarket I need to layout a grid forecasts for five days for up to six providers, Met Office, AccuWeather etc. I have the providers vertically, each with the location, and a dropdown box to change the location. The days are laid out horizontally. This has always worked fine for Desktop browsers with plenty of pixel real estate, but not for mobiles where there is limited width.

Mon 17th

Tue 18th

> more days…

Met Office

Forecast

Forecast

Forecast

Weather Channel

Forecast

Forecast

Forecast

AccuWeather

Forecast

Forecast

Forecast

BBC

Forecast

Forecast

Forecast

MetCheck

Forecast

Forecast

Forecast

The Weather Channel

Forecast

Forecast

Forecast

Possible solutions

I looked at making the table header fixed on the left and scrolling horizontally, however this is difficult if you have both vertical and horizontal headers which need to remain on display at all times.

I also tried using floating divs, however this did not work as the forecast cells are all different heights which isn’t known in advance. e.g. Met Office forecasts have a lot of detail, but BBC are one liners.

Solution

I kept the markup how it was, but introduced some JavaScript to use the window width to approximate the number of days that can be comfortably shown at one time. To allow the user to see other days, there are two large buttons to move left and right – these are enabled only when there are more columns available in that direction.

For dynamic updates – e.g. resizing the window, or flipping a mobile/tablet between portrait and landscape I put a change listener of the window object.

Note this only the spriting dynamic part. I had existing handcrafted CSS for background-attachment, width, height etc. This is then imported into my main.css using @import and then inlined/optimized later in the build process.

The input/textarea placeholder attribute implemented using jQuery and data- attributes. Custom data attributes are only standardized in HTML5 but pretty much every browser ever has supported them via DOM setAttribute() which jQuery attr() delegates onto.

JSON support for IE8. I actually found this was only necessary when I needed to do raw JSON.stringify() calls etc. jQuery $.ajax is coded to use a regex/eval solution if the JSON native object does not exist. So I only included the Douglas Crockford json2.js on one of the sites in question.

The problem…

I’m rewriting weathersupermarket, a screen scraper for weather forecasts using Rails. This is the basic logic of server forecast service.

user requests forecast for location 123
get location 123 from database
if last forecast retrieved more than N seconds ago
retrieve new forecast
save forecast
update last retrieved time
then
return results from database
end

This works fine, but when it comes to handling requests from different users concurrently it sucks. Why. By default rails runs in a single threaded mode, serving one request than the next.

More threads can help?

I realise that throwing more threads at a problem doesn’t help unless you’ve got cores to service those threads. However in my case a lot of the blocking work is IO bound, i.e. requesting data from remote sites. For example, two users request data for London and Manchester, in theory the downloading of the forecasts can be done in parallel…

Enabling multithreading

Usefully, Rails 4.0 enables config.threadsafe! by default, so no work required. However the default development server WEBrick does not support it. However the lightweight server thin does. By default it supports 1024 concurrent connections – my app will break long before that!

Next problem

Enabling multi-threading creates a unique problem for my app. Some requests can take 5-10 seconds to complete. If there were to be another request for the same data during that period then the work would be done again, in parallel, this is not ideal.

My solution is to introduce a proxy around my service class with the following logic.

if this request being processed already
wait for other thread to complete
return results from other thread
else
add request to hash map with current thread
do the work
save the result
end

This is the implementation with the necessary Mutex to protect the internal state.

Next problem

So everything is great now. Well, not really… I’m using ActiveRecord

…and then problem is actually slightly more complicated than I explained above… As an optimization to simplify and improve client speed the service interface supports requests for up to 6 locations in parallel, the worst case. This happens when a search for say ‘London’ returns results from all 6 forecast providers.

So with ActiveRecord a database connection is required for every thread that accesses the database. Requests from the threads coming from the controllers seem fine as the same ones are used over and over again, however when I started accessing the database from newly spawned threads I got Timeout errors. It seems that connections are held until released or the reaper gets them. You can help ActiveRecord out by telling it when you’re done with access on the current thread using release_connection

I’ve just been working on code to dynamically show/hide columns in a horizontal table to fit the width of the browser, i.e. show 1 column on 320px mobile, but all on desktop etc.

To support this I need to animate the Nth cell from each row concurrently.

Firstly create an empty selector $([]). Apparently $() used to work but functionality has changed between jQuery versions.

Secondly, append jQuery objects to the empty selector using add(). e.g. selector = selector.add(foo). Note add() returns a new selector. The push() method does exist, but this is marked for internal use only.

Dreamhost ‘Extra Web Security’ option in the dreamhost panel causes this issue, this is just a switch for mod_security. It explicitly blocks IE6, but only the SV1 UA variant. I tried a whole load of user agents, including those all the way back to IE2 on Windows 3.1. Only the SP1+ WinXP IE6 variant is blocked.

I contacted supported, their response is IE6 is “not supported” so not going to do anything about it. I replied explaining the issue again but no luck.

In 2013 I vowed never to write a line of PHP again, it’s dirty and bad for your CV. When it came to implementing a basic AJAX form for a small campaign website I decided to use my new friend Ruby, but wasn’t as straightforward as I had hoped…

The site is otherwise static so using rails seemed like a bit of overkill, along with the deployment hell it causes with dreamhost. Yes the performance of CGI isn’t great compared to PHP with fast CGI mode, but we’re only talking small traffic volumes.

The ruby CGI script reads the POST data from standard input, sends the necessary headers. The whole thing is wrapped with an exception handler to avoid returning HTTP 500 errors that would otherwise occur with a non-zero exit status.The script either returns JSON {success:true} or {success:false, message:’…’}

With dreamhost it is important to tell the mail gem to use sendmail rather than SMTP otherwise you’ll get into all sorts of authentication issues.

Also with shared hosting you need to setup a custom gem directory e.g ~/.gems, gem install mail, and set the GEM_HOME variable before the call to require ‘mail’

The JavaScript reads the values from two input fields, converts to JSON and posts to /app/contact. The result from the HTTP POST is also JSON so that response is handled and relevant feedback given to the user.

Bizare issue on OS X 10.6 effecting both Mail and Thunderbird. Mail simply fails to download inbox, silently without error – helpful. Thunderbird reports “server email@example.org has disconnected. The server may have gone down or there may be a network problem”