<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<title>Michael Melanson</title>
	<link href="https://michaelmelanson.net/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="https://michaelmelanson.net"/>
	<generator uri="https://www.getzola.org/">Zola</generator>
	<updated>2020-05-09T18:10:51+00:00</updated>
	<id>https://michaelmelanson.net/atom.xml</id>
	<entry xml:lang="en">
		<title>Up to speed on the new features of Javascript</title>
		<published>2019-11-21T14:31:29+00:00</published>
		<updated>2020-05-09T18:10:51+00:00</updated>
		<link href="https://michaelmelanson.net/posts/up-to-speed-on-es6-javascript/" type="text/html"/>
		<id>https://michaelmelanson.net/posts/up-to-speed-on-es6-javascript/</id>
		<content type="html">&lt;p&gt;A few years ago, many great new features were added to Javascript in the ES5, ES6 and ES7 language versions that make it a much better language for building large web applications and services. If you&#x27;re someone who learned Javascript a few years ago but haven&#x27;t learned these new features, this article will help get you up to speed.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;a-short-history-of-javascript&quot;&gt;A short history of Javascript&lt;&#x2F;h2&gt;
&lt;p&gt;Javascript was created for the Netscape browser in 1995. The first version of the interpreter was written in only about two weeks, and so it was a quick and dirty implementation intended to be used for small interactive features in web pages.&lt;&#x2F;p&gt;
&lt;p&gt;In the next year it was standardized as &amp;quot;ECMAScript&amp;quot; (named after the standards body &amp;quot;European Computer Manufacturers Association&amp;quot;). This is where the name &amp;quot;ES6&amp;quot; comes from, but otherwise the name ECMAScript is rarely used. The language spread and became one of the most widely used languages in the world. A few attempts were made to evolve the language (ECMAScript 2-4) that never really caught on.&lt;&#x2F;p&gt;
&lt;p&gt;But once developers started using Javascript for &lt;em&gt;single-page applications&lt;&#x2F;em&gt; (web applications where all the routing between pages is handled in the browser, not by requesting new HTML pages from the server) in about 2005-2008, people started getting frustrated by its limitations. But it&#x27;s hard to change a language that&#x27;s used so widely.&lt;&#x2F;p&gt;
&lt;p&gt;This led to languages such as CoffeeScript (released in 2009) where developers could write code in a more sophisticated language, which was then compiled to Javascript so it could be run in a browser. This acted as a way to prototype new language features, and many parts of CoffeeScript were eventually rolled back into Javascript in ES5 (2015) and ES6 (2016). The latest version is ES7, released in 2017.&lt;&#x2F;p&gt;
&lt;p&gt;In the rest of this article I&#x27;m going to talk about many of the new features in these most recent releases of the Javascript language.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;new-variable-bindings-let-and-const&quot;&gt;New variable bindings (&lt;code&gt;let&lt;&#x2F;code&gt; and &lt;code&gt;const&lt;&#x2F;code&gt;)&lt;&#x2F;h2&gt;
&lt;p&gt;In old Javascript there was only one way to declare a variable – by using &lt;code&gt;var&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;var name = &amp;quot;Michael&amp;quot;;
console.log(name); &amp;#x2F;&amp;#x2F; prints &amp;quot;Michael&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;var&lt;&#x2F;code&gt; still exists of course, but ES6 added two new &lt;em&gt;binding types&lt;&#x2F;em&gt; (ways of declaring variables): &lt;code&gt;let&lt;&#x2F;code&gt; and &lt;code&gt;const&lt;&#x2F;code&gt;. The difference between them is that &lt;code&gt;let&lt;&#x2F;code&gt; can be reassigned to it, and &lt;code&gt;const&lt;&#x2F;code&gt; can&#x27;t:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const name = &amp;quot;Michael&amp;quot;;
name = &amp;quot;Bob&amp;quot;; &amp;#x2F;&amp;#x2F; error

let name = &amp;quot;Michael&amp;quot;;
name = &amp;quot;Bob&amp;quot;; &amp;#x2F;&amp;#x2F; okay
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But, it&#x27;s important to understand that the &lt;code&gt;const&lt;&#x2F;code&gt; binding doesn&#x27;t make things &lt;em&gt;immutable&lt;&#x2F;em&gt; (unable to be changed at all). It just means that you can&#x27;t reassign it to an entirely new value. You can, however, mutate the value it&#x27;s pointing to – you can change characters in a string, or fields in an object like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const michael = { name: &amp;quot;Michael&amp;quot;, age: 34 };

&amp;#x2F;&amp;#x2F; it&amp;#x27;s my birthday!
michael.age = 35;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;what-s-the-difference-between-let-and-var&quot;&gt;What&#x27;s the difference between &lt;code&gt;let&lt;&#x2F;code&gt; and &lt;code&gt;var&lt;&#x2F;code&gt;?&lt;&#x2F;h3&gt;
&lt;p&gt;If both &lt;code&gt;let&lt;&#x2F;code&gt; and &lt;code&gt;var&lt;&#x2F;code&gt; can be changed, why create a whole new binding type? The difference between them is that &lt;code&gt;let&lt;&#x2F;code&gt; doesn&#x27;t cause the variable to be &lt;em&gt;hoisted&lt;&#x2F;em&gt;. What&#x27;s hoisting?&lt;&#x2F;p&gt;
&lt;p&gt;In most programming languages, if you declare a variable in the middle of a scope then you can access that variable only later in the scope. If this were another language, this would throw an error about &lt;code&gt;message&lt;&#x2F;code&gt; not being defined:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;console.log(message);
var message = &amp;quot;Hello world!&amp;quot;;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But Javascript is different; that snippet won&#x27;t throw an error. What do you think that will print?&lt;&#x2F;p&gt;
&lt;p&gt;The answer is that it will print the value &lt;code&gt;undefined&lt;&#x2F;code&gt;. On the first line, &lt;code&gt;message&lt;&#x2F;code&gt; exists as a variable in that scope even though it&#x27;s before the &lt;code&gt;var&lt;&#x2F;code&gt; statement. It just has the value &lt;code&gt;undefined&lt;&#x2F;code&gt;. Why does it exist? Because the &lt;code&gt;var&lt;&#x2F;code&gt; binding &lt;em&gt;hoisted&lt;&#x2F;em&gt; the variable to the top of the scope as if it were declared at the very top of the scope. Then the &lt;code&gt;var&lt;&#x2F;code&gt; statement itself just assigns it the value &lt;code&gt;&amp;quot;Hello world&amp;quot;&lt;&#x2F;code&gt;. It exactly the same as if you wrote this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;var message = undefined;
console.log(message);
message = &amp;#x27;Hello world!&amp;#x27;;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But this doesn&#x27;t happen with either &lt;code&gt;let&lt;&#x2F;code&gt; or &lt;code&gt;const&lt;&#x2F;code&gt;. You can only reference one of these bindings after they are declared. So &lt;code&gt;let&lt;&#x2F;code&gt; is like &lt;code&gt;var&lt;&#x2F;code&gt; except that it&#x27;s not hoisted.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;strong&gt;tl;dr&lt;&#x2F;strong&gt; My recommendation is that there&#x27;s no reason to use &lt;code&gt;var&lt;&#x2F;code&gt; anymore. You should also prefer to use &lt;code&gt;const&lt;&#x2F;code&gt; unless you actually need to reassign a variable.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;array-and-object-matching-destructuring&quot;&gt;Array and object matching (destructuring)&lt;&#x2F;h2&gt;
&lt;p&gt;The next two features – destructuring, and object shorthand – are probably the new features I use the most.&lt;&#x2F;p&gt;
&lt;p&gt;Destructuring is a syntax for declaring local variables and assigning them to fields from an object. It&#x27;s best explained with an example:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const michael = { name: &amp;quot;Michael&amp;quot;, age: 34 };
const { name } = michael; &amp;#x2F;&amp;#x2F; (1)
console.log(name); &amp;#x2F;&amp;#x2F; prints &amp;#x27;Michael&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The second line there, marked &lt;code&gt;(1)&lt;&#x2F;code&gt;, &lt;em&gt;destructures&lt;&#x2F;em&gt; the &lt;code&gt;michael&lt;&#x2F;code&gt; variable, creating a variable &lt;code&gt;name&lt;&#x2F;code&gt; initialized to &lt;code&gt;michael.name&lt;&#x2F;code&gt;. It means the same thing as this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const name = michael.name;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;So far this seems not too useful. But you can do this for multiple fields at the same time:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const { name, age } = michael;
console.log(name, &amp;#x27;is&amp;#x27;, age, &amp;#x27;years old&amp;#x27;); &amp;#x2F;&amp;#x2F; print &amp;#x27;Michael is 34 years old&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;You can also do this on function parameters:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;function printBirthday({name, age}) {
  console.log(name, &amp;#x27;is&amp;#x27;, age, &amp;#x27;years old&amp;#x27;);
}
printBirthday(michael); &amp;#x2F;&amp;#x2F; prints &amp;#x27;Michael is 34 years old&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;The other feature of destructuring is that you can also use the &lt;em&gt;spread operator&lt;&#x2F;em&gt; (&lt;code&gt;...&lt;&#x2F;code&gt;) to create an object with all the remaining fields in the object that you haven&#x27;t mentioned:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;function printBirthday({name, age, ...rest}) {
  console.log(name, &amp;#x27;is&amp;#x27;, age, &amp;#x27;years old&amp;#x27;);
  console.log(&amp;quot;Here&amp;#x27;s some more things about them:&amp;quot;, rest);
}

const michael = { name: &amp;quot;Michael&amp;quot;, age: 34, city: &amp;quot;Ottawa&amp;quot; };
printBirthday(michael); &amp;#x2F;&amp;#x2F; prints &amp;quot;Michael is 34 years old&amp;quot; and &amp;quot;Here&amp;#x27;s some more things about them: { city: &amp;#x27;Ottawa&amp;#x27; }&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Notice that it only showed the &lt;code&gt;city&lt;&#x2F;code&gt; field, because that was the only field in the input object other than the &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;age&lt;&#x2F;code&gt; that were pulled out specifically.&lt;&#x2F;p&gt;
&lt;p&gt;Destructuring is one of those features that when it&#x27;s described like this it sounds kind of interesting. But once you start using it, it becomes a natural way of working with object values and you use it all the time.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;shorthands-for-creating-objects&quot;&gt;Shorthands for creating objects&lt;&#x2F;h2&gt;
&lt;p&gt;If destructuring is for taking apart objects, the flip side is the shorthand for putting them together. The first is a notation for creating fields bound to local variables:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const name = &amp;quot;Michael&amp;quot;;
const age = 34;
const michael = { name, age }; &amp;#x2F;&amp;#x2F; (1)
console.log(michael.name, &amp;#x27;is&amp;#x27;, michael.age, &amp;#x27;years old&amp;#x27;);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On the line marked &lt;code&gt;(1)&lt;&#x2F;code&gt;, it creates an object with two fields, &lt;code&gt;name&lt;&#x2F;code&gt; and &lt;code&gt;age&lt;&#x2F;code&gt;, and assigns them to the values from &lt;em&gt;variables of the same name&lt;&#x2F;em&gt;. It&#x27;s the same thing as writing this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const michael = { name: name, age: age };
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That&#x27;s nifty and convenient and avoids extra noise giving the same name twice if the variables are the same name. I often use it to build up return objects like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;function someFunction() {
  const one = &amp;quot;first value&amp;quot;;
  const two = &amp;quot;second value&amp;quot;;
  return { one, two };
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This lets you deal with each field separately, then the return line just packages them up together into an object with the right shape.&lt;&#x2F;p&gt;
&lt;p&gt;You can also use the spread operator we saw earlier when creating objects. This copies &lt;em&gt;all&lt;&#x2F;em&gt; the fields from one object into the new object. One place I use this a lot is when creating objects in test cases, where you have some fields that are required and some are specific to the test.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&amp;#x2F;&amp;#x2F; at the top of the file
const defaultPerson = { name: &amp;quot;Michael&amp;quot;, age: 34 };

&amp;#x2F;&amp;#x2F; the test function
it(&amp;#x27;people are adults when they turn 18&amp;#x27;, () =&amp;gt; {
  const person = { ...defaultPerson, age: 18 }; &amp;#x2F;&amp;#x2F; (1)
  expect(isAdult(person)).toEqual(true);
});
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On the line marked &lt;code&gt;(1)&lt;&#x2F;code&gt;, we create a new person that&#x27;s like the default one except that it has a different &lt;code&gt;age&lt;&#x2F;code&gt;. Any other fields, like the &lt;code&gt;name: &amp;quot;Michael&amp;quot;&lt;&#x2F;code&gt; field here, will have the value from &lt;code&gt;defaultPerson&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;If you want you can spread in multiple objects. That&#x27;s perfectly okay – it&#x27;ll just do any of the assignments in order:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const person = {
  ...defaultPerson,
  age: 18,
  ...overrides
};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this case it will copy the fields from &lt;code&gt;defaultPerson&lt;&#x2F;code&gt;, then assign &lt;code&gt;age&lt;&#x2F;code&gt; to be &lt;code&gt;18&lt;&#x2F;code&gt;, then copy all the fields from &lt;code&gt;overrides&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;arrow-functions&quot;&gt;Arrow functions&lt;&#x2F;h2&gt;
&lt;p&gt;It&#x27;s always been possible to write simple anonymous functions in Javascript and people have used this to write callbacks, for example. But one of the awkward things about Javascript is that when you do this, the &lt;code&gt;this&lt;&#x2F;code&gt; variable is special. Its value isn&#x27;t passed as part of the closure (the variables captured from the scope where a function is defined), but rather is set when the function is &lt;em&gt;called.&lt;&#x2F;em&gt;&lt;&#x2F;p&gt;
&lt;p&gt;(The technical term for this is that &lt;code&gt;this&lt;&#x2F;code&gt; is &lt;em&gt;dynamically scoped&lt;&#x2F;em&gt; but everywhere else in Javascript things are &lt;em&gt;lexically scoped&lt;&#x2F;em&gt;.)&lt;&#x2F;p&gt;
&lt;p&gt;This difference led to lots of confusion and hacks where you&#x27;d have to write &lt;code&gt;myFunction.bind(this)&lt;&#x2F;code&gt; to create a new version of the function where &lt;code&gt;this&lt;&#x2F;code&gt; had a particular value no matter who calls it.&lt;&#x2F;p&gt;
&lt;p&gt;The solution to this was to create a new way of writing inline functions, usually called &amp;quot;arrow functions&amp;quot; because of the &lt;code&gt;=&amp;gt;&lt;&#x2F;code&gt; operator you use to define them. They look like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const printBirthday = ({name, age}) =&amp;gt; {
  console.log(name, &amp;#x27;is&amp;#x27;, age, &amp;#x27;years old&amp;#x27;);
};

printBirthday(michael); &amp;#x2F;&amp;#x2F; prints &amp;#x27;Michael is 34 years old&amp;#x27;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This does the same thing as an example earlier in the section on destructuring. It creates an arrow function, then assigns it to a variable &lt;code&gt;printBirthday&lt;&#x2F;code&gt; which can then be called just like any function. If you use it inside a class, then the function will have the &lt;code&gt;this&lt;&#x2F;code&gt; value you expect.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;promises-and-async-await&quot;&gt;Promises and &lt;code&gt;async&lt;&#x2F;code&gt; &#x2F; &lt;code&gt;await&lt;&#x2F;code&gt;&lt;&#x2F;h2&gt;
&lt;p&gt;I&#x27;m saving the best for last here because Promises, and the &lt;code&gt;async&lt;&#x2F;code&gt; and &lt;code&gt;await&lt;&#x2F;code&gt; syntax that came with them, are probably the single most significant change in Javascript. But first I have to go back a bit and talk about how the Javascript runtime works.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;aside-how-the-javascript-runtime-works&quot;&gt;Aside: How the Javascript runtime works.&lt;&#x2F;h3&gt;
&lt;p&gt;Javascript runs in a single threaded environment. It can only be running one line of code at a time – anything else needs to wait. There&#x27;s no way for a web page to be running two pieces of Javascript code at the same time.&lt;&#x2F;p&gt;
&lt;p&gt;(For the pedantic readers: I&#x27;m ignoring WebWorkers here, which is a whole other topic that you can read about if you&#x27;re interested.)&lt;&#x2F;p&gt;
&lt;p&gt;This has the great benefit of avoiding all the problems that you run into when you have a multithreaded environment – where two processors might be running different code in the same memory at the same time – meaning your code can be much simpler and easier to reason about. But the drawback is that if you want to stay responsive you can never block the main thread for more than a few milliseconds. Web browsers want to run at 60 frames per second, which gives you 16 milliseconds (1000 &#x2F; 16) to work before you start delaying the next frame. If this happens then the interface will start to feel unresponsive or &amp;quot;janky&amp;quot;.&lt;&#x2F;p&gt;
&lt;p&gt;To make it &lt;em&gt;appear&lt;&#x2F;em&gt; like we can do more than one thing, we have to interleave pieces of work – instead of waiting, we need to be able to give up the processor to let something else run. You can see this interleaving if you open the &amp;quot;Performance&amp;quot; tab in your browser&#x27;s development tools. If you click around a page you&#x27;ll see something like this:
&lt;img src=&quot;&#x2F;content&#x2F;images&#x2F;2019&#x2F;11&#x2F;Screen-Shot-2019-11-20-at-4.52.23-PM.png&quot; alt=&quot;&quot; &#x2F;&gt;
See how the top bar is sliced up with many different bars? These are pieces of work being scheduled on the main thread. This interleaving is done with *event handlers – *callback functions that get invoked when interesting events happen. If you want to know when a button gets clicked, you can set a click handler.&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;html&quot; class=&quot;language-html &quot;&gt;&lt;code class=&quot;language-html&quot; data-lang=&quot;html&quot;&gt;&amp;lt;!-- in your HTML --&amp;gt;
&amp;lt;div&amp;gt;
    &amp;lt;button onClick={onButtonClicked}&amp;gt;Click me&amp;lt;&amp;#x2F;button&amp;gt;
&amp;lt;&amp;#x2F;div&amp;gt;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;&amp;#x2F;&amp;#x2F; in your Javascript
function onButtonClicked() {
    console.log(&amp;quot;You clicked the button!&amp;quot;);
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This means that you don&#x27;t need to write some loop to like &lt;code&gt;while (!button.clicked()) { ... }&lt;&#x2F;code&gt; to wait for a click. You can set the handler, then give up the processor for other work. If a click happens, the browser knows how to let you know so you can respond to it.&lt;&#x2F;p&gt;
&lt;p&gt;The same is true for network requests, by the way. When you make a request, it may take a long time (up to a few seconds) for a result to come back. Rather than waiting for a response, you can set an event handler on the request to say &amp;quot;call this function when a result comes back&amp;quot;. Then you can give up the main thread so other work can happen.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;callback-hell&quot;&gt;Callback hell&lt;&#x2F;h3&gt;
&lt;p&gt;This all works great for simple cases. The problem is what happens when you start building larger applications. Sometimes you want to build code that does a sequence of steps. You want to do something, then wait for an event, then do another thing. You also need error handlers for lots of asynchronous operations.&lt;&#x2F;p&gt;
&lt;p&gt;Very quickly, you end up with very deeply nested code that looks like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;doOneThing(function() {
  doSecondThing(function() {
    console.log(&amp;quot;All done!&amp;quot;);
  }, function() {
    console.log(&amp;quot;An error happened on the second thing!&amp;quot;);
  });
}, function() {
  console.log(&amp;quot;An error happened on the first thing!&amp;quot;);
});
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Imagine this being several layers deep. It becomes an unmanageable, tangled mess of callback functions. People called this &amp;quot;callback hell&amp;quot;.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;how-promises-work&quot;&gt;How promises work&lt;&#x2F;h3&gt;
&lt;p&gt;Promises help with callback hell by giving you a way of representing some work you want to happen in the future once a value is available.&lt;&#x2F;p&gt;
&lt;p&gt;A promise is just a Javascript object that you can call &lt;code&gt;.then(...)&lt;&#x2F;code&gt; on giving it a function. It will call that function when the promise is &lt;em&gt;resolved&lt;&#x2F;em&gt; if the work completes successfully. You can also call &lt;code&gt;.catch(...)&lt;&#x2F;code&gt; on it to give it a function you want called if the promise is &lt;em&gt;rejected&lt;&#x2F;em&gt; because the work failed.&lt;&#x2F;p&gt;
&lt;p&gt;Both of these functions – &lt;code&gt;then&lt;&#x2F;code&gt; and &lt;code&gt;catch&lt;&#x2F;code&gt; – each return promises themselves. This means that they can be chained:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;fetch(&amp;#x27;&amp;#x2F;products.json&amp;#x27;)
  .then(({products}) =&amp;gt; console.log(&amp;quot;These are the products in your store:&amp;quot;, products))
  .then(() =&amp;gt; console.log(&amp;quot;All done!&amp;quot;))
  .catch((error) =&amp;gt; console.log(&amp;quot;An error occurred:&amp;quot;, error));
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This lets you flatten out what would be nested nested callbacks into a sequence of steps. It&#x27;s also composable – you can combine together promises in a natural sort of way. Let&#x27;s say we wanted to hide the error handling logic in the &lt;code&gt;catch&lt;&#x2F;code&gt; step. You could do this by writing a new function that will fetch the products, and also handles errors if it fails:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;function fetchProducts() {
  return fetch(&amp;#x27;&amp;#x2F;products.json&amp;#x27;)
    .then((result) =&amp;gt; { console.log(&amp;quot;All done!&amp;quot;); return result; })
    .catch((error) =&amp;gt; console.log(&amp;quot;An error occurred fetching the products:&amp;quot;, error));
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This function returns a promise that resolves once the fetch occurs – and it also prints a message and handles the error. Now someone can call it and chain on their own work to use the products that were just fetched:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;fetchProducts()
  .then(({products}) =&amp;gt; console.log(&amp;quot;These are the products in your store:&amp;quot;, products));
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Being able to create higher level operations like this is one of the most powerful parts of promises. It was very hard to do with just callbacks.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;async-and-await&quot;&gt;&lt;code&gt;async&lt;&#x2F;code&gt; and &lt;code&gt;await&lt;&#x2F;code&gt;&lt;&#x2F;h3&gt;
&lt;p&gt;As great as promises are all by themselves, writing the list of &lt;code&gt;then&lt;&#x2F;code&gt; and &lt;code&gt;catch&lt;&#x2F;code&gt; clauses is still awkward and hard to read, especially if you need to do loops. You need to be sure that you chain promises together properly and never leave them &#x27;dangling&#x27;. The next step was to add syntax to Javascript to make promises a core part of the language so asynchronous code is easier to write and reads more like synchronous code.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;async&lt;&#x2F;code&gt; and &lt;code&gt;await&lt;&#x2F;code&gt; keywords work together. You put &lt;code&gt;async&lt;&#x2F;code&gt; on a function where you want to use &lt;code&gt;await&lt;&#x2F;code&gt;. Inside an &lt;code&gt;async&lt;&#x2F;code&gt; function, you can use &lt;code&gt;await&lt;&#x2F;code&gt; to essentially wrap everything after that line in a &lt;code&gt;then&lt;&#x2F;code&gt; clause. You can also use a &lt;code&gt;try&lt;&#x2F;code&gt;&#x2F;&lt;code&gt;catch&lt;&#x2F;code&gt; block to catch rejected promises the same way as any other exception in Javascript.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s rewrite the &lt;code&gt;fetchProducts&lt;&#x2F;code&gt; function above again to use this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;async function fetchProducts() {
  try {
    const result = await fetch(&amp;#x27;&amp;#x2F;products.json&amp;#x27;);
    console.log(&amp;quot;All done!&amp;quot;);
    return result;
  } catch(error) {
    console.log(&amp;quot;An error occurred fetching the products:&amp;quot;, error);
  }
}
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then you can use it like this:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;js&quot; class=&quot;language-js &quot;&gt;&lt;code class=&quot;language-js&quot; data-lang=&quot;js&quot;&gt;const {products} = await fetchProducts();
console.log(&amp;quot;These are the products in your store:&amp;quot;, products);
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In this way you can almost pretend that you&#x27;re writing regular code and forget that it will run asynchronously. But it will. This code won&#x27;t actually &lt;em&gt;wait&lt;&#x2F;em&gt; for the result to come back. It will break and give up the processor and let other things use the processor. Then, when a result eventually comes back from the server (or an error occurs) your code will pick up where it left off.&lt;&#x2F;p&gt;
&lt;p&gt;The &lt;code&gt;await&lt;&#x2F;code&gt; statement works properly even in the case of loops, &lt;code&gt;if&lt;&#x2F;code&gt; conditions, and so on.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;more-reading&quot;&gt;More reading&lt;&#x2F;h2&gt;
&lt;p&gt;I hope this article was helpful to you!&lt;&#x2F;p&gt;
&lt;p&gt;I certainly haven&#x27;t covered all the new features in Javascript. This is just a few I think are the most important but there&#x27;s more, including classes, the module system, template variables, and many more! If you want to learn more about them I suggest going to &lt;a href=&quot;https:&#x2F;&#x2F;es6-features.org&#x2F;&quot;&gt;es6-features.org&lt;&#x2F;a&gt; where you&#x27;ll find a list of all the features.&lt;&#x2F;p&gt;
&lt;p&gt;If you want more details about any of the jargon terms I&#x27;ve used in this article, I suggest googling for &lt;code&gt;mdn &amp;lt;term&amp;gt;&lt;&#x2F;code&gt;. This will point you to the Mozilla Developer Network&#x27;s documentation, which is a great resource that has all the details about every part of Javascript.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Running on the treadmill</title>
		<published>2017-10-03T02:44:00+00:00</published>
		<updated>2019-01-05T06:45:42+00:00</updated>
		<link href="https://michaelmelanson.net/posts/running-on-the-treadmill/" type="text/html"/>
		<id>https://michaelmelanson.net/posts/running-on-the-treadmill/</id>
		<content type="html">&lt;p&gt;If there’s one thing that’s always true about software development, it’s that it just never sits still. Just when you think you’re on top of things, a new framework comes along and suddenly you feel out-of-date and you’re worried all the cool kids will laugh at you.&lt;&#x2F;p&gt;
&lt;p&gt;But there’s some bits of evergreen advice I can give.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;knowing-vs-knowing&quot;&gt;Knowing vs. knowing&lt;&#x2F;h4&gt;
&lt;p&gt;No one knows everything. No one is an expert on every single Javascript library out there. Most of them are crap anyway.&lt;&#x2F;p&gt;
&lt;p&gt;Realize that there&#x27;s many levels of ‘knowing’ something –&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Awareness:&lt;&#x2F;em&gt; “I’ve heard the word before.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Familiarity:&lt;&#x2F;em&gt; “I’ve read some stuff and know the general idea behind it.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Tinkerer:&lt;&#x2F;em&gt; “I’ve played around with it or made something small.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Experienced:&lt;&#x2F;em&gt; “I’ve shipped a real product that uses it.”&lt;&#x2F;li&gt;
&lt;li&gt;&lt;em&gt;Expert:&lt;&#x2F;em&gt; “I know it inside and out and can make it do things the author never intended.”&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;What do you mean when you say you &#x27;know&#x27; something? Are you sure that&#x27;s what other people mean? Set unrealistic expectations about how many things you can be an &lt;em&gt;expert&lt;&#x2F;em&gt; on.&lt;&#x2F;p&gt;
&lt;p&gt;One thing? You’re doing well.&lt;&#x2F;p&gt;
&lt;p&gt;And you can say you ‘know’ something long before you work your way through all of them and definitely when you’re &lt;em&gt;experienced&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You might imagine that if someone else says they ‘know’ something that they’re an &lt;em&gt;expert&lt;&#x2F;em&gt;, but then you look at your own skill set and think “I still have to check the docs every five minutes and Stack Overflow several times a day”. We all do. That’s okay.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;tick-tock&quot;&gt;Tick tock.&lt;&#x2F;h4&gt;
&lt;p&gt;If you squint a bit, new developments follow a metronome pattern.&lt;&#x2F;p&gt;
&lt;p&gt;There’s a &lt;em&gt;tick&lt;&#x2F;em&gt; phase where people have a new problem of some kind. They solve it by adding or replacing a thing in their system’s tech stack. Then there’s a &lt;em&gt;tock&lt;&#x2F;em&gt; phase where people look at that solution and try to do the same thing only better: merge two things together, make it faster, give it a better developer experience, more repeatable, whatever.&lt;&#x2F;p&gt;
&lt;p&gt;It’s okay to ignore the &lt;em&gt;tick&lt;&#x2F;em&gt; phase altogether. When you start a new system, start at the last &lt;em&gt;tock&lt;&#x2F;em&gt; and skip from there to the next &lt;em&gt;tock&lt;&#x2F;em&gt; when it comes along. Usually at that point there’s usually a clear advantage to moving from one &lt;em&gt;tock&lt;&#x2F;em&gt; to the next. You don’t have to stay on the bleeding edge.&lt;&#x2F;p&gt;
&lt;p&gt;But even then make sure it makes sense &lt;em&gt;for you and your customers&lt;&#x2F;em&gt; compared to everything else you could be spending time working on.&lt;&#x2F;p&gt;
&lt;p&gt;It’s rarely necessary to use a &lt;em&gt;tick&lt;&#x2F;em&gt; technology unless it’s a specific competitive advantage for you. You might want to anyway if that’s fun for you, but you don’t have to.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;mind-the-mess&quot;&gt;Mind the mess.&lt;&#x2F;h4&gt;
&lt;p&gt;Don’t let ideologues fool you. Building software in the real world is never as neat and tidy as we’d like. Real software always has dust bunnies under the couches.&lt;&#x2F;p&gt;
&lt;p&gt;When you decide to adopt a new technology, you do not have to adopt it 100%. Invest in it where it makes sense to, leave things as-is when there’s no reason to change it.&lt;&#x2F;p&gt;
&lt;p&gt;Are you using fancy newfangled client-rendered React but there’s some dusty corner of your system where things are plugging along with server-rendered JSP templates? Relax, don’t worry about it.&lt;&#x2F;p&gt;
&lt;p&gt;If you have to come back to that dusty corner, perhaps because it’s producing bugs or because you need to modify it for some new work, then think about updating it then. But if it’s quietly doing its thing? Let it be, focus on more important things.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;code-is-code&quot;&gt;Code is code.&lt;&#x2F;h4&gt;
&lt;p&gt;Never forget that no matter what framework you’re using, how it’s built, or how it’s delivered to your users, the same fundamentals apply. It’s all just code.&lt;&#x2F;p&gt;
&lt;p&gt;Optimize for being able to come back later, understand the code easily, and change it without breaking other stuff.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;look-out-for-each-other&quot;&gt;Look out for each other.&lt;&#x2F;h4&gt;
&lt;p&gt;Do you feel like you can never keep up-to-date with all the new stuff? Being a software developer can feel like you’re always on a treadmill going just a bit too fast. You’re always worried you’re one misstep away from face-planting.&lt;&#x2F;p&gt;
&lt;p&gt;Take a breath. If you’re even reading posts like this one and thinking these thoughts, you’re already doing plenty. Do a good day’s work, leave your code in a better place than it was yesterday, &lt;em&gt;then go home&lt;&#x2F;em&gt;. Spend time with your family and friends, read a book, do some Judo 🥋. Whatever helps give you perspective about how insane our industry can be.&lt;&#x2F;p&gt;
&lt;p&gt;Most importantly, realize that everyone else around you feels insecure about this too. Be kind and helpful to each other as we all muddle through this together.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Transactions: the limits of isolation</title>
		<published>2014-12-01T02:37:00+00:00</published>
		<updated>2019-01-05T03:15:26+00:00</updated>
		<link href="https://michaelmelanson.net/posts/transactions-the-limits-of-isolation/" type="text/html"/>
		<id>https://michaelmelanson.net/posts/transactions-the-limits-of-isolation/</id>
		<content type="html">&lt;p&gt;At Toushay, one of our major feature was &#x27;digital signage&#x27; — lists of images and videos we&#x27;d display on the screens of tables. We ran into a tricky issue: our customers were noticing that, very rarely, these digital signage playlists were being subtly corrupted. After our customers had been moving items around in the list, things would go awry. Sometimes an image would be lost, other times one would be duplicated. It happened only a few times, and in each case we were able to manually correct it. But it was very painful – and trust-breaking – for them when it did.&lt;&#x2F;p&gt;
&lt;p&gt;Clearly something was wrong with how we were handling this data.&lt;&#x2F;p&gt;
&lt;p&gt;The problem was that it wasn’t reproducible on a developer’s machine, it didn’t show up in our integration tests, and occurred only very rarely in production.&lt;&#x2F;p&gt;
&lt;p&gt;I was tasked with figuring out the source of the problem and solving it once and for all. At first, everything worked okay on my machine and I couldn’t reproduce it. On a hunch that it may only occur on a database under high load, I tried hammering my local database with as much load as I could manage with this command:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;mysqlslap -a --auto-generate-sql-execute-number=10000 --concurrency 140
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;That command spins up 140 MySQL clients, and each one hits the database with 10,000 random queries as fast as they can. That keeps the server busy for several minutes with much higher load than our production servers will ever see.&lt;&#x2F;p&gt;
&lt;p&gt;With that command running, I was able to reproduce the problem fairly consistently: duplicated images, missing images, the whole bit. Clearly, the extra database load was causing the different requests to step on each other’s toes. But how?&lt;&#x2F;p&gt;
&lt;p&gt;The code to move an item in the list basically works like this:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;Read in the list of images.&lt;&#x2F;li&gt;
&lt;li&gt;Check that the item we’re moving is in the list and at the position we expect. This is a sanity check to ensure the UI isn’t running on stale data.&lt;&#x2F;li&gt;
&lt;li&gt;Move the item to the new position.&lt;&#x2F;li&gt;
&lt;li&gt;Save the list to the database.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;This block of code is run within a database transaction (I checked to be sure), which should isolate it from other transactions. Yet, the behaviour could only be caused by two requests colliding with each other something like this:&lt;&#x2F;p&gt;
&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;strong&gt;Request A&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;th&gt;&lt;strong&gt;Request B&lt;&#x2F;strong&gt;&lt;&#x2F;th&gt;&lt;&#x2F;tr&gt;&lt;&#x2F;thead&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Read in the list of images.&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Check that the item we’re moving is in the list and at the position we expect.&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Read in the list of images.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Check that the item we’re moving is in the list and at the position we expect.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Move the item.&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;Save the list to the database.&lt;&#x2F;td&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Move the item.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;&#x2F;td&gt;&lt;td&gt;Save the list to the database.&lt;&#x2F;td&gt;&lt;&#x2F;tr&gt;
&lt;&#x2F;tbody&gt;&lt;&#x2F;table&gt;
&lt;p&gt;But how can this be? Transactions are one of the key features of any relational data store and, as we all learned in school, transactions provide ACID guarantees. Shouldn’t the Isolation guarantee prevent two transactions from interfering with each other like that?&lt;&#x2F;p&gt;
&lt;p&gt;By digging deeper, I realized what was going on. One key fact that is not well known about transactions, or is easily forgotten, is this: by default, databases do not provide full Isolation guarantees.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;how-isolated-is-isolated&quot;&gt;How isolated is isolated?&lt;&#x2F;h4&gt;
&lt;p&gt;What exactly the Isolation guarantee in the SQL standard means based on what they call “read phenomena”. There are three types of phenomena:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Dirty reads&lt;&#x2F;strong&gt; – If another transaction writes, but does not commit, during your transaction, is it possible that you will see their data?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Non-repeatable reads&lt;&#x2F;strong&gt; – If you read the same row twice, is it possible that you might get different data the second time?&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Phantom reads&lt;&#x2F;strong&gt; – If you read a collection of rows twice, is it possible that different rows will be returned the second time?&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;In the SQL standard, there are four levels of transactional isolation based on which of these phenomena they prevent (from weakest to strongest):&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Read Uncommitted&lt;&#x2F;strong&gt; – A transaction can see the results of another transaction’s &lt;code&gt;INSERT&lt;&#x2F;code&gt; or &lt;code&gt;UPDATE&lt;&#x2F;code&gt; queries before they are committed. This allows all read phenomena.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Read Committed&lt;&#x2F;strong&gt; – A transaction is guaranteed to only see rows that are committed. This prevents &lt;em&gt;dirty reads&lt;&#x2F;em&gt; but allows the other phenomena.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Repeatable Read&lt;&#x2F;strong&gt; – A transaction is gets a snapshot of all rows it reads during the transaction. This prevents &lt;em&gt;dirty reads&lt;&#x2F;em&gt; and &lt;em&gt;non-repeatable reads&lt;&#x2F;em&gt;, but allows &lt;em&gt;phantom reads&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;strong&gt;Serializable&lt;&#x2F;strong&gt; – A transaction gets a “range lock” any time it queries a collection of rows, guaranteeing that it sees a snapshot of that data. This prevents &lt;em&gt;phantom reads&lt;&#x2F;em&gt; as well as &lt;em&gt;dirty reads&lt;&#x2F;em&gt; and &lt;em&gt;non-repeatable reads&lt;&#x2F;em&gt;.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;The default isolation level, at least for PostgreSQL, MySQL and Oracle, is Read Committed and so that’s what we were using in our application. You probably are in your application to, unless you’ve specifically changed the isolation level. If that’s the case, you can’t assume that because you read in some data that someone can’t change it underneath you before you commit.&lt;&#x2F;p&gt;
&lt;p&gt;The reason they don’t use a higher default level is that both Repeatable Read and Serializable both introduce cases where a transaction cannot be completed and must be aborted (race conditions). In these cases, the DBMS aborts the transaction, rolls it back, and returns an error.&lt;&#x2F;p&gt;
&lt;p&gt;When this happens, the application has to know how to retry the transaction. In some cases it may be difficult to retry a transaction if it had side effects on the application’s side: talking to external services or other data stores. In these cases, the application would have to use something like a &lt;a href=&quot;https:&#x2F;&#x2F;en.wikipedia.org&#x2F;wiki&#x2F;Two-phase_commit_protocol&quot;&gt;two-phase commit protocol&lt;&#x2F;a&gt;, or else manually roll back the side effects.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;the-solution&quot;&gt;The solution&lt;&#x2F;h4&gt;
&lt;p&gt;The corruption we were seeing was the result of non-repeatable reads and phantom reads: we were reading a range of images, doing some checks on them, then modifying that range and writing them out. In between the reads and writes, there’s a window where another transaction could sneak in and insert or remove an image, or rearrange the list. Any of those cases could cause corruption of the list when you make your changes and overwrite the new changes.&lt;&#x2F;p&gt;
&lt;p&gt;There are two solutions to this: either you use row locks (probably a shared lock, but possibly exclusive) to prevent any concurrent access to the rows, or you use stricter transaction isolation. In our case, we need Serializable isolation to prevent the phenomena we were seeing.&lt;&#x2F;p&gt;
&lt;p&gt;The problem with both of these is that you take a performance hit. We checked what impact enabling Serializable isolation globally (by setting the MySQL server variable &lt;code&gt;tx_isolation = SERIALIZABLE&lt;&#x2F;code&gt;) would have, and the results were… mixed. In some cases, the effect was negligible; in other cases, it raised the response time by up to 10x. And in all cases, it made the response time much more variable. So switching to Serializable everywhere was a no-go.&lt;&#x2F;p&gt;
&lt;p&gt;We also didn’t want to use row locks: it’s easy to miss a case where a lock is necessary, and need to be used properly to prevent deadlocks. They’re also often stricter than we need, which may incur a greater performance hit than is necessary.&lt;&#x2F;p&gt;
&lt;p&gt;In the end, we switched to Serializable isolation on the particular operations where the stricter isolation is necessary. In all the rest, we continue to use the default Read Committed isolation.&lt;&#x2F;p&gt;
&lt;h4 id=&quot;lessons-learned&quot;&gt;Lessons learned&lt;&#x2F;h4&gt;
&lt;p&gt;This was a very subtle and interesting bug. It came about from a fairly serious misunderstanding of how transactions work. But it’s an easy one to make: it’s natural to think of transactions as some sort of magic that protects you from concurrency issues. Going into this, my own mental model was that transactions gave something like Serializable isolation by default. I’m sure I’m not alone there, which is why I wrote this blog post.&lt;&#x2F;p&gt;
&lt;p&gt;Here the key lesson you can take away from this: be sure to understand your database’s documentation in detail. I got all the information in this post from the &lt;a href=&quot;http:&#x2F;&#x2F;dev.mysql.com&#x2F;doc&#x2F;refman&#x2F;5.7&#x2F;en&#x2F;set-transaction.html&quot;&gt;MySQL&lt;&#x2F;a&gt; and &lt;a href=&quot;http:&#x2F;&#x2F;www.postgresql.org&#x2F;docs&#x2F;9.1&#x2F;static&#x2F;transaction-iso.html&quot;&gt;PostgreSQL&lt;&#x2F;a&gt; documentation.&lt;&#x2F;p&gt;
&lt;p&gt;It also showed us that there’s a gap in our testing methodology: the tests are run on an unloaded database, and transaction isolation issues don’t appear until you have multiple competing transactions. When you’re doing integration testing, consider running &lt;code&gt;mysqlslap&lt;&#x2F;code&gt;, or similar, in the background. This should increase the chances that isolation problems will occasionally cause your tests to fail.&lt;&#x2F;p&gt;
</content>
	</entry>
	<entry xml:lang="en">
		<title>Using Git&#x27;s interactive rebase</title>
		<published>2013-06-17T02:24:00+00:00</published>
		<updated>2019-11-21T18:38:58+00:00</updated>
		<link href="https://michaelmelanson.net/posts/git-tip-using-interactive-rebase/" type="text/html"/>
		<id>https://michaelmelanson.net/posts/git-tip-using-interactive-rebase/</id>
		<content type="html">&lt;p&gt;Interactive rebase is a one-stop shop for revising history: combining, removing and reordering commits. It’s one of those things where you learn it, and afterwards wonder how you got by without knowing it. I use it almost every day when preparing a topic branch for review. If I have to make changes during review, I commit them as incremental patches, then squash them with an interactive rebase before I commit.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (June 2019):&lt;&#x2F;strong&gt; This article was originally written in 2013. You know how it feels to come back to something you did a long time ago and all you can do is see everything &lt;em&gt;wrong&lt;&#x2F;em&gt; with it? Well I just did that and, long story short, spent a while editing it and updating it so it doesn&#x27;t make me cringe quite as much. Cheers!&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;In this post, I’ll explain a bit about how it works. Let’s forget about topic branches right now, and just assume you’re working directly on the master.&lt;&#x2F;p&gt;
&lt;p&gt;Let&#x27;s say you’ve been working a bit on a new feature, and if you&#x27;re anything like me if you run &lt;code&gt;git log&lt;&#x2F;code&gt; you&#x27;ll find you&#x27;ve ended up with history that looks like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;master&lt;&#x2F;code&gt; Fix a bug when you foo the bar&lt;&#x2F;li&gt;
&lt;li&gt;Fix typo&lt;&#x2F;li&gt;
&lt;li&gt;Implement the remainder of feature XYZ&lt;&#x2F;li&gt;
&lt;li&gt;Oops, forgot to add this file&lt;&#x2F;li&gt;
&lt;li&gt;Implement part of feature XYZ&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;origin&#x2F;master&lt;&#x2F;code&gt;&lt;em&gt;(Other commits already pushed to the upstream repo)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;There&#x27;s five local commits here, but only two of them are actual commits. The rest are fixing errors or bugs in code that no one else has seen. Leaving them in the history would just clutter it up. It&#x27;s best for each commit to represent a complete bit of work so it&#x27;s easier to understand by reviewers now, and by other developers later if they have to go back into the history.&lt;&#x2F;p&gt;
&lt;p&gt;This is where &amp;quot;interactive rebase&amp;quot; comes in. It&#x27;s a tool in Git to let you edit the recent history in almost any way you could want. The best way to understand it is to actually use it. Since we’ve added five commits here, we start by running a rebase with the &lt;code&gt;-i&lt;&#x2F;code&gt; (&amp;quot;interactive&amp;quot;) flag:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;git rebase -i HEAD~5
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This will open up your editor – the same one you&#x27;d use to write a commit message – and at the top you&#x27;ll see something that looks like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;pick 39a2bef Implement part of feature XYZ
pick 4bc987e Oops, forgot to add this file
pick f9282bc Implement the remainder of feature XYZ
pick 2c5dd33 Fix typo
pick a524b5c Fix a bug when you foo the bar
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;On each line, you have the command (&lt;code&gt;pick&lt;&#x2F;code&gt; here), the commit ID, and the description. Below that, there&#x27;s some instructions about what&#x27;s going on including a list of commands you can use:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;pick&lt;&#x2F;code&gt; — leave the commit as-is&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;reword&lt;&#x2F;code&gt; — change the commit summary only (this is a recent addition)&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;edit&lt;&#x2F;code&gt; — change the commit contents, much like doing a &lt;code&gt;git reset --mixed&lt;&#x2F;code&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;squash&lt;&#x2F;code&gt; — keep the changes in this commit, but merge it with the commit on the previous line, and append the commit messages and allow the message to be edited.&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;fixup&lt;&#x2F;code&gt; — keep the changes, like with squash but throw away the commit message instead of appending them.&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;You can also delete a line to discard a commit entirely, or reorder them. The idea is that you edit this file so it shows the history you wish you created, then write the file and close your editor. Let’s change it so it looks like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;pick 39a2bef Implement part of feature XYZ
fixup 4bc987e Oops, forgot to add this file
pick f9282bc Implement the remainder of feature XYZ
fixup 2c5dd33 Fix typo
fixup a524b5c Fix a bug when you foo the bar
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;All I&#x27;ve done here is change the command “&lt;code&gt;pick&lt;&#x2F;code&gt;” to “&lt;code&gt;fixup&lt;&#x2F;code&gt;”  for all the mistake commits I made. This will roll them in with the  commits above them so that, when we close the editor, Git will rewrite the commit history so it looks like this:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;master&lt;&#x2F;code&gt; Implement the remainder of feature XYZ&lt;&#x2F;li&gt;
&lt;li&gt;Implement part of feature XYZ&lt;&#x2F;li&gt;
&lt;li&gt;&lt;code&gt;origin&#x2F;master&lt;&#x2F;code&gt;&lt;em&gt;(Other commits already pushed to the upstream repo)&lt;&#x2F;em&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;It&#x27;s important to understand here that all the changes from the commits are still there! They&#x27;ve just been incorporated into the previous commit. So, for example the changes in the &amp;quot;Oops, forgot to add this file&amp;quot; commit, presumably to add the missing file, is now part of the previous &amp;quot;Implement part of feature XYZ&amp;quot; commit where it belongs.&lt;&#x2F;p&gt;
&lt;p&gt;As I said, I use this almost daily to prepare a patch set for review. After I rebase, I prepare patch emails with &lt;code&gt;git format-patch -2 --attach&lt;&#x2F;code&gt;, then send them with &lt;code&gt;git send-email 000[12]* --to=mailinglist@somewhere.com&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Update (June 2019):&lt;&#x2F;strong&gt; I&#x27;m leaving that last paragraph in for posterity. I can&#x27;t believe that used to be my workflow! If I were writing this today I would have talked about posting a pull request with the changes.&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I hope that helps you out. Interactive Rebase is a very useful feature of Git that I haven’t seen in other source control systems. It can be a bit confusing at first but once you get the hang of it, it&#x27;s a very handy tool making the history clean and easy to understand for reviewers and for anyone who may look at the history later.&lt;&#x2F;p&gt;
</content>
	</entry>
</feed>
