Won’t

This developer wanted to create a language selector and asked for help on Twitter. You won’t believe what happened next!

Hey, it works for Upworthy, right?

Yesterday in a weak moment Dhananjay Garg asked me on Twitter to help him with a coding issue and I had some time to do that. Here’s a quick write-up of what I created and why.

Dhananjay had posted his problem on StackOverflow and promptly got an answer that wasn’t really solving or explaining the issue, but at least linked to W3Schools to make matters worse (no, I am not bitter about the success of either resource).

The problem was solved, yes (assignment instead of comparison – = instead of === ) but the code was still far from efficient or easily maintainable which was something he asked about.

The thing Dhananjay wanted to achieve was to have a language selector for a web site that would redirect to documents in different languages and store the currently selected one in localStorage to redirect automatically on subsequent visits. The example posted has lots and lots of repetition in it:

function english()
{
if(typeof(Storage)!=="undefined")
  {
  localStorage.clear();
  localStorage.language="English";
 window.location.reload();
  }
}
 
function french()
{
if(typeof(Storage)!=="undefined")
  {
  localStorage.clear();
  localStorage.language="French";
  window.location.href = "french.html";
  }
}
window.onload = function() {
if (localStorage.language === "Language")
  {
   window.location.href = "language.html";
  }
else if (localStorage.language === "English")
  {
   window.location.href = "eng.html";
  }
else if (localStorage.language === "French")
  {
  window.location.href = "french.html";
  }
else if (localStorage.language === "Spanish")
  {
  window.location.href = "spanish.html";
  }

This would be done for 12 languages, meaning you’ll have 12 functions all doing the same with different values assigned to the same property. That’s the first issue here, we have parameters on functions to avoid this. Instead of having a function for each language, you write a generic one:

function setLanguage(language, url) {
	localStorage.clear();
 	localStorage.language = language;
 	window.location.href = url;
 }
}

Then you could call for example setLanguage(‘French’, ‘french.html’) to set the language to French and do a redirect. However, it seems dangerous to clear the whole of localStorage every time when you simply redefine one of its properties.

The onload handler reading from localStorage and redirecting accordingly is again riddled with repetition. The main issue I see here is that both the language values and the URLs to redirect to are hard-coded and a repetition of what has been defined in the functions setting the respective languages. This would make it easy to make a mistake as you repeat values.

A proposed solution

Assuming we really want to do this in JavaScript (I’d probably do a .htaccess re-write on a GET parameter and use a cookie) here’s the solution I came up with.

First of all, text links to set a language seem odd as a choice and do take up a lot of space. This is why I decided to go with a select box instead. As our functionality is dependent on JavaScript to work, I do not create any static HTML at all but just use a placeholder form in the document to add our language selector to:

<form id="languageselect"></form>

Instead of repeating the same information in the part of setting the language and reading out which one has been set onload, I store the information in one singular object:

var locales = {
    'us': {label: 'English',location:'english.html'},
    'de': {label: 'German',location: 'german.html'},
    'fr': {label: 'Français',location: 'french.html'},
    'nl': {label: 'Nederlands',location: 'dutch.html'}       
};

I also create locale strings instead of using the name of the language as the condition. This makes it much easier to later on change the label of the language.

This is generally always a good plan. If you find yourself doing lots of “if – else if” in your code use an object instead. That way to get to the information all you need to do is test if the property exists in your object. In this case:

if (locales['de']) { // or locales.de - the bracket allows for spaces
	console.log(locales.de.label) // -> "German"
}

The rest is then all about using that data to populate the select box options and to create an accessible form. I explained in the comments what is going on:

// let's not leave globals
(function(){
  // when the browser knows about local storage…
  if ('localStorage' in window) {
    // Define a single object to hold all the locale 
    // information - notice that it is a good idea 
    // to go for a language code as the key instead of
    // the text that is displayed to allow for spaces
    // and all kind of special characters
    var locales = {
        'us': {label: 'English',location:'english.html'},
        'de': {label: 'German',location: 'german.html'},
        'fr': {label: 'Français',location: 'french.html'},
        'nl': {label: 'Nederlands',location: 'dutch.html'}       
    };
    // get the current locale. If nothing is stored in 
    // localStorage, preset it to 'en'
    var currentlocale = window.localStorage.locale || 'en';
    // Grab the form element
    var selectorContainer = document.querySelector('#languageselect');
    // Add a label for the select box - this is important 
    // for accessibility
    selectorContainer.innerHTML = '<label for="languageselectdd">'+
                                  'Select Language</label>';
    // Create a select box 
    var selector = document.createElement('select');
    selector.name = 'language';
    selector.id = 'languageselectdd';
    var html = '';
    // Loop over all the locales and put the right data into 
    // the options. If the locale matches the current one,
    // add a selected attribute to the option
    for (var i in locales) {
      var selected = (i === currentlocale) ? 'selected' : '';
        html += '<option value="'+i+'" '+selected+'>'+
                 locales[i].label+'</option>';
    }
    // Set the options of the select box and add it to the
    // form
    selector.innerHTML = html;
    selectorContainer.appendChild(selector);
    // Finish the form HTML with a submit button
    selectorContainer.innerHTML += '<input type="submit" value="go">';
    // When the form gets submitted…
    selectorContainer.addEventListener('submit', function(ev) {
      // grab the currently selected option's value
      var currentlocale = this.querySelector('select').value;
      // Store it in local storage as 'locale'
      window.localStorage.locale = currentlocale;
      // …and redirect to the document defined in the locale object
      alert('Redirect to: '+locales[currentlocale].location);
      //window.location = locales[currentlocale].location;
      // don't send the form
      ev.preventDefault();
    }, false);
  }
})();

Surely there are different ways to achieve the same, but the important part here is that an object is a great way to store information like this and simplify the whole process. If you want to add a language now, all you need to do is to modify the locales object. Everything is maintained in one place.

View full post on Christian Heilmann

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Building A Node.JS Server That Won’t Melt – A Node.JS Holiday Season, part 5

This is episode 5, out of a total 12, in the A Node.JS Holiday Season series from Mozilla’s Identity team. For this post, we bring the discussion back to scaling Node.JS applications.

How can you build a Node.JS application that keeps running, even under impossible load?

This post presents a technique and a library that implements that technique, all which is distilled into the following five lines of code:

var toobusy = require('toobusy');
 
app.use(function(req, res, next) {
  if (toobusy()) res.send(503, "I'm busy right now, sorry.");
  else next();
});

Why Bother?

If your application is important to people, then it’s worth spending a moment thinking about disaster scenarios. These are the good kind of disasters where your project becomes the apple of social media’s eye and you go from ten thousand users a day to a million. With a bit of preparation you can build a service that can persevere during traffic bursts that exceed capacity by orders of magnitude. If you forego this preparation, then your service will become completely unusable at precisely the wrong time – when everyone is watching.

Another great reason to think about legitimate bursts traffic, is malicious bursts of traffic: the first step to mitigating DoS attacks is building servers that don’t melt.

Your Server Under Load

To illustrate how applications with no considerations for burst behave, I built an application server with an HTTP API that consumes 5ms of processor time spread over five asynchronous function calls. By design, a single instance of this server is capable of handling 200 requests per second.

This roughly approximates a typical request handler that perhaps does some logging, interacts with the database, renders a template, and streams out the result. What follows is a graph of server latency and TCP errors as we linearly increase connection attempts:

Analysis of the data from this run tells a clear story:

This server is not responsive: At 6x maximum capacity (1200 requests/second) the server is hobbled with 40 seconds of average request latency.

These failures suck: With over 80% TCP failures and high latency, users will see a confusing failure after up to a minute of waiting.

Failing Gracefully

Next, I instrumented the same application with the code from the beginning of this post. This code causes the server to detect when load exceeds capacity and preemptively refuse requests. The following graph depicts the performance of this version of the server as we linearly increase connections attempts:

Your server with limits

One thing not depicted on the graph is the volume of 503 (server too busy) responses returned during this run which steadily increases proportional to connection attempts. So what do we learn from this graph and the underlying data?

Preemptive limiting adds robustness: Under load that exceeds capacity by an order of magnitude the application continues to behave reasonably.

Success and Failure is fast: Average response time stays for the most part under 10 seconds.

These failures don’t suck: With preemptive limiting we effectively convert slow clumsy failures (TCP timeouts), into fast deliberate failures (immediate 503 responses).

To be clear, building a server that returns HTTP 503 responses (“server is too busy”), requires that your interface render a reasonable message to the user. Typically this is a pretty simple task, and should be familiar as it’s done by many popular sites.

How To Use It

node-toobusy is available on npm and github. After installation (npm install toobusy), simply require it:

var toobusy = require('toobusy');

At the moment the library is included, it will begin actively monitoring the process, and will determine when the process is “too busy”. You can then check if the process is toobusy at key points in your application:

// The absolute first piece of middle-ware we would register, to block requests
// before we spend any time on them.
app.use(function(req, res, next) {
  // check if we're toobusy() - note, this call is extremely fast, and returns
  // state that is calculated asynchronously.  
  if (toobusy()) res.send(503, "I'm busy right now, sorry.");
  else next();
});

This application of node-toobusy gives you a basic level of robustness at load, which you can tune and customize to fit the design of your application.

How It Works

How do we reliably determine if a Node application is too busy?

This turns out to be more interesting that you might expect, especially when you consider that node-toobusy attempts to work for any node application out of the box. In order to understand the approach taken, let’s review some approaches that don’t work:

Looking at processor usage for the current process: We could use a number like that which you see in top – the percentage of time that the node process has been executing on the processor. Once we had a way of determining this, we could say usage above 90% is “too busy”. This approach fails when you have multiple processes on the machine that are consuming resources and there is not a full single processor available for your node application. In this scenario, your application would never register as “too busy” and would fail terribly – in the way explained above.

Combining system load with current usage: To resolve this issue we could retrieve current system load as well and consider that in our “too busy” determination. We could take the system load and consider the number of available processing cores, and then determine what percentage of a processor is available for our node app! Very quickly this approach becomes complex, requires system specific extensions, and fails to take into account things like process priority.

What we want is a simpler solution that Just Works. This solution should conclude that the node.js process is too busy when it is unable to serve requests in a timely fashion – a criteria that is meaningful regardless of the details of other processes running on the server.

The approach taken by node-toobusy is to measure event loop lag. Recall that Node.JS is at its core an event loop. Work to be done is enqueued, and on each loop iteration is processed. As a node.js process becomes over-loaded, the queue grows and there is more work to be done than can be done. The degree to which a node.js process is overloaded can be understood by determining how long it takes a tiny bit of work to get through the event queue. The node-toobusy library provides libuv with a callback that should be invoked every 500 milliseconds. Subtracting 500ms from the actual time elapsed between invocations gives us a simple measure of event loop lag.

In short, node-toobusy measures event loop lag to determine how busy the host process is, which is a simple and robust technique that works regardless of whatever else is running on the host machine.

Current State

node-toobusy is very new library that makes it easy to build servers that don’t melt by measuring event loop lag: attempting to solve the general problem of determining if a node.js application is too busy. All of the test servers described here as well as the load generation tools used in the post are available on github.

At Mozilla we’re currently evaluating applying this approach to the Persona service, and expect to refine it as we learn. I look forward to your feedback – as a comment on this post, on the identity mailing list, or in github issues.

Previous articles in the series

This was part five in a series with a total of 12 posts about Node.js. The previous ones are:

View full post on Mozilla Hacks – the Web developer blog

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

MobiUs Web Browser Technology From appMobi – You Won’t Believe What the Mobile Web Can Do Now

appMobi® today unveiled MobiUs⢠â the first-of-its-kind mobile Web browser technology that allows developers to create Web applications â or WebApps â that exceed the functionality possible with native apps, putting the entire World Wide Web on equal footing with app stores as the distribution channel for discovering, downloading and interacting with mobile apps. Â

View full post on web development – Yahoo! News Search Results

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)