Designing Elixir... Flashcards

(24 cards)

1
Q

what is the boundary layer

A
  • machinery of processes, message passing, and recursion that form the heart of concurrency in Elixir systems
  • An API of plain functions that hides that machinery from clients
    P 8
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

what does the boundary layer deal with?

A

side effects and state

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

What are the rules for functions in the functional core?

A
  • must not have side effects
  • when invoked with the same inputs, must always return the same outputs
  • no processes
  • invokes no external services
  • encapsulates the bulk of the business logic
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

describe strategies for defining functions in the functional core to make them pipeable

A

a module has a single concept, and each function taking a common datatype as it’s first arg. When the functions also return the modules struct, it’s also easier to pipe.

Complex multipurpose functions break down into pipes of single-purpose functions

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

List the signs of good Elixir code

A
  • skinny left margin
  • short functions
  • long pipes (shape functions for composition)
  • functions are used to “name a concept” (P. 69)
  • functions built w/ single level of abstraction
  • make decisions in the head when possible
  • single purpose functions
  • where possible, bring functions to data instead of data to functions
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

List the 3 parts of the boundary layer

A

boundaries, workers, lifecyle P. 100

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

describe “the boundary”

A

An optional layer of impure integration code that makes the core fast, robust, and reliable

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

describe “the lifecycle”

A

provides tools to start and stop the boundary layer

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

describe “workers”

A

divide work for performance, isolation, or reliability

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Name 5 scenarios you should consider using processes

A
  • Sharing state across processes
  • Presenting a uniform API for external services such as databases or communications
  • Managing side effects such as logging or file IO
  • Monitoring system-wide resources or performance metrics
  • Isolating critical services from failure
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

What is the job of the API layer?

A

To insulate the server layer from inconsistent data and to stitch together independent concepts from the individual GenServer implementations.

It can also hide implementation details from the user.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

What is the most important design concept when designing the API layer

A

To keep the API layer as thin as possible, and take on as little business logic as possible

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

how do you check a Process’s message mailbox length?

A
defp message_queue_length() do
{:message_queue_len, messages} = Process.info(self(), :message_queue_len) messages
end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

should you prefer call or cast?

A

Call, it provides backpressure and serializability

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

what are some cases where you may need to judisciously use cast instead of call?

A

when starting multiple workers at once, or when notifying multiple workers simultaneously.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Define the purpose of a worker

A

The worker layer exists to manage concurrency using a variety of tools: naked processes, connection pools, tasks, and other dependencies….

A worker is process machinery that lets us divide labor for reliability, performance, or scalability

17
Q

where does worker code go?

A

Worker code lives in the boundary with the rest of our process machinery.

18
Q

What is the worker layer?

A

the process machinery that manages concurrency apart from lifecycle policy

19
Q

Explain why you’d use a worker layer

A

Three primary motivations for introducing a worker layer: concurrency, isolation and scalability. Concurrency is a focused issue that allows more than one task to happen at a time, often reducing latency or enabling a feature like a scheduler. Isolation improves system reliability by limiting the damage any single bug can do by crashing a process. Scalability is a broader architectural concern, allowing one program to run across many processes.

20
Q

List 2 tools for implementing a worker layer

A

GenServers, Tasks

21
Q

How can you provide back pressure when using concurrency

A

prefer handle_call to handle_cast

Make use of async_stream (P. 159).
What you really need is a way to spread that work out. Even better, you would like to divide the work optimally, based on the number of cores supported by your hardware. Thats what async_stream does

22
Q

list the parts of the boundary layer

A

boundary API, lifecycles, and workers

23
Q

How can you silence logs in ExUnit

A

ExUnit.CaptureLog.capture_log P. 198

Or, @moduletag capture_log: true P. 208

24
Q

Name one sign that your abstractions are right

A

if your abstraction is right, your tests should be simple. P. 199