The Holy Java

Building the right thing, building it right, fast

A Costly Failure to Design for Performance and Robustness

Posted by Jakub Holý on December 6, 2015

I have learned that it is costly to not prioritise expressing one’s design concerns and ideas early. As a result, we have a shopping cart that is noticeably slow, goes down whenever the backend experiences problems, and is a potential performance bottleneck. Let’s have a look at the problem, the actual and my ideal designs, and their pros and cons.

We have added shopping cart functionality to our web shop, using a backend service to provide most of the functionality and to hold the state. The design focus was on simplicity – the front-end is stateless, any change to the cart is sent to the backend and the current content of the cart is always fetched anew from it to avoid the complexity of maintaining and syncing state at two places. Even though the backend wasn’t design for the actual front-end needs, we work around it. The front-end doesn’t need to do much work and it is thus a success in this regard.

Read the rest of this entry »

Posted in SW development | Tagged: , , , | Comments Off on A Costly Failure to Design for Performance and Robustness

Why we practice fronted-first design (instead of API-first)

Posted by Jakub Holý on December 6, 2015

Cross-posted from the TeliaSonera tech blog

Alex has introduced us to the idea of front-end first design: You start by creating the front-end (browser) code. As you discover data or API calls that you need, you mock them. When the UI stabilizes, you use the mocked APIs and data to create the backend with exactly the functionality and exactly the data needed by the UI. The end result is a simpler application.

We are trying to adopt this as our approach because it is so sensible. Whenever we work with an API that wasn’t designed with the actual client needs in mind, we experience unnecessary friction and have to do various workarounds and adaptations so front-end-first absolutely makes sense to us. (E.g. when working with a REST API designed in line with REST principles – but not with our needs, resulting in a too chatty communication and more complex code.)

Of course there are same limitations. It is more challenging when you need to support different clients. And you need to take into account not just what the UI wants but also what is reasonably possible in the constraints of the existing system. You want to avoid a big gap between the two – we still remember the pain of integrating OOP and relational databases and the complexity of pitfalls of Object-Relational Mappers such as Hibernate, that try to bridge the two.

Conclusion

Fronted-first design rocks (for us). Try it too and see whether you too get a simpler application code and shorter time to market.

Posted in SW development | Tagged: , | Comments Off on Why we practice fronted-first design (instead of API-first)

Troubleshooting And Improving HTTPS/TLS Connection Performance

Posted by Jakub Holý on November 27, 2015

Our team has struggled with slow calls to the back-end, resulting in unpleasant, user-perceivable delays. While a direct (HTTP) call to a backend REST service took around 50ms, our median time was around 300ms (while using HTTPS and a proxy between us and the service).

We have just decreased that time to median of 80ms by making sure to keep the connections alive and reusing them, which in Node.js can be achieved via using an https.agent and setting its keepAlive: true (see the Node TLS documentation).

PayPal has a couple of additional useful tips in their 4/2014 post Outbound SSL Performance in Node.js, mainly:

  • Disable expensive SSL ciphers (if you don’t need their strength)
  • Enable SSL session resume, if supported by the server, for shorter handshakes – the StrongLoop post “How-to Improve Node.js HTTPS Server Performance” explains how to enable SSL session resume
  • Keep Alive

The article SSL handshake latency and HTTPS optimizations (via Victor Danell) explains the ± 3.5* higher cost of SSL due to the 3 roundtrips need for the handshake (+ key generation time) and shows how to use curl to time connections and their SSL parts, as well as how to use OpenSSL and Tcpdump to learn even more about it.

See also IsTlsFastYet.com for a lot of valuable information, benchmarks etc.

Tools

(See the articles linked to above for examples)

  • curl
  • openssl s_client
  • pathchar by the traceroute author, intended to help to “find the bandwidth, delay, average queue and loss rate of every hop between any source & destination”; there is also pchar, based on it

 

Posted in General | Tagged: , , | Comments Off on Troubleshooting And Improving HTTPS/TLS Connection Performance

Moving Too Fast For UX? Genuine Needs, Wrong Solutions

Posted by Jakub Holý on November 12, 2015

Cross-posted from the TeliaSonera tech blog

Our UX designer and interaction specialist – a wonderful guy – has shocked us today by telling us that we (the developers) are moving too fast. He needs more time to do proper user experience and interface design – talk to real users, collect feedback, design based on data, not just hypotheses and gut feeling. To do this, he needs us to slow down.

We see a common human “mistake” here: where the expression of a genuine need gets mixed in with a suggestion for satisfying it. We are happy to learn about the need and will do our best to satisfy it (after all, we want everybody to be happy, and we too love evidence-based design) but we want to challenge the proposed solution. There is never just one way to satisfy a need – and the first proposed solution is rarely the best one (not mentioning that this particular one goes against the needs of us, the developers).

Read the rest of this entry »

Posted in SW development | Tagged: , , | 1 Comment »

Upgrade or not to upgrade dependencies? The eternal dilemma

Posted by Jakub Holý on October 20, 2015

Cross-posted from TeliaSonera Tech blog.

Handling dependencies is one of important challenges in any software project – and especially in the fast-moving JavaScript world. Our Nettbutikk team just had a heated discussion about handling upgrades of our dependencies that continuous our learning journey lined with failures (or rather “experiments that generated new knowledge” :-)).

Failed attempt one: Let tools do it

Originally we let npm automatically do minor upgrades but that turned out to be problematic as even minor version changes can introduce bugs and having potentially different (minor) versions on our different machines and in production makes troubleshooting difficult.

Read the rest of this entry »

Posted in SW development | Tagged: , , | Comments Off on Upgrade or not to upgrade dependencies? The eternal dilemma

Storytelling as a Vehicle of Change: Introducing ClojureScript for the Heart and Mind

Posted by Jakub Holý on October 7, 2015

People don’t really like changes yet change we must in this fast-developing world. How to introduce a change, or rather how to inspire people to embrace a change? That is one of the main questions of my professional life.

I have recently talked about Functional programming (FP) in JavaScript and compared it to ClojureScript, which was designed for FP. To my surprise the team proposed to give ClojureScript a try and we agreed to have a live coding session, implementing a new functionality in our internal part of our webshop using ClojureScript. But how to kindle this little flame of motivation to keep it going, despite hurdles that will certainly come? And here I got a few interesting ideas.

  1. An experienced speaker once recommended sharing personal experiences (even – or especially – if they make me vulnerable) as it is much easier for people to relate to them than to general statements.
  2. A Cognicast eposide mentioned storytelling as a great tool for introductory guides. We humans are natural storytellers, we think in stories and relate to them much more easily – so a story should be great also to communicate the value of a change.
  3. My ex-colleague Therese Ingebrigtsen gave an inspiring talk presenting some points from The Switch – mainly that we need to address the recipient’s minds with rational arguments, but also their hearts to involve their emotion (e.g. by drawing a picture of the new bright future), and that it is important to show a clear path forward.

Read the rest of this entry »

Posted in General, Languages | Tagged: , , | Comments Off on Storytelling as a Vehicle of Change: Introducing ClojureScript for the Heart and Mind

An answer to CircleCI’s “Why we’re no longer using Core.typed”

Posted by Jakub Holý on October 6, 2015

CircleCI has recently published a very useful post “Why we’re no longer using Core.typed” that raises some important concerns w.r.t. Typed Clojure that in their particular case led to the cost overweighting the benefits. CircleCI has a long and positive relation to Ambrose Bonnaire-Sergeant, the main author of core.typed, that has addressed their concerns in his recent Strange Loop talk “Typed Clojure: From Optional to Gradual Typing” (gradual typing is also explained in his 6/2015 blog post “Gradual typing for Clojure“). For the sake of searchability and those of us who prefer text to video, I would like to summarise the main points from the response (spiced with some thoughts of my own).

Read the rest of this entry »

Posted in Languages | Tagged: , | Comments Off on An answer to CircleCI’s “Why we’re no longer using Core.typed”

Refactoring & Type Errors in Clojure: Experience and Prevention

Posted by Jakub Holý on October 6, 2015

While refactoring a relatively simple Clojure code to use a map instead of a vector, I have wasted perhaps a few hours due to essentially type errors. I want to share the experience and my thoughts about possible solutions since I encounter this problem quite often. I should mention that it is quite likely that it is more a problem (an opportunity? :-)) with me rather than the language, namely with the way I write and (not) test it.

The core of the problem is that I write chains of transformations based on my sometimes flawed idea of what data I have at each stage. The challenge is that I cannot see what the data is and have to maintain a mental model while writing the code, and I suck at it. Evaluating the code in the REPL as I develop it helps somewhat but only when writing it – not when I decide to refactor it.

Read the rest of this entry »

Posted in Languages | Tagged: , , | Comments Off on Refactoring & Type Errors in Clojure: Experience and Prevention

Nginx: Protecting upstream from overload on cache miss

Posted by Jakub Holý on October 1, 2015

These 2 magical lines will protect your upstream server from possible overload of many users try to access the same in cached or expired content: 

proxy_cache_use_stale updating timeout; # Serve the cached version even when outdated while refreshing it
proxy_cache_lock on; # Only one req is allowed to load/refresh the item, others wait / get the stale one 

You can verify this using Shopify’s Toxiproxy. 

<3 Nginx

Posted in [Dev]Ops | Comments Off on Nginx: Protecting upstream from overload on cache miss

Shipping a Refactoring & Feature One Tiny Slice at a Time, to Reduce Risk

Posted by Jakub Holý on September 1, 2015

You don’t need to finish a feature and your users don’t need to see it to be able to release and start battle-testing it. Slice it as much as possible and release the chunks ASAP to shorten the feedback loop and decrease risk.

My colleagues have been working on a crucial change in our webshop – replacing our legacy shopping cart and checkout process with a new one and implementing some new, highly desired functionality that this change enables. We have decided to decrease the risk of the change by doing it first only for product accessories. However the business wanted the new feature included and that required changes to the UI. But the UI has to be consistent across all sections so we would need to implement it also for the main products before going live – which would necessitate implementing also the more complex process used by the main products (and not yet supported by the new backend). And suddenly we had a a load of work that would take weeks to complete and would be released in a big bang deployment.

Such a large-scale and time-consuming change without any feedback from reality whatsoever and then releasing it all at once, having impact on all our sales – I find that really scary (and have fought it before). It is essentially weeks of building risk and then releasing it in a big kaboom. How could we break it down, to release it in small slices, without making the business people unhappy?

Read the rest of this entry »

Posted in SW development | Tagged: , | Comments Off on Shipping a Refactoring & Feature One Tiny Slice at a Time, to Reduce Risk