All you need is fun Cons T Åhs Keeper of The Code cons@klarna.com
Cons T Åhs Keeper of The Code at klarna Architecture - The Big Picture Development - getting ideas to work Code Quality - care about the details Increase competence of developers - better developers are more productive and delivers better solutions
Cons T Åhs Student in Uppsala 1981-85 (writing code for five years, Lisp before starting in Uppsala) Uppsala University (1985-2000, 2002, 2009, 2012), research & teaching; foundations, algorithms, functions, relations, objects, compilers, pragmatics, theory, theorem proving, formal program correctness.. Consultant (1991-); online poker, low level networking, medical imaging, graphics, finance, musical notation (Lisp), speech synthesis (Lisp, Prolog), compilers (Lisp, Prolog), real time video decoding, teaching.. Klarna from Feb. 28, 2011
Klarna - The Business Make shopping on the net simpler, safer, more fun. Pay by invoice after the goods are delivered Customer checks out at estore Klarna identifies customer and investigates credit estore sends goods and invoice Klarna pays estore (Klarna takes the risk) customer pays Klarna Identification and risk determination needs to be done fast (a few seconds)
Klarna - The Business Klarna makes money by taking a calculated risk We re buying and selling invoices What do we need to be good at? Identifying our customers - do you exist? Interesting algorithms, lots of data Evaluate risk - are you going to pay? Interesting algorithms, lots of data Bookkeeping - we re essentially a bank. Only lots of data, no algorithms
Founded in 2005 Revenue doubled every year from start - we re growing exponentially Sweden, Norway, Denmark, Finland, Germany, Netherlands, Austria - more to come.. Over 750 employees Klarna - The Facts Over 15K estores and growing Very nice for the shareholders.. 2005 2006 2007 2008 2009 2010 2011 2012
Klarna - The Facts Currently over 1.5M transactions/month average < 0.6/s, but there are peaks both over the day and the year you can t build for the average People shop all the time Available 24/7 - no downtime Software upgrades with no downtime Hardware upgrades and relocation with no downtime.. we need to build and maintain a robust system
Klarna - The technology Use technology from a domain with similar needs large amount of messages/transactions high demands on availability, scalability, robustness low tolerance for downtime for software or hardware upgrades We re using Erlang/otp functional, state is handled in processes easy to distribute and communicate can handle large amounts of processes robust soft real time
Erlang A functional language Dynamically typed functional language No side effects; variables are bound once and the value can not be changed Every expression computes a value Pattern matching provides parallel binding and compact programs (mixed blessing - beware!) Looks very much like Prolog The power of higher order functions and closures It is easier to understand, reason about, compile and debug a functional program.
Processes handles state Processes respond to incoming messages, compute a new state and recurse with this new state. Typical way of implementing a server: start_server() -> server(init_state()). server(state) -> server(process(get_msg(), State)). Note: compiler has last call optimisation, so tail recursive calls do not consume stack.
Erlang Easy to scale and distribute Processes are very light weight and process creation is very fast - encourages use of concurrent programming Concurrency and distribution model is very simple. Asynchronous message passing No shared state between processes No mutable state (at all) Process communication is the same regardless of if the process are in the same VM, different VMs or different physical machines - very easy to scale by adding more machines (or cores) when the need arises.
Joe Armstrong says: Each year your sequential programs will go slower. Each year your concurrent programs will go faster.
Erlang fault tolerance No shared state means that a crashing process will not take another process down. A crashing process can notify another process, which knows how to restart. Processes can be linked with each other, thereby creating process and supervisor structures Ease of distribution and horisontal scalability also makes it easy to build redundant systems - we have immediate failover if a server dies. Not trivial, but support for it exists in the language
Erlang at Klarna Focus on consistency and availability Use several nodes for fail over When, not if, a node dies another one can take over Replicate data between nodes Data is consistent between nodes and safe Know what you ve done Logs can be used to rebuild state after failures
The First System Site 1 Master BO Master Site 2 Slave BO Slave Each node runs Erlang Mnesia is used for persistence Master and slave have different main tasks master handles incoming purchases slave handles web traffic Back office (BO) handles customer service Data is replicated among the nodes, so all nodes have the same data If one node dies, the other takes over all responsibilities until the dead one comes up again (master and slave might then switch) Transaction logs are kept to rebuild state if needed Regular backups are kept
The First System Site 1 Master BO Master Site 2 Slave BO Slave Availability is covered by multiple nodes being able to fail over fast; this is immediate. Consistency is covered by letting the nodes/sites have different responsibilities and replicating data. Partition tolerance is handled in the same way as a dead node, i.e., a node will take over all responsibilities in a site. Data is synced upon contact again. We can keep availability even when external services don t answer. When one node has died, we re vulnerable during the time the other takes to restart. If both nodes die on a site, we have a serious problem.
The First System Site 1 Master BO Master Site 2 Slave BO Slave Software upgrades are done several times each week without downtime or stopping the system. Code is loaded while normal traffic is flowing. OS, Erlang and hardware can be upgraded without downtime; stop one node, do maintenance and restart. Hardware can be moved without downtime; stop one node, move it and restart. This has served us well from the start and is still doing quite nicely. Growth has been exponential, but this has also been able to handle the needed scaling. We are currently in a state of rebuilding the system
No silver bullet Erlang is not a silver bullet, nor is any functional programming language or any other language or technology There are no silver bullets for software engineering You can write excellent programs in C, Java, assembler, C ++,.., any language You can write bad programs in Erlang, Lisp, Scala,.., any language In the end it has more to do with the people, their competence, mindset, architecture and methods.
Benefits of Erlang Compact language in terms of core and semantics (small core + libraries written in the language itself) Easy to reason about due to lack of side effects, locks and shared memory High level of abstraction leads to compact programs Automatic memory management (GC) Easy to upgrade software and hardware without downtime Processes cannot interfere with each other; communication only with asynchronous message passing Fault tolerance easy (loose coupling of processes, supervisors) Distribution is simple among cores, VMs, boxes
Benefits of functional programming A true high level language makes you more productive Short turn around times True generality means less need for special constructs in the language Concentrate on details of the problem and the solution, not on irrelevant and tedious details of the language, memory management, implementation, hardware Correctly written, testing and reuse is easier Debugging is easier; only high level details and actual argument, no transient state created by other parts of the program Higher order programming
Benefits of functional programming Principles and patterns used in OO are just natural higher order programming Easy to write a DSL (Domain Specific Language) when needed - great for productivity Great for both rapid prototyping and short development iterations - great for productivity Hot code loading
Still no silver bullet Using a functional programming language is not a substitute for competence You still need to know your tools (language (use and implementation), algorithms, data structures, compilers (both using and writing),..) Using abstraction does not mean that you can ignore what happens behind the layers, but you don t mix them up. There are no short cuts to becoming a great software developer, but if you know your basics and functional programming you can be much more productive Being great in a functional language makes it easier to be great in any language the converse is not true, though
Still no silver bullet Know the math behind the problems and solutions Know the complexity Know different programming paradigms - choose the correct one for each problem Design, write and maintain code, programs, systems Readability and understandability is important in the long run Code is read more often than written Know how to write the tools you need To measure is to know - don t guess! Software development is a long term process
Software development is a long term process Summit far away
Software development is a long term process 250-300m still Summit far away
Distribution made easy Distribute work load among a number of workers Input the work to be done, a queue of tasks the workers that performs the work (pids) What is specific for each problem? How to get a chunk of work from the queue How to combine results from a single worker with the result from the others
Distribution made easy We re done when the queue is empty and we have no active workers. We wait for a worker to return a result when the queue is empty or we have no passive workers We activate a worker when the queue is non empty and we have passive workers. Initial state is a queue of work, no active workers and a collection of passive workers.
Distribution made easy sequential(l) -> lists:filter(fun is_prime/1, L). process_work([], [], _, State) -> State; process_work(work, Active, Passive, State) when Work =:= []; Passive =:= [] -> receive {Worker, M} -> process_work(work, lists:delete(worker, Active), [Worker Passive], add_result(state, M)) end; process_work(work, Active, [Worker Passive], State) -> {Chunk, Rest} = get_chunk(state, Work), Worker! {self(), Chunk}, process_work(rest, [Worker Active], Passive, State). worker() -> receive {Pid, Work} -> Pid! {self(), sequential(work)}, worker() end.
Summary Don t think that functional and other declarative languages are oddities used for teaching. There is an increasing interest in functional languages such as Erlang, scala, clojure, Lisp, F#.. Other languages are starting to include lambda abstractions and closures. It is much easier to transit from functional languages to other paradigms than the other way. Know thy declarative languages and look forward to a great future! All you need is fun!