Table of contents : Cover Title Page Copyright and Credits Dedication Packt Upsell Contributors Table of Contents Preface Chapter 1: Preparing for the Journey Ahead Why functional programming? Elixir and Erlang Elixir's data types Integers Floats Atoms Booleans Tuples Lists Maps Binaries Strings and charlists Other types Keyword lists Ranges MapSets Pattern matching Pattern matching on tuples Pattern matching on lists Pattern matching on maps Pattern matching on binaries and strings Functions and Modules Anonymous functions Modules and Named Functions Module attributes, directives, and uses Working with collections Looping through recursion Eager processing with the Enum module Comprehensions Lazy processing with the stream module Control flow if and unless cond case with Exceptions Typespecs and behaviours Typespecs Dialyzer Behaviours Protocols Structs Bringing structs and protocols together Tooling and ecosystems IEx Mix ExUnit Erlang interoperability Summary Chapter 2: Innards of an Elixir Project Elixir applications Elixir project structure Project dependencies Umbrella projects ElixirDrip – our showcase application Using behaviours Viewing cross references with xref Adopting a consistent coding style Summary Chapter 3: Processes – The Bedrock of Concurrency and Fault Tolerance Inside the BEAM Working with processes Creating processes Message passing between processes Building a cache worker Detecting errors by linking and monitoring processes Using links Using monitors Recovering from errors with supervisors and supervision trees Defining and starting a supervisor Streamlined child specs Starting children at runtime using dynamic supervisors Minimizing error effects with supervision trees Summary Chapter 4: Powered by Erlang/OTP GenServer GenServer at your service Implementing a CacheWorker with GenServer Agent Task Parallel tasks Using (D)ETS Disk-based ETS Registry Summary Chapter 5: Demand-Driven Processing GenStage The upload pipeline The notifier stage The RemoteStorage stage The Encryption stage The Starter stage The download pipeline The Notifier stage The Encryption stage The RemoteStorage stage The Starter stage Final remarks Flow Sample data Lazy queries Disk-usage rank query Summary Chapter 6: Metaprogramming – Code That Writes Itself The abstract syntax tree Tinkering with macros Hygienic accesses Famous (un)quotes Macros – a silver bullet? Extending modules Using the use and __using__/1 macros Creating a domain-specific language Registering module attributes Collecting a list of pipeline steps Generating worker specs and subscription options Producer stage ProducerConsumer and Consumer stages Collecting the pipeline worker specs Defining the supervisor functions Streamlining GenStage modules Simpler pipeline producers Simpler pipeline (producer) consumers Macros cheat sheet Summary Chapter 7: Persisting Data Using Ecto Connecting to the database Schemas and migrations Schemas Custom field types Users or media owners? Schema or not – that is the question Migrations Relationships Changesets Media Users Media ownership Constraints Queries Media folder queries Loading schemas and their associations Queries with raw SQL Finding top users with aggregates Summary Chapter 8: Phoenix – A Flying Web Framework The Plug specification Creating a module plug Creating a function plug Routing requests Handling requests in a controller Rendering views Layouts Authenticating users Implementing a JSON API Authenticating users in the API Interactive applications using channels Preparing the server Joining channels on the client Exchanging events Authenticating socket connections Tracking users statuses using Presence Summary Chapter 9: Finding Zen through Testing Unit testing Testing functions without side-effects Testing functions with side-effects Creating mocks with Mox Testing interactions with the repository separately Testing the documentation Integration testing Testing Phoenix Channels Testing macros Property-based testing Summary Chapter 10: Deploying to the Cloud Releasing with Distillery Configuring the release Interpolating environment variables Creating the release Creating a custom release task Containerizing our application Creating a development container Orchestrating more than one container Composing the deployment containers Deploying to Kubernetes Configuring the cloud database Creating a namespace Creating secrets Publishing the production image Deploying your first pod Creating a Kubernetes job Exposing your pods to the world Continuous deployment with Travis CI Connecting the deployed Elixir nodes Testing the connected nodes Summary Chapter 11: Keeping an Eye on Your Processes Collecting metrics Exposing Prometheus metrics Creating custom Prometheus metrics Local Prometheus server Deploying Prometheus in Kubernetes Calculating percentiles Setting Grafana variables A window to your nodes Connecting to a containerized node Connecting to an Erlang node running in Kubernetes Using a remote shell Inspecting application behavior Profiling with the fprof profiler Tracing with the :dbg module Summary Other Books You May Enjoy Index