Skip to content

Commit 5a53a86

Browse files
committed
caching example
1 parent 326e475 commit 5a53a86

File tree

1 file changed

+6
-2
lines changed

1 file changed

+6
-2
lines changed

chapters/ch06.asciidoc

+6-2
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,13 @@ One particularly insidious form of state is caching. A cache is a great way to i
215215

216216
Derived state should seldom be treated as state that's separate from the data it was derived from. When it's not, we might run into situations where the original data is updated, but the derived state is not, becoming stale and inaccurate. When, instead, we always compute derived state from the original data, we reduce the likelyhood that this derived state will become stale.
217217

218-
State is almost ubiquitous, and practically a synonym with application. Applications without state aren't particularly useful, but how can we better manage state? If we look at applications such as your typical web server, their main job is to receive requests, process them, and send a response. Consequently, web servers associate state to each request, keeping it close to the request handlers, the most relevant party. There should be as little global state as possible when it comes to web servers, with the vast majority of state contained in each request/response cycle instead. In this way, we save ourselves from a world of trouble when setting up horizontal scaling with multiple server nodes that don't need to communicate with each other in order to maintain consistency across web server nodes, leaving that job to the data persistance layer instead, which is ultimately responsible for the state as its source of truth.
218+
State is almost ubiquitous, and practically a synonym of applications, because applications without state aren't particularly useful. The question then arises: how can we better manage state? If we look at applications such as your typical web server, their main job is to receive requests, process them, and send back the appropriate responses. Consequently, web servers associate state to each request, keeping it near request handlers, the most relevant consumer of request state. There is as little global state as possible when it comes to web servers, with the vast majority of state contained in each request/response cycle instead. In this way, web servers save themselves from a world of trouble when setting up horizontal scaling with multiple server nodes that don't need to communicate with each other in order to maintain consistency across web server nodes, leaving that job to a data persistance layer, which is ultimately responsible for the state as its source of truth.
219219

220-
When a request results in a long running job (such as sending out an email campaign, modifying records in a persistant database, etc), it's best to hand that off into a separate service that -- again -- mostly keeps state regarding said job. Separating services into specific needs means we can keep web servers lean, stateless, and improve our flows by adding more servers, persistent queues (so that we don't drop jobs), and so on. When every task is tethered together through tight coupling and state, it becomes challenging to maintain, upgrade, and scale a service over time.
220+
When a request results in a long running job (such as sending out an email campaign, modifying records in a persistant database, etc), it's best to hand that off into a separate service that -- again -- mostly keeps state regarding said job. Separating services into specific needs means we can keep web servers lean, stateless, and improve our flows by adding more servers, persistent queues (so that we don't drop jobs), and so on. When every task is tethered together through tight coupling and state, it could become challenging to maintain, upgrade, and scale a service over time.
221+
222+
Derived state in the form of caches is not uncmoon in the world of web servers. In the case of a personal website with some books available for download, for instance, we might be tempted to store the PDF representation of each book in a file, so that we don't have to recompile the PDF whenever the corresponding `/book` route is visited. When the book is updated, we'd recompute the PDF file and flush it to disk again, so that this derived state remains fresh. When our web server ceases to be single node and we start using a cluster of several nodes, however, it might not be so trivial to broadcast the news about books being updated across nodes, and thus it'd be best to leave derived state to the persistance layer. Otherwise, a web server node might receive the request to update a book, perform the update and recompute the PDF file on that node, but we'd be inadvertently invalidating the PDF files being served by other nodes, which would have stale copies of the PDF representation.
223+
224+
A better alternative in such a case would be to store derived state in a data store like Redis or Amazon S3, either of which we could update from any web server, and then serving precomputed results from Redis directly. In this way we'd still be able to access the latency benefits of using precomputed derived state, but at the same time we'd stay resilient when these requests or updates can happen on multiple web server nodes.
221225

222226
==== 6.6 Disposability
223227

0 commit comments

Comments
 (0)