Let it crash

As the functional programming paradigm becomes more and more broadly recognized, interest in functional languages (Scala, F#, Erlang, Elixir, Haskell, Clojure, Mathematica, and many others) has increased rapidly over the last few years; it still remains far from the position that mainstream languages like Java and .NET have. Functional languages are predominantly declarative and based on the principles of avoiding state change and eliminating side effects. Several of these languages and frameworks, such as Scala/Akka and Erlang/OTP, also provide a new approach to handling concurrency by avoiding shared state and promoting messaging/events as a means of communication and coordination between processes. As a consequence, they also provide frameworks based on actors and lightweight processes.

Fail-fast, on the other hand, as an important system design paradigm, helps avoid flawed processing in mission-critical systems. Fail-fast makes it easier to find the root cause of a failure, but also requires that the system be built in a fault-tolerant way and be able to automatically recover from the failure.

Fail-fast, combined with lightweight processes, brings us to the “Let it crash” paradigm. “Let it crash” takes the fail-fast paradigm even further. The “Let it crash” system is not only built to detect and handle errors and exceptions early, but also assumes that only the main processing flow really counts and should be implemented and handled. There is little purpose in programming defensively, i.e., by attempting to identify all possible fault scenarios up front. As a programmer, you now only need to focus on the most probable scenarios and the most likely exceptional flows. Any other hypothetical flows are not worth spending time on and should instead lead to a crash and recovery. “Let it crash” focuses on the functionality first and this way supports very well modern Lean Development and Agile Development paradigms.

As Joe Armstrong states in his Ph.D. thesis, if you canʼt do what you want to do, die, and you should not program defensively, thus program offensively and “Let it crash. “ Instead of trying to focus on covering all possible fault scenarios, just let it crash. “

Photo: Pexels

However, recovery from a fault always takes some time (i.e., seconds or even minutes). Not all kinds of languages and systems are designed to handle this kind of behavior. In particular, “Let it crash” is hard to achieve in C++ or Java. The recovery needs to be fast and unnoticed for the processes that are not directly involved in it. This is where functional languages and actor frameworks come into the picture. Languages like Scala/Akka or Erlang/OTP promote the actor model, enabling the handling of many thousands of processes on a single machine, rather than hundreds of OS processes. Thousands of lightweight processes enable isolating processing for a single system user or subscriber. It is thus cheaper to let the process crash; it also recovers faster.

“Let it crash” is also naturally easier to implement in an untyped language (e.g., Erlang). The main reason for this is error handling and how difficult it is to redesign exception handling once it is implemented. Typed languages can be quite constraining when combined with the “Let it crash” paradigm. In particular, it is rather hard to change an unchecked exception into a checked exception and vice versa once you have designed your Java class.

Finally, “Let it crash” also implies that there exists a sufficient framework for recovery. In particular, Erlang and OTP (Open Telecom Platform) provide the concept of supervisors and various recovery scenarios for the whole process trees. This kind of framework makes implementing the “Let it crash” much simpler by providing a foolproof, out-of-the-box recovery scheme for your system.

There are also other benefits of the “Let it crash” approach. As there are now multiple end users of your system and each subscriber is represented as a single process, you can easily leverage advanced models such as finite state machines. Even though not specific to Erlang or Scala, finite state machines are quite useful for understanding what led to a failure once your system fails. Finite state machines, combined with a “Let it crash” framework, can be very efficient for fault analysis and correction.

Although very powerful and sophisticated, “Let it crash” unfortunately has not yet gained much attention, except when combined with Scala/Akka and Erlang/OTP. The reasons are many, on one side (as explained above), the very specific and tough requirements on the programming languages and platforms, but also the very fact that only the mission-critical systems really require this level of fault tolerance. For classic, less-critical business systems, fault-tolerance requirements are not significant enough to justify using a niche technology such as Erlang or Scala/Akka.

“Perfect is the enemy of good,” and mainstream languages like Java or .NET win the game again, even though they are inferior when it comes to fault-tolerance and supporting the “Let it crash” approach.

All content on this site, excluding the photos and pictures, is licensed under a Creative Commons Attribution 4.0 International License.

Creative Commons License

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.