Skip to content

Commit

Permalink
titlecase a bunch of headers
Browse files Browse the repository at this point in the history
  • Loading branch information
hjwp committed Nov 9, 2019
1 parent 0107b3c commit 6c6c6ae
Show file tree
Hide file tree
Showing 16 changed files with 45 additions and 45 deletions.
4 changes: 2 additions & 2 deletions appendix_bootstrap.asciidoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[[appendix_bootstrap]]
== Bootstrap (aka Configuration Root)
== Bootstrap (AKA Configuration Root)

NOTE: placeholder chapter, under construction

Expand Down Expand Up @@ -105,7 +105,7 @@ def bootstrap(
* it gives us back the core of our app, the messagebus


=== Using Bootstrap in our Entrypoints
=== Using Bootstrap in Our Entrypoints

In our application's entrypoints, we just call `bootstrap.bootstrap()`
to get a messagebus, rather than configuring a UoW and the rest of it.
Expand Down
2 changes: 1 addition & 1 deletion appendix_csvs.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -298,4 +298,4 @@ def main(folder):
Ta-da! NOW ARE Y'ALL IMPRESSED OR WHAT?

much love,
Bob and Harry.
Bob and Harry.
4 changes: 2 additions & 2 deletions appendix_django.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ You can see that the implementation relies on the Django models having
some custom methods for translating to and from our domain model.


==== Custom Methods on Django ORM Classes to Translate To/From our Domain Model
==== Custom Methods on Django ORM Classes to Translate To/From Our Domain Model

NOTE: As in <<chapter_02_repository>>, we use dependency inversion.
The ORM (Django) depends on the model, and not the other way around
Expand Down Expand Up @@ -371,4 +371,4 @@ So why might you still do it?
be a bad idea, it goes against the grain of wanting to decouple your model
and business logic from the ORM...)

// TODO: Expand on this wrap-up?
// TODO: Expand on this wrap-up?
2 changes: 1 addition & 1 deletion appendix_project_structure.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -399,4 +399,4 @@ config and so on.
We've not needed to make tests pip-installable, but if you have difficulties with
import paths, you might find it helps.

// TODO (DS): Mysterious...
// TODO (DS): Mysterious...
4 changes: 2 additions & 2 deletions chapter_01_domain_model.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -897,7 +897,7 @@ def allocate(line: OrderLine, batches: List[Batch]) -> str:
----
====

==== Python's Magic Methods Let Us Use our Models with Idiomatic Python
==== Python's Magic Methods Let Us Use Our Models with Idiomatic Python

You may or may not like the use of `next()` above, but we're pretty
sure you'll agree that being able to use `sorted()` on our list of
Expand Down Expand Up @@ -1013,4 +1013,4 @@ This is the time to apply your best OO design principles::
You'll also want to think about consistency boundaries and Aggregates::
But that's a topic for <<chapter_06_aggregate>>.
*****************************************************************
*****************************************************************
2 changes: 1 addition & 1 deletion chapter_02_repository.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -948,4 +948,4 @@ You'll be wondering, how do we actually instantiate these repositories, fake or
real? What will our flask app actually look like? We'll find out in the next
exciting installment, <<chapter_04_service_layer,the Service Layer pattern>>.

But first, a brief digression.
But first, a brief digression.
6 changes: 3 additions & 3 deletions chapter_04_service_layer.asciidoc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[[chapter_04_service_layer]]

== Our First Use Case: Flask API and Service Layer.
== Our First Use Case: Flask API and Service Layer

Back to our allocations project!

Expand Down Expand Up @@ -83,7 +83,7 @@ BatchRepository ---> Session : abstracts



=== Connecting our Application to the Real World
=== Connecting Our Application to the Real World

Like any good agile team, we're hustling to try and get an MVP out and
in front of the users to start gathering feedback. We have the core
Expand Down Expand Up @@ -686,7 +686,7 @@ stuff, which we implement end-to-end; and tests about orchestration stuff, which
we can test against the service layer in memory.


=== How is our Test Pyramid Looking?
=== How Is Our Test Pyramid Looking?

Let's see what this move to using a Service Layer, with its own service-layer tests,
does to our test pyramid:
Expand Down
2 changes: 1 addition & 1 deletion chapter_05_uow.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -658,4 +658,4 @@ a|
things like rollbacks, multithreading, and nested transactions. Perhaps just
sticking to what Django or Flask-SQLAlchemy gives you will keep your life
simpler.
|===
|===
4 changes: 2 additions & 2 deletions chapter_06_aggregate.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -569,7 +569,7 @@ class Product:
// also discuss similarity with eventsourcing version numbers.


=== Testing for our Data Integrity Rules
=== Testing for Our Data Integrity Rules

Now to actually make sure we can get the behavior we want: if we have two
concurrent attempts to do allocation against the same `Product`, one of them
Expand Down Expand Up @@ -766,4 +766,4 @@ a|
big mental shift.

* Dealing with eventual consistency between aggregates can be complex.
|===
|===
8 changes: 4 additions & 4 deletions chapter_07_events_and_message_bus.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ image::images/message_bus_diagram.png[]

=== Avoiding Making a Mess.

==== First, Avoid Making a Mess of of our Web Controllers
==== First, Avoid Making a Mess of of Our Web Controllers

So. Email alerts when we run out of stock. When we have a new requirement like
this, that's not _really_ to do with the core domain, it's all too easy to
Expand Down Expand Up @@ -99,7 +99,7 @@ end up in a mess by patching things in this way. Sending emails isn't the job of
our HTTP layer, and we'd like to be able to unit test this new feature.


==== ... And Let's Not Make a Mess of our Model Either
==== ... And Let's Not Make a Mess of Our Model Either

Assuming we don't want to put this code into our web controllers, because
we want them to be as thin as possible, we may look at putting it right at
Expand Down Expand Up @@ -380,7 +380,7 @@ service layer explicitly collects events from aggregates, and passes them to
the messagebus.


==== Option 2: The Service Layer Raises its own Events
==== Option 2: The Service Layer Raises Its Own Events

Another variant on this which we've used is that you can have the service layer
in charge of creating and raising events directly, rather than having them
Expand Down Expand Up @@ -666,4 +666,4 @@ a|
* celery is _fine_.
|===

TODO: finish up pros + cons
TODO: finish up pros + cons
24 changes: 12 additions & 12 deletions chapter_08_all_messagebus.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ model -> event [style=dotted, len=100]
----


=== A New Requirement Leads Us To Consider A New Architecture
=== A New Requirement Leads Us to Consider a New Architecture

Rich Hickey talks about "situated software", meaning software that runs for
extended periods of time, managing some real world process. Examples include
Expand Down Expand Up @@ -106,7 +106,7 @@ enforce the single responsibility principle, and it allows us to make choices ab
transactions and data integrity.


==== Imagining an Architecture Change: Everything Will Be An Event Handler
==== Imagining an Architecture Change: Everything Will Be an Event Handler

But before we jump in, think about where we're headed. There are two
kinds of flows through our system:
Expand Down Expand Up @@ -162,7 +162,7 @@ Refactoring] workflow, AKA "make the change easy, then make the easy change":
handler for allocations that the API uses.


=== Refactoring Service Functions To Message Handlers
=== Refactoring Service Functions to Message Handlers

We start by defining the two events that capture our current API inputs:
`AllocationRequired` and `BatchCreated`:
Expand Down Expand Up @@ -268,7 +268,7 @@ The change might be clearer as a diff:
====


==== The MessageBus needs to pass a UoW to each handler
==== The MessageBus Needs to Pass a UoW to Each Handler

Our event handlers now need a UoW. We make a small modification
to the main `messagebus.handle()` function:
Expand Down Expand Up @@ -312,7 +312,7 @@ class AbstractUnitOfWork(abc.ABC):
double-dispatch and it's a common trick for managing a circular dependency.


==== Our tests are all written in terms of events too:
==== Our Tests Are All Written in Terms of Events Too:


[[handler_tests]]
Expand Down Expand Up @@ -347,7 +347,7 @@ class TestAllocate:
// TODO: (DS) why staticmethod?


==== A temporary ugly hack: the messagebus has to return results
==== A Temporary Ugly Hack: The Messagebus Has to Return Results

Our API and our service layer currently want to know the allocated batch ref
when they invoke our `allocate()` handler. This means we need to put in
Expand All @@ -372,7 +372,7 @@ a temporary hack on our messagebus to let it return events.
It's because we're mixing the read and write responsibilities in our system.
We'll come back to fix this wart in <<chapter_09_cqrs>>.

==== Modifying our API to do Events
==== Modifying Our API to Do Events

[[flask_uses_messagebus]]
.Flask changing to messagebus as a diff (src/allocation/flask_app.py)
Expand Down Expand Up @@ -411,7 +411,7 @@ fully event-driven.
TODO: recap?


=== Implementing our new requirement
=== Implementing Our New Requirement

We're done with our refactoring phase. Our application is a message processor,
everything is driven by events and the message bus.
Expand Down Expand Up @@ -448,7 +448,7 @@ end



==== Our new event
==== Our New Event

The event that tells us a batch quantity has changed is very simple, it just
nees a batch reference and a new quantity:
Expand All @@ -467,7 +467,7 @@ class BatchQuantityChanged(Event):
====


=== Test-driving A New Handler
=== Test-Driving a New Handler

Following the lessons learned in <<chapter_03_service_layer>>,
we can operate in "high gear," and write our unit tests at the highest
Expand Down Expand Up @@ -821,7 +821,7 @@ Singleton Pattern.
and really stick to the SRP.


=== Why have we achieved?
=== Why Have We Achieved?

Our ongoing objective with these architectural patterns is to try and have
the complexity of our application grow more slowly than its size. Here
Expand Down Expand Up @@ -855,4 +855,4 @@ a|
* duplication / maintenance cost of having model objects _and_ events
now. adding a field to one usually means adding a field to at least
on of the others
|===
|===
2 changes: 1 addition & 1 deletion chapter_09_commands.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -221,4 +221,4 @@ TODO (ej) Devil's advocate: If your messagebus.handle processes half the events
or being OOM killed, how do you mitigate problems cause by the lost messages?
////

TODO: discussion, can events raise commands?
TODO: discussion, can events raise commands?
14 changes: 7 additions & 7 deletions chapter_10_external_events.asciidoc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[[chapter_10_external_events]]
== Event-driven Architecture: Using Events To Integrate Microservices
== Event-Driven Architecture: Using Events to Integrate Microservices

NOTE: Chapter under construction.

Expand All @@ -12,7 +12,7 @@ In this chapter:
TODO: DIAGRAM GOES HERE


=== How Do We Talk To The Outside World?
=== How Do We Talk to the Outside World?

In the last chapter we never actually spoke about _how_ we would receive
the "batch quantity changed" events, or indeed, how we might notify the
Expand All @@ -28,7 +28,7 @@ to encompass the way that we handle incoming and outgoing messages from the
system.


==== Using A Redis Pubsub Channel For Integration
==== Using a Redis Pubsub Channel for Integration

To avoid the "distributed BBOM" antipattern, instead of temporally coupled HTTP
API calls, we want to use some sort of asynchronous messaging layer to
Expand Down Expand Up @@ -80,7 +80,7 @@ MessageBus -> Redis : publish to line_allocated channel
----


=== Test-driving It All Using An End-to-end Test
=== Test-Driving It All Using an End-To-End Test

Here's how we might start with an end-to-end test. We can use our existing
API to create batches, and then we'll test both inbound and outbound messages:
Expand Down Expand Up @@ -227,7 +227,7 @@ def publish(channel, event: events.Event): #<3>
<3> We also provide a helper function to publish events back into Redis.


==== Our new outgoing event
==== Our New Outgoing Event

Here's what the `Allocated` event will look like:

Expand Down Expand Up @@ -320,11 +320,11 @@ much a topic for another book though).
*******************************************************************************


=== Wrap-up
=== Wrap-Up

* events can come _from_ the outside, but they can also be published
externally -- our `publish` handler converts an event to a message
on a Redis channel. We use events to talk to the outside world.


TODO: more here
TODO: more here
4 changes: 2 additions & 2 deletions chapter_11_cqrs.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ TIP: Split out your read-only views from your state-modifying
command and event handlers.


=== Why On Earth Would You Write Raw SQL In Your Views?
=== Why on Earth Would You Write Raw SQL in Your Views?

OK Bob and Harry, let's get back to that SQL monstrosity though. Why
on earth would you show us that? Don't think we're about to forget, the
Expand Down Expand Up @@ -480,4 +480,4 @@ TODO: demo this.
So definitely don't do this. ever. But, if you do need to, see how easy
the event-driven model makes it?

OK. On that note, let's sally forth into our final chapter.
OK. On that note, let's sally forth into our final chapter.
6 changes: 3 additions & 3 deletions chapter_12_dependency_injection.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ functions and event handlers and other entrypoints, our dependencies would be
all over the place.


=== Initializing DI in our App Entrypoints
=== Initializing DI in Our App Entrypoints

In our flask app, we can just initialize the messagebus inline with
the rest of our app config and setup, passing it in the actual
Expand Down Expand Up @@ -362,7 +362,7 @@ def handle_change_batch_quantity(m, bus: messagebus.MessageBus):
(we'll look at fixing that in <<appendix_bootstrap>>.


=== Initializing DI in our Tests
=== Initializing DI in Our Tests


[[fakebus]]
Expand Down Expand Up @@ -607,4 +607,4 @@ notifications or something?
Oh yeah, step 4 is a bit challenging...
Or, do the same thing for redis. You'll need to split pub from sub.
******************************************************************************
******************************************************************************
2 changes: 1 addition & 1 deletion uppercase-titles.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from chapters import CHAPTERS

SPECIAL = {
'CSVs', 'To/From', 'UoW',
'CSVs', 'To/From', 'UoW', 'AKA', 'SELECT',
}

LOWERCASE = {
Expand Down

0 comments on commit 6c6c6ae

Please sign in to comment.