# Topic 32-34
###### tags: `The Pragmatic Programmer`
## Topic 32 Configuration
- **Code relies on values that may change** after the application has gone live, keep those values **external** to the app.
- Application will run in different environments, and potentially for different customers
- **Keep the environment- and customer-specific values outside the app**
- **Parameterize** your application: the code adapts to the places it runs.
### Tip 55: Parameterize Your App Using External Configuration
Look for anything that you know will have to change that you can express outside your main body of code
:::spoiler Common things put in configuration data
- Credentials for external services (database, third party APIs, and so on)
- Logging levels and destinations
- Port, IP address, machine, and cluster names the app uses
- Environment-specific validation parameters
- Externally set parameters, such as tax rates
- Site-specific formatting details
- License keys
:::
#### Static Configuration
> Flat files or database tables
Format:
- Popular flat files type: **YAML**, **JSON** (example from FR Studio)
- Better to store in database when:
- Information is structured
- Likely to be changed by the customer (ex: sales tax rates)
The configuration:
- Is read into your application as a data structure
- Normally when the application starts
- Commonly is made global, easier for any code to get to the values.
:::warning
The author suggest us NOT to do the above.
Instead, **wrap the configuration information behind a (thin) API**.
This decouples our code from the details of the representation of configuration.
:::
#### Configuration-As-A-Service
> Rather than flat file or database, the authors suggest configuration to be stored behind a service API. (example from FR Studio)
Benifits:
- Multiple applications can **share configuration information**, with authentication and access control limiting what each can see
- Configuration **changes can be made globally**
- The configuration data can be **maintained via a specialized UI**
- <u>The configuration data becomes **dynamic** !!!</u>
:::danger
:no_entry: <u>Static Configuation</u>
- We have to stop and restart an application to change a single parameter.
:::
:::success
:heavy_check_mark: <u>Configuration service</u>
- Components of the application could **register for notifications of updates** to parameters they use.
- Service could send them messages containing new values when they are changed.
- No need to rebuild, when configuration values change.
:::
**Reminders:**
- Don’t Write Dodo-Code:
Without external configuration, your code is not as adaptable or flexible as it could be.
- Don’t Overdo It:
Don’t push decisions to configuration out of laziness.
## Chapter 6 Concurrency: Introduction
- **Definition**
- <u>Concurrency</u>
- When the execution of two or more pieces of code act as if they run at the same time.
- To have concurrency, you need to run code in an environment that can switch execution between different parts of your code when it is running.
=> JavaScript Event Loop

- <u>Parallelism</u>
- When they do run at the same time.
- To have parallelism, you need hardware that can do two things at once. (ex: multiple cores in a CPU, multiple CPUs in a computer, or multiple computers connected together)

### Everything Is Concurrent
> Concurrency is a requirement if you want your application to be able to deal with the real world, where things are asynchronous: users are interacting, data is being fetched, external services are being called, all at the same time.
## Topic 33: Breaking Temporal Coupling
Two aspects of time that are important to us:
- **Concurrency**: things happening at the sametime
- **Ordering**: the relative positions of things in time
Temporal coupling: coupling in time, ex:
- `Method A` must always be called before `method B`
- Only one report can be run at a time
- Must wait for the screen to redraw before the button click is received.
:arrow_right: We need to allow for concurrency and to think about decoupling any time or order dependencies.
### Looking for Concurrency
Find out:
- **What can happen at the same time**
- **What must happen in a strict order**
:star: **Activity Diagram**: one way to capture the workflow
> Maximize parallelism by identifying activities that could be performed in parallel, but aren’t.
#### *Tip 56: Analyze Workflow to Improve Concurrency*
Example: steps of robotic piña colada maker
1. Open blender
2. Open piña colada mix
3. Put mix in blender
4. Measure 1/2 cup white rum
5. Pour in rum
6. Add 2 cups of ice
7. Close blender
8. Liquefy for 1 minute
9. Open blender
10. Get glasses
11. Get pink umbrellas
12. Serve
:arrow_down: **Applying activity diagram**

What is found:
- The top-level tasks (1, 2, 4, 10, and 11) can all happen concurrently, up front.
- Tasks 3, 5, and 6 can happen in parallel later.
### Opportunities for Concurrency
Activity diagrams show the potential areas of concurrency, but **have nothing to say about whether these areas are worth exploiting**. :arrow_right: **This is where the design part comes in**
*Robotic piña colada maker example:
Number 8, liquify, will take a minute. During that time, our bartender can get the glasses and umbrellas (activities 10 and 11) and probably still have time to serve another customer.*
:::info
Find activities that take time, but not time in our code. ex:
- Querying a database
- accessing an external service
- waiting for user input
These are opportunities to do something more productive.
:::
### Opportunities for Parallelism
> Parallelism is a hardware concern
- Split into pieces of work that are relatively independent—where each can proceed without waiting for anything from the others.
- Split it into independent chunks, process each in parallel, then combine the results.
:::warning
:heavy_exclamation_mark: Identifying Opportunities Is the Easy Part. The tricky part: how can we implement it safely.
:::
*<u>Challenges</u>
How many tasks do you perform in parallel when you get ready for work in the morning? Could you express this in a UML activity diagram? Can you find some way to get ready more quickly by increasing concurrency?*
## Topic 34: Shared State Is Incorrect State
*The apple pie example*

- The problem is the shared state. Each server in the restaurant looked into the display case without regard for the other.
- The problem here is not that two processes can write to the same memory. The problem is that **neither process can guarantee that its view of that memory is consistent**.
*If the value in the display case changes, their memory (which they are using to make decisions) is now out of date.*
*This is all because the fetching and then updating the pie count is not an atomic operation: the underlying value can change in the middle.*
### Semaphores and Other Forms of Mutual Exclusion
Semaphore: a thing that only one person can own at a time
*Apple pie example with Semaphore*
```
case_semaphore.lock()
if display_case.pie_count > 0
promise_pie_to_customer()
display_case.take_pie()
give_pie_to_customer()
end
case_semaphore.unlock()
```
:::warning
Problems with this approach:
- This is a convention that everyone need to agree and remember, or chaos.
- Delegates responsibility for protecting access to the pie case to the people who use it.
:::
#### Make the Resource Transactional
> centralize the control of Semaphore
Misconception example:
```
slice = display_case.get_pie_if_available()
if slice
give_pie_to_customer()
end
def get_pie_if_available() ####
if @slices.size > 0 #
update_sales_data(:pie) #
return @slices.shift #
else # incorrect code!
false #
end #
end ####
```
Correct way:
```
def get_pie_if_available()
@case_semaphore.lock()
try {
if @slices.size > 0
update_sales_data(:pie)
return @slices.shift
else
false
end
}
ensure {
@case_semaphore.unlock()
}
end
```
#### Multiple Resource Transactions
*Apple pie with ice cream as a single order*
```
slice = display_case.get_pie_if_available()
if slice
try {
scoop = freezer.get_ice_cream_if_available()
if scoop
try {
give_order_to_customer()
}
rescue {
freezer.give_back(scoop)
}
end
}
rescue {
display_case.give_back(slice)
}
end
```
:::warning
Problems with this approach:
- The code is now really ugly
- What about more resource?
:::
:::success
The pragmatic approach would be to say that “apple pie à la mode” is its own resource. We’d move this code into a new module, and then the client could just say “get me apple pie with ice cream” and it either succeeds or fails.
- Composite dishes
- Generic `get_menu_item`
:::
<br>
To be completed...