SlideShare a Scribd company logo
Exploring Cqrs And Event Sourcing A Journey Into
High Scalability Availability And
Maintainability With Windows Azure 1st Edition
Dominic Betts download
https://ebookbell.com/product/exploring-cqrs-and-event-sourcing-
a-journey-into-high-scalability-availability-and-maintainability-
with-windows-azure-1st-edition-dominic-betts-4686082
Explore and download more ebooks at ebookbell.com
Here are some recommended products that we believe you will be
interested in. You can click the link to download.
The Best Car Book In The World Exploring The Worlds Most Expensive
Cars The Worlds Rarest Cars And Cars Of The Future Hedditch
https://ebookbell.com/product/the-best-car-book-in-the-world-
exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and-
cars-of-the-future-hedditch-42118868
The Best Car Book In The World Exploring The Worlds Most Expensive
Cars The Worlds Rarest Cars And Cars Of The Future Pdfdrivecom
Hedditch
https://ebookbell.com/product/the-best-car-book-in-the-world-
exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and-
cars-of-the-future-pdfdrivecom-hedditch-43618202
The Best Car Book In The World Exploring The Worlds Most Expensive
Cars The Worlds Rarest Cars And Cars Of The Future Peter Hedditch
https://ebookbell.com/product/the-best-car-book-in-the-world-
exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and-
cars-of-the-future-peter-hedditch-42118944
The Best Car Book In The World Exploring The Worlds Most Expensive
Cars The Worlds Rarest Cars And Cars Of The Future Hedditch
https://ebookbell.com/product/the-best-car-book-in-the-world-
exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and-
cars-of-the-future-hedditch-42083162
The Best Car Book In The World Exploring The Worlds Most Expensive
Cars The Worlds Rarest Cars And Cars Of The Future Peter Hedditch
https://ebookbell.com/product/the-best-car-book-in-the-world-
exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and-
cars-of-the-future-peter-hedditch-5552660
Exploring Meditation Exploring Series Susan Shumsky
https://ebookbell.com/product/exploring-meditation-exploring-series-
susan-shumsky-44908504
Exploring Geographic Information Systems 2nd Edition Nicholas Chrisman
https://ebookbell.com/product/exploring-geographic-information-
systems-2nd-edition-nicholas-chrisman-44967472
Exploring Scale Symmetry Thomas Lowe
https://ebookbell.com/product/exploring-scale-symmetry-thomas-
lowe-44975766
Exploring Susceptibleinfectiousrecovered Sir Model For Covid19
Investigation Rahul Saxena
https://ebookbell.com/product/exploring-
susceptibleinfectiousrecovered-sir-model-for-covid19-investigation-
rahul-saxena-45333430
Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts
Exploring CQRS and
Event Sourcing
A journey into high scalability, availability,
and maintainability with Windows Azure
Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts
Exploring CQRS and
Event Sourcing
A journey into high scalability, availability,
and maintainability with Windows Azure
Dominic Betts
Julián Domínguez
Grigori Melnik
Fernando Simonazzi
Mani Subramanian
978-1-62114-016-0
This document is provided “as-is”. Information and views expressed in
this document, including URL and other Internet Web site references,
may change without notice.
Some examples depicted herein are provided for illustration only and are
fictitious. No real association or connection is intended or should be
inferred.
This document does not provide you with any legal rights to any
intellectual property in any Microsoft product. You may copy and use
this document for your internal, reference purposes. You may modify this
document for your internal, reference purposes
© 2012 Microsoft. All rights reserved.
Microsoft, MSDN, SQL Azure, SQL Server, Visual Studio, Windows, and
Windows Azure are trademarks of the Microsoft group of companies. All
other trademarks are property of their respective owners.
v
What other readers are saying about this guide xvii
Foreword by Greg Young xxi
Preface xxiii
Why we created this guidance now xxiii
How is this guidance structured? xxiii
A CQRS journey xxiv
CQRS reference xxv
Tales from the trenches xxv
A CQRS journey xxv
CQRS reference xxvi
Tales from the trenches xxvi
Selecting the domain for the RI xxvi
Arrow legend xxvii
Where to go for more information xxviii
The Crew xxix
Journey 1: Our Domain: Conference Management System 1
The Contoso Corporation 1
Who is coming with us on the journey? 2
The Contoso Conference Management System 3
Overview of the system 3
Selling seats for a conference 4
Creating a conference 4
Nonfunctional requirements 4
Scalability 4
Flexibility 5
Beginning the journey 5
More information 5
Contents
vi
Journey 2: Decomposing the Domain 7
Definitions used in this chapter 7
Bounded contexts in the conference management system 8
Bounded contexts not included 9
The context map for the Contoso Conference Management
System 10
Why did we choose these bounded contexts? 11
More information 11
Journey 3: Orders and Registrations Bounded Context 13
A description of the bounded context 13
Working definitions for this chapter 14
Domain definitions (ubiquitous language) 15
Requirements for creating orders 17
Architecture 18
Patterns and concepts 18
Validation 23
Transaction boundaries 24
Concurrency 25
Aggregates and aggregate roots 25
Implementation details 25
High-level architecture 26
1. Querying the read model 27
2. Issuing commands 28
3. Handling commands 28
4. Initiating business logic in the domain 29
5. Persisting the changes 29
6. Polling the read model 29
Inside the write model 31
Aggregates 31
Aggregates and process managers 34
Infrastructure 40
Using the Windows Azure Service Bus 42
Delivering a command to a single recipient 44
Why have separate CommandBus and EventBus
classes? 48
How scalable is this approach? 48
How robust is this approach? 48
What is the granularity of a topic and a subscription? 48
How are commands and events serialized? 49
Impact on testing 49
Summary 52
More information 52
vii
Journey 4: Extending and Enhancing the Orders and
Registrations Bounded Context 53
Changes to the bounded context 53
Working definitions for this chapter 53
User stories 54
Implement a login using a record locator 54
Tell the registrant how much time remains to complete
an order 55
Enable a registrant to create an order that includes
multiple seat types 55
Architecture 55
Patterns and concepts 56
Record locators 56
Querying the read side 56
Storing denormalized views in a database 57
Making information about partially fulfilled orders
available to the read side 60
CQRS command validation 61
The countdown timer and the read model 62
Implementation details 62
The order access code record locator 63
The countdown timer 64
Using ASP.NET MVC validation for commands 66
Pushing changes to the read side 69
Querying the read side 72
Refactoring the SeatsAvailability aggregate 73
The AddSeats method 74
Impact on testing 74
Acceptance tests and the domain expert 74
Defining acceptance tests using SpecFlow features 74
Making the tests executable 76
Using tests to help developers understand message flows 81
A journey into code comprehension: A tale of pain, relief,
and learning 83
Testing is important 83
Domain tests 84
The other side of the coin 86
Summary 90
More information 90
Journey 5: Preparing for the V1 Release 91
The Contoso Conference Management System V1 release 91
Working definitions for this chapter 91
User stories 92
Ubiquitous language definitions 92
Conference Management bounded context user stories 92
Ordering and Registration bounded context user stories 92
viii
Architecture 93
Conference Management bounded context 97
Patterns and concepts 97
Event sourcing 97
Identifying aggregates 98
Task-based UI 99
CRUD 101
Integration between bounded contexts 101
Pushing changes from the Conference Management
bounded context 102
Pushing changes to the Conference Management
bounded context 104
Choosing when to update the read-side data 105
Distributed transactions and event sourcing 105
Autonomy versus authority 105
Favoring autonomy 106
Favoring authority 106
Choosing between autonomy and authority 106
Approaches to implementing the read side 107
Eventual consistency 107
Implementation details 108
The Conference Management bounded context 108
Integration with the Orders and Registration bounded
context 108
The Payments bounded context 109
Integration with online payment services, eventual
consistency, and command validation 111
Event sourcing 113
Raising events when the state of an aggregate changes 113
Persisting events to the event store 117
Replaying events to rebuild state 118
Issues with the simple event store implementation 120
Windows Azure table storage-based event store 120
Calculating totals 122
Impact on testing 123
Timing issues 123
Involving the domain expert 123
Summary 124
More information 124
Journey 6: Versioning Our System 125
Working definitions for this chapter 125
User stories 126
No down time upgrade 126
Display remaining seat quantities 126
Handle zero-cost seats 126
Architecture 126
ix
Patterns and concepts 127
Handling changes to events definitions 128
Mapping/filtering event messages in the infrastructure 128
Handling multiple message versions in the aggregates 128
Honoring message idempotency 128
Avoid processing events multiple times 129
Persisting integration events 131
Message ordering 133
Implementation details 133
Adding support for zero-cost orders 134
Changes to the RegistrationProcessManager class 134
Changes to the UI 134
Data migration 136
Displaying remaining seats in the UI 138
Adding information about remaining seat quantities
to the read model 138
Modifying the UI to display remaining seat quantities 140
Data migration 140
De-duplicating command messages 141
Guaranteeing message ordering 142
Persisting events from the Conference Management
bounded context 146
Adding additional metadata to the messages 146
Capturing and persisting messages to the message log 146
Data migration 148
Migrating from V1 to V2 150
Generating past log messages for the Conference
Management bounded context 151
Migrating the event sourcing events 151
Rebuilding the read models 151
Impact on testing 151
SpecFlow revisited 152
Discovering a bug during the migration 155
Summary 155
More information 155
Journey 7: Adding Resilience and Optimizing Performance 157
Working definitions for this chapter 157
Architecture 158
Adding resilience 159
Making the system resilient when an event is reprocessed 161
Ensuring that commands are always sent 161
Optimizing performance 162
UI flow before optimization 162
Optimizing the UI 163
UI optimization 1 164
UI optimization 2 165
x
Optimizing the infrastructure 165
Sending and receiving commands and events
asynchronously 165
Optimizing command processing 166
Using snapshots with event sourcing 166
Publishing events in parallel 167
Filtering messages in subscriptions 167
Creating a dedicated receiver for the SeatsAvailability
aggregate 167
Caching conference information 167
Partitioning the Service Bus 168
Other optimizations 168
Further changes that would improve performance 169
Further changes that would enhance scalability 171
No down-time migration 172
Rebuilding the read models 173
Implementation details 174
Hardening the RegistrationProcessManager class 174
Detecting out-of-order SeatsReserved events 175
Detecting duplicate OrderPlaced events 178
Creating a pseudo transaction when the
RegistrationProcessManager class saves its state
and sends a command 178
Optimizing the UI flow 181
Receiving, completing, and sending messages
asynchronously 186
Receiving messages asynchronously 186
Completing messages asynchronously 186
Sending messages asynchronously 186
Handling commands synchronously and in-process 186
Implementing snapshots with the memento pattern 189
Publishing events in parallel 191
Filtering messages in subscriptions 192
Creating a dedicated SessionSubscriptionReceiver
instance for the SeatsAvailability aggregate 193
Caching read-model data 194
Using multiple topics to partition the service bus 195
Other optimizing and hardening changes 196
Sequential GUIDs 196
Asynchronous ASP.NET MVC controllers. 198
Using prefetch with Windows Azure Service Bus 198
Accepting multiple sessions in parallel 199
Adding an optimistic concurrency check 199
Adding a time-to-live value to the
MakeSeatReservation command 199
Reducing the number of round-trips to the database 199
xi
Impact on testing 200
Integration tests 200
User interface tests 200
Summary 200
More information 200
Journey 8: Epilogue: Lessons Learned 201
What did we learn? 201
Performance matters 201
Implementing a message-driven system is far from simple 202
The cloud has challenges 203
CQRS is different 204
Event sourcing and transaction logging 205
Involving the domain expert 206
When to use CQRS 206
What would we do differently if we started over? 207
Start with a solid infrastructure for messaging and
persistence 207
Leverage the capabilities of the infrastructure more 207
Adopt a more systematic approach to implementing
process managers 208
Partition the application differently 208
Organize the development team differently 208
Evaluate how appropriate the domain and the bounded
contexts are for the CQRS pattern 208
Plan for performance 208
Think about the UI differently 209
Explore some additional benefits of event sourcing 209
Explore the issues associated with integrating bounded
contexts 210
More information 210
Reference 1: CQRS in Context 211
What is domain-driven design? 212
Domain-driven design: concepts and terminology 212
Domain model 213
Ubiquitous language 213
Entities, value objects, and services 214
Aggregates and aggregate roots 215
Bounded contexts 215
Anti-corruption layers 217
Context maps 218
Bounded contexts and multiple architectures 218
Bounded contexts and multiple development teams 219
Maintaining multiple bounded contexts 220
CQRS and DDD 220
More information 221
xii
Reference 2: Introducing the Command Query
Responsibility Segregation Pattern 223
What is CQRS? 223
Read and write sides 225
CQRS and domain-driven design 227
Introducing commands, events, and messages 228
Why should I use CQRS? 230
Scalability 230
Reduced complexity 231
Flexibility 231
Focus on the business 232
Facilitates building task-based UIs 232
Barriers to adopting the CQRS pattern 232
When should I use CQRS? 232
Collaborative domains 233
Stale data 233
Moving to the cloud 234
When should I avoid CQRS? 234
Summary 234
More information 234
Reference 3: Introducing Event Sourcing 235
What is event sourcing? 236
Comparing using an ORM layer with event sourcing 236
Why should I use event sourcing? 240
Event sourcing concerns 242
CQRS/ES 243
Standalone event sourcing 245
Event stores 245
Basic requirements 245
Underlying storage 245
Performance, scalability, and consistency 245
More information 246
Reference 4: A CQRS and ES Deep Dive 247
Introduction 247
Read models and write models 247
Commands and data transfer objects 247
Domain-driven design (DDD) and aggregates 248
Data and normalization 248
Events and event sourcing 248
Eventual consistency 248
Defining aggregates in the domain model 249
Aggregates and object-relational mapping layers 249
Aggregates and event sourcing 250
xiii
Commands and command handlers 252
Commands 253
Example code 253
Command handlers 254
Commands and optimistic concurrency 256
Events and event handlers 256
Events and intent 256
How to model intent 258
Events 259
Sample Code 259
Event handlers 260
Sample code 260
Embracing eventual consistency 261
Eventual consistency and CQRS 263
Optimizing the read-side 266
Optimizing the write side 267
Concurrency and aggregates 267
Messaging and CQRS 268
Messaging considerations 268
Duplicate messages 268
Lost messages 269
Out-of-order messages 269
Unprocessed messages 269
Event versioning 269
Redundant events 270
New event types 270
Changing existing event definitions 270
Task-based UIs 271
Taking advantage of Windows Azure 272
Scaling out using multiple role instances 273
Implementing an event store using Windows Azure
table storage 273
Persisting events 274
Retrieving events 275
Publishing events 276
Implementing a messaging infrastructure using
the Windows Azure Service Bus 278
A word of warning 279
More information 279
Reference 5: Communicating Between Bounded Contexts 281
Introduction 281
Context maps 281
The anti-corruption layer 281
xiv
Integration with legacy systems 282
Reading the database 282
Generating events from the database 282
Modifying the legacy systems 282
Implications for event sourcing 282
More information 283
Reference 6: A Saga on Sagas 285
Clarifying the terminology 285
Process Manager 286
Messages and CQRS 286
What is a process manager? 286
When should I use a process manager? 290
When should I not use a process manager? 290
Sagas and CQRS 290
More information 290
Reference 7: Technologies Used in the Reference
Implementation 291
Windows Azure Service Bus 291
Queues 292
Topics and Subscriptions 293
Useful API features 294
Reading messages 294
Sending messages 294
Expiring messages 294
Delayed message processing 294
Serializing messages 295
Further information 295
Unity Application Block 296
Further information 296
More information 296
Tales from the Trenches 297
Twilio 297
Product overview 297
Lessons learned 297
Separating reads and writes 297
Designing for high availability 297
Idempotency 298
No-downtime deployments 298
Performance 298
References 299
More information 299
xv
Tales from the Trenches: Lokad Hub 300
Project overview 300
Lessons learned 300
Benefits of DDD 301
Reducing dependencies 301
Using sagas 301
Testing and documentation 301
Migration to ES 301
Using projections 301
Event sourcing 301
Infrastructure 302
References 302
More information 302
Tales from the Trenches: DDD/CQRS for large financial
company 303
Project overview 303
Lessons learned 304
Query performance 304
Commands 304
Working with legacy databases 304
Using an Inversion of Control (IoC) container 304
Key lessons learned 305
More information 305
Tales from the Trenches: Digital Marketing 306
Single Responsibility of Objects 309
More information 309
Tales from the Trenches: TOPAZ Technologies 310
What did we hope to accomplish by using CQRS/ES? 310
What were the biggest challenges and how did we
overcome them? 310
What were the most important lessons learned? 311
With hindsight, what would we have done differently? 311
Further information 311
More information 311
Tales from the Trenches: eMoney Nexus 312
eMoney Nexus: Some CQRS lessons 312
About eMoney & the Nexus 312
System overview 313
The evolution of the system 314
Lessons learned 320
Making it better 321
xvi
Appendix 1: Release Notes 323
System evolution 323
Building and running the sample code (RI) 323
Prerequisites 324
Obtaining the code 325
Creating the databases 325
SQL Express Database 325
Windows Azure SQL Database instance 325
Creating the Settings.xml File 327
Building the RI 327
Build Configurations 328
Release 328
Debug 328
DebugLocal 328
Running the RI 328
Scenario 1. Local Web Server, SQL Event Bus,
SQL Event Store 328
Scenario 2. Local Web Server, Windows Azure
Service Bus, Table Storage Event Store 329
Scenario 3. Compute Emulator, SQL Event Bus,
SQL Event Store 329
Scenario 4. Compute Emulator, Windows Azure
Service Bus, Table Storage Event Store 329
Scenario 5. Windows Azure, Windows Azure
Service Bus, Table Storage Event Store 329
Running the Tests 329
Running the Unit and Integration Tests 329
Running the Acceptance Tests 330
Known issues 330
More information 330
Appendix 2: Migrations 331
Migrating from the V1 to the V2 release 331
Running the migration program to migrate the data 331
If the data migration fails 332
Migrating from the V2 to the V3 Release 333
More information 333
Index 335
xvii
This is another excellent guide from the patterns & practices team—real software engineering with
no comforting illusions taken or offered. This guide provides a detailed journal of the practitioners
implementing a real production system using the CQRS and Event Sourcing patterns, and also high-
lights the tradeoffs and teaches the principles that underlie them. The topics presented are relevant
and useful, especially if you are building highly scalable Windows Azure applications. You’ll be both
challenged and inspired!
—Scott Guthrie, Corporate Vice-President, Azure App Platform, Microsoft
Having participated and co-authored various guides from patterns & practices, the “CQRS Journey”
follows the same walkthrough, scenario-based style, but adding even more fresh empirical content.
It’s a true testament of a skilled development team without previous CQRS experience, going through
the journey of implementing a complex system and documenting their adventures and lessons learnt
in this diary. If I had to recommend to someone where to start with CQRS, I would definitely point
them to this guide.
—Matias Woloski, CTO, Auth10 LLC
The “CQRS Journey” guide is an excellent resource for developers who want to begin developing a
CQRS system or convert their current system. It’s a true “trial by fire” approach to the concepts and
implementation hurdles that a team would encounter when adopting CQRS. I would recommend
reading it twice as I picked up even more lessons the second time through.
—Dan Piessens, Lead Software Architect, Zywave
I think it’s a really big step in communication with the developer community. You not only share your
development experience with a broad audience (which is very valuable by itself) but you’re also open
for learning from the community. While working on real projects it’s difficult to stop, find some time
to structure your knowledge, prepare it in the form understandable for others. It’s very cool that you
found time and resources for such educational effort, I really appreciate this.
—Ksenia Mukhortova, Business Applications Developer, Intel
I’m very excited about A CQRS Journey for a number of reasons. It explores, with an even hand and a
fair mind, a topic where opinions are both diverse and numerous. True to its name, the guide captures
the progression of learning. Conclusions are not simply stated; they arrive as a result of experience.
Additionally, the project embraced a passionate community with a spirit of inclusion and transparency.
The result is friendly-to-read guidance that is both diligent in execution and rigorous in its research.
—Christopher Bennage, Software Development Engineer, Microsoft
What other readers are
saying about this guide
xviii
The journey project used Windows Azure SQL Database (backing write & read models), Service Bus
(for reliable messaging), and Tables (for event store). Production-quality, scalable cloud services that
can be provisioned on-demand with a few mouse-clicks (or API calls) can turn some tough infrastruc-
ture problems into trivial ones.
—Bill Wilder, MVP, Independent Consultant
Perhaps the best lessons out of this guidance will be just how easy it is to work with Microsoft now
that they are embracing more community and open source.
—Adam Dymitruk, Systems Architect
The work that patterns & practices is doing here is very important as it is packaging the concepts in
a digestible fashion and helping developers to wade through the ambiguities of CQRS. The real world
experiences captured within the journey project will be invaluable to folks looking at applying CQRS
within their application development”
—Glenn Block, Senior Program Manager, Microsoft, Windows Azure SDK for Node.js,
Organizer at ALT.NET Seattle Chapter
The p&p team’s dedication and hard work go hand-in-hand with the very high level of competency
present on the team. Their attention to detail, insistence on clarity, and open collaboration with the
community all led to the creation of material representing enormous value to consumers of the guid-
ance. I definitely plan on referencing this material and code in future engagements because I think my
clients will derive many benefits from it–a win-win for everyone!
—Josh Elster, Principal, Liquid Electron
CQRS is a very important pattern, and a tool that any cloud developer should have in his or her tool-
belt. It is particularly well-suited for the cloud since it allows for the implementation of massively
scalable solutions based on simple, common patterns (like queues, event handlers, and view models,
to name a few). Like all patterns, there are several concrete, correct ways of implementing CQRS. A
journey of the type undertaken by Microsoft’s patterns & practices team is a great way to explore the
different options, tradeoffs, and even possible mistakes one can make along the way, and accelerate
one’s learning of the CQRS pattern.
—Shy Cohen, Principal, Shy Cohen Consulting
patterns & practices assembled many of the active and key people in the CQRS community to join
them on the their journey with CQRS and along the way discovered confusing terminology and con-
cepts that created opportunities for leaders in the community to bring clarity to a broad audience.
The material produced is influenced from the results of building a real world application and ex-
presses the experiences from advisors and the patterns & practices team during the development
process. By request from the community to allow outside contributions, everything has been open
sourced on GitHub. Anyone interested is encouraged to take a look at the guide or implementation.
The patterns & practices team has been very welcoming to anyone who wants to collaborate on
covering additional areas, alternative implementations or further extending what is currently in place.
—Kelly Sommers, Developer
xix
Congratulations on getting to what looks to be nice guidance. I know that the announcement that
p&p was going to embark on this project caused a twitter firestorm but you seem to have come
through it well. I’m a fan of the p&p books and think you’ve done a great job in sharing good prac-
tices with the community.
—Neil Mackenzie, Windows Azure MVP
CQRS is as much about architecture community as it is about concrete patterns—thus the project is
aptly named “CQRS Journey.” The community involvement and engagement in this project is unprec-
edented for Microsoft and reflects the enthusiasm amongst the many (if may say: young) software
architects from across the industry who are rediscovering proven architecture patterns and are recom-
posing them in new ways to solve today’s challenges. For me, one takeaway from this project is that
the recipes developed here need to be carefully weighed against their alternatives. As with any soft-
ware architecture approaches that promise easy scalability or evolvability of solutions, the proof will
be in concrete, larger production implementations and how they hold up to changing needs over time.
Thus, the results of this Journey project mark a start and not a finish line.
—Clemens Vasters, Principal Technical Lead, Microsoft Corporation
The experiences and conclusions of the p&p team match up very well with our own real-world expe-
riences. Their conclusions in Chapter 8 are spot on. One of the best aspects of this guidance is that
the p&p team exposes more of their thought processes and learning throughout the Journey than
most write-ups that you may read. From arguments between Developer 1 and Developer 2 on the
team, to discussions with experts such as Greg Young and Udi Dahan, to an excellent post-project
review in Chapter 8, the thought process is out there for you to learn from.
Thanks for this great work, guys. I hope you keep this style with your upcoming guidance pieces.
—Jon Wagner, SVP & Chief Architect, eMoney Advisor
The CQRS journey release by patterns & practices provides real world insight into the increasingly
popular CQRS pattern used in distributed systems that rely upon asynchronous, message based ap-
proaches to achieve very large scale. The exploration of the issues the team faced throughout the
implementation of the pattern is extremely useful for organizations considering CQRS, both to de-
termine where the pattern is appropriate for them, and to go into the design and implementation with
a baseline understanding of the complexity it will introduce. I really enjoyed the candor around the
approach taken, the issues encountered, and the early design choices that the team would change in
hindsight. This is a must read for any organization embarking upon CQRS, regardless of what platform
they are using.
—Chris Keyser, VP Engineering, CaseNetwork
It is a great resource on tactical and technical aspects of building a distributed system.
—Rinat Abdullin, Technology Leader, Lokad
I’d like to personally thank the team for putting together such a transparent journey throughout this
project. I’m very pleased with the final release.
—Truong Nguyen, CEO, Nepsoft
It’s a good read. Lots to learn from it.
—Christian Horsdal Gammelgaard, Lead Software Architect, Mjølner Informatics
Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts
Foreword by Greg Young
I started off the new year on January 3rd with a few hour long meeting showing the team at patterns
& practices a bit about Command and Query Responsibility Segregation (CQRS) and Event Sourcing
(ES). Most of the team had previously not been exposed to these ideas. Today is almost exactly six
months later and they have produced a document of over 200 pages of discussions and guidance as
well as a full end to end example hosted in Windows Azure. This is certainly not a small feat.
When the announcement of the project came out, the twitter stream near instantly went nega-
tive as many thought that Microsoft was building a CQRS framework; which was premature from the
community. The process followed similar paths to other patterns & practices projects with a large
advisor board being set up. I believe however that the most interesting part of the process was the
decision to host the work on GitHub and allow pull requests which is an extremely open and transpar-
ent way of communicating during the project.
One of the main benefits for the community as a whole of going through such a process is that
people were forced to refine their vocabularies. There are in the DDD/CQRS/ES communities many
different voices and often times, especially in younger groups, vocabularies will go down divergent paths
leading to fractured community. An example of nebulous terminologies can be seen in the terms ”saga,”
”process manager,” and ”workflow”; the community as a whole I believe benefited from the discussions
over defining what it actually is. One of the most interesting conversations brought up for me person-
ally was defining the difference between an Event Store and a Transaction Log as legitimate arguments
can be made that either is a higher level abstraction of the other. This has led not only to many interest-
ing discussions in the community but to a far stricter future definition of what an Event Store is.
”For the things we have to learn before we can do them, we learn by doing them. ~Aristotle”
The quote above was the team motto during the project. Many will be looking towards the guidance
presented as being authoritative guidance of how things should be done. This is however not the
optimal way to look at the guidance as presented (though it does contain many bits of good authori-
tative guidance). The main benefit of the guidance is the learning experience that it contains. It is
important to remember that the team came into the ideas presented as non-experienced in CQRS
and they learned in the process of doing. This gives a unique perspective throughout much of the text
where things are learned along the way or are being seen through fresh eyes of someone recently
having learned and attempted to apply the ideas. This perspective has also brought up many interest-
ing conversations within the community. The patterns & practices team deserves credit for digging
deep, facilitating these discussions, and bringing to light various incongruities, confusions and incon-
sistencies as they went along.
xxi
xxii
Keeping in mind the origination point of the team, the most valuable bits in the text that a
reader should focus on aside from general explanations are places where tradeoffs are discussed.
There is an unfortunate tendency to seek authoritative answers that ”things should be done in this
way” when they in fact do not exist. There are many ways to proverbially skin a cat and all have their
pros and cons. The text is quite good at discussing alternative points of view that came up as possible
answers, or that received heavy discussion within the advisor group, these can often be seen in the
“developer 1/developer 2 discussions.” One such discussion I mentioned previously in defining the
difference between event sourcing and a transaction log. Many of these types of discussions come at
the end of the guidance.
How might things be approached differently? One of my favourite discussions towards the end
of the guidance dealing with performance is the independent realization that messaging is not
equivalent to distribution. This is a very hard lesson for many people to understand and the way that
it comes up rather organically and much like it would on most teams as a performance problem is a
great explanation. I can say 100 times to apply the first law of distributed computing, don’t distribute;
however seeing it from the eyes of a team dealing with a performance problem who has already made
the mistake of equating the two is a very understandable path and a great teaching tool. This section
also contains a smörgåsbord of information and insights in terms of how to build performant applica-
tions in Windows Azure.
Out in the wild, there are plenty of naïve samples of CQRS/ES implementations, which are great
for describing the concepts. There are details and challenges that will not surface till you work on a
complex, real-world production system. The value of the p&p’s sample application is that it uses a
fairly complex domain and the team went through multiple releases and focused on infrastructure
hardening, performance optimizations, dealing with transient faults and versioning, etc. — many
practical issues that you face when implementing CQRS and ES.
As with any project, people may disagree with implementation choices and decisions made. It is
important to remember the scoping of the project. The guidance is not coming from an expert view-
point throughout the process, but that of a group “learning by doing.” The process was and remains
open to contributions, and in fact this version has been reviewed, validated, and guided by experts in
the community. In the spirit of OSS “send a pull request.” This guide can serve as a valuable point to
start discussions, clear up misconceptions, and refine how we explain things, as well as drive improve-
ment both in the guidance itself and in getting consistent viewpoints throughout the community.
In conclusion I think patterns & practices has delivered to the community a valuable service in the
presentation of this guidance. The view point the guidance is written from is both an uncommon and
valuable one. It has also really been a good overall exercise for the community in terms of setting the
bar for what is being discussed and refining of the vocabularies that people speak in. Combine this
with the amount of previously difficult to find Windows Azure guidance and the guidance becomes
quite valuable to someone getting into the ideas.
Greg Young
Preface
Why are we embarking on this journey?
“The best way to observe a fish is to become a fish.”
Jacques Cousteau
Why we created this guidance now
The Command Query Responsibility Segregation (CQRS) pattern and event sourcing (ES) are cur-
rently generating a great deal of interest from developers and architects who are designing and build-
ing large-scale, distributed systems. There are conference sessions, blogs, articles, and frameworks all
dedicated to the CQRS pattern and to event sourcing, and all explaining how they can help you to
improve the maintainability, testability, scalability, and flexibility of your systems.
However, like anything new, it takes some time before a pattern, approach, or methodology is
fully understood and consistently defined by the community and has useful, practical guidance to help
you to apply or implement it.
This guidance is designed to help you get started with the CQRS pattern and event sourcing. It is
not intended to be the guide to the CQRS pattern and event sourcing, but a guide that describes the
experiences of a development team in implementing the CQRS pattern and event sourcing in a real-
world application. The development team did not work in isolation; they actively sought input from
industry experts and from a wider group of advisors to ensure that the guidance is both detailed and
practical.
The CQRS pattern and event sourcing are not mere simplistic solutions to the problems associ-
ated with large-scale, distributed systems. By providing you with both a working application and
written guidance, we expect you’ll be well prepared to embark on your own CQRS journey.
How is this guidance structured?
There are two closely related parts to this guidance:
• A working reference implementation (RI) sample, which is intended to illustrate many of the
concepts related to the CQRS pattern and event sourcing approaches to developing complex
enterprise applications.
• This written guidance, which is intended to complement the RI by describing how it works,
what decisions were made during its development, and what trade-offs were considered.
xxiii
xxiv
This written guidance is itself split into three distinct sections that you can read independently: a
description of the journey we took as we learned about CQRS, a collection of CQRS reference ma-
terials, and a collection of case studies that describe the experiences other teams have had with the
CQRS pattern. The map in Figure 1 illustrates the relationship between the first two sections: a
journey with some defined stopping points that enables us to explore a space.
Figure 1
A CQRS journey
A CQRS journey
This section is closely related to the RI and the chapters follow the chronology of the project to de-
velop the RI. Each chapter describes relevant features of the domain model, infrastructure elements,
architecture, and user interface (UI) that the team was concerned with during that phase of the
project. Some parts of the system are discussed in several chapters, and this reflects the fact that the
team revisited certain areas during later stages. Each of these chapters discuss how and why particu-
lar CQRS patterns and concepts apply to the design and development of particular bounded contexts,
describe the implementation, and highlight any implications for testing.
xxv
Other chapters look at the big picture. For example, there is a chapter that explains the rationale
for splitting the RI into the bounded contexts we chose, another chapter analyzes the implications of
our approach for versioning the system, and other chapters look at how the different bounded con-
texts in the RI communicate with each other.
This section describes our journey as we learned about CQRS, and how we applied that learn-
ing to the design and implementation of the RI. It is not prescriptive guidance and is not intended
to illustrate the only way to apply the CQRS approach to our RI. We have tried wherever possible
to capture alternative viewpoints through consultation with our advisors and to explain why we
made particular decisions. You may disagree with some of those decisions; please let us know at
cqrsjourney@microsoft.com.
This section of the written guidance makes frequent cross-references to the material in the sec-
ond section for readers who wish to explore any of the concepts or patterns in more detail.
CQRS reference
The second section of the written guidance is a collection of reference material collated from many
sources. It is not the definitive collection, but should contain enough material to help you to under-
stand the core patterns, concepts, and language of CQRS.
Tales from the trenches
This section of the written guidance is a collection of case studies from other teams that describe
their experiences of implementing the CQRS pattern and event sourcing in the real world. These case
studies are not as detailed as the journey section of the guidance and are intended to give an overview
of these projects and to summarize some of the key lessons learned.
The following is a list of the chapters that comprise both sections of the written guidance:
A CQRS journey
• Chapter 1, “The Contoso Conference Management System,” introduces our sample applica-
tion and our team of (fictional) experts.
• Chapter 2, “Decomposing the Domain,” provides a high-level view of the sample application
and describes the bounded contexts that make up the application.
• Chapter 3, “Orders and Registrations Bounded Context,” introduces our first bounded
context, explores some CQRS concepts, and describes some elements of our infrastructure.
• Chapter 4, “Extending and Enhancing the Orders and Registrations Bounded Context,”
describes adding new features to the bounded context and discusses our testing approach.
• Chapter 5, “Preparing for the V1 Release,” describes adding two new bounded contexts and
handling integration issues between them, and introduces our event-sourcing implementa-
tion. This is our first pseudo-production release.
• Chapter 6, “Versioning Our System,” discusses how to version the system and handle
upgrades with minimal down time.
• Chapter 7, “Adding Resilience and Optimizing Performance,” describes what we did to make
the system more resilient to failure scenarios and how we optimized the performance of the
system. This was the last release of the system in our journey.
• Chapter 8, “Lessons Learned,” collects the key lessons we learned from our journey and
suggests how you might continue the journey.
xxvi
CQRS reference
• Chapter 1, “CQRS in Context,” provides some context for CQRS, especially in relation to the
domain-driven design approach.
• Chapter 2, “Introducing the Command Query Responsibility Segregation Pattern,” provides a
conceptual overview of the CQRS pattern.
• Chapter 3, “Introducing Event Sourcing,” provides a conceptual overview of event sourcing.
• Chapter 4, “A CQRS and ES Deep Dive,” describes the CQRS pattern and event sourcing in
more depth.
• Chapter 5, “Communicating between Bounded Contexts,” describes some options for
communicating between bounded contexts.
• Chapter 6, “A Saga on Sagas,” explains our choice of terminology: process manager instead of
saga. It also describes the role of process managers.
• Chapter 7, “Technologies Used in the Reference Implementation,” provides a brief overview
of some of the other technologies we used, such as the Windows Azure Service Bus.
• Appendix 1, “Release Notes,” contains detailed instructions for downloading, building, and
running the sample application and test suites.
• Appendix 2, “Migrations,” contains instructions for performing the code and data migrations
between the pseudo-production releases of the Contoso Conference Management System.
Tales from the trenches
• Chapter 1, “Twilio,” describes a highly available, cloud-hosted, communications platform.
Although the team who developed this product did not explicitly use CQRS, many of the
architectural concepts they adopted are very closely related to the CQRS pattern.
• Chapter 2, “Lokad Hub,” describes a project that made full use of domain-driven design,
CQRS, and event sourcing in an application designed to run on multiple cloud platforms.
• Chapter 3, “DDD/CQRS for large financial company,” describes a project that made full use
of domain-driven design and CQRS to build a reference application for a large financial
company. It used CQRS to specifically address the issues of performance, scalability, and
reliability.
• Chapter 4, “Digital Marketing,” describes how an existing application was refactored over
time while delivering new features. This project adopted the CQRS pattern for one of its
pieces as the project progressed.
• Chapter 5, “TOPAZ Technologies,” describes a project that used the CQRS pattern and
event sourcing to simplify the development of an off-the-shelf enterprise application.
• Chapter 6, “eMoney Nexus,” describes migration project for an application that used legacy
three-tier architecture to an architecture that used the CQRS pattern and event sourcing.
Many of the conclusions drawn in this project are similar to our own experiences on our
CQRS journey.
Selecting the domain for the RI
Before embarking on our journey, we needed to have an outline of the route we planned to take and
an idea of what the final destination should be. We needed to select an appropriate domain for the RI.
We engaged with the community and our advisory board to help us choose a domain that would
enable us to highlight as many of the features and concepts of CQRS as possible. To help us select be-
tween our candidate domains, we used the criteria in the following list. The domain selected should be:
xxvii
• Non-trivial. The domain must be complex enough to exhibit real problems, but at the same
time simple enough for most people to understand without weeks of study. The problems
should involve dealing with temporal data, stale data, receiving out-of-order events, and
versioning. The domain should enable us to illustrate solutions using event sourcing, sagas, and
event merging.
• Collaborative. The domain must contain collaborative elements where multiple actors can
operate simultaneously on shared data.
• End to end. We wanted to be able illustrate the concepts and patterns in action from the
back-end data store through to the user interface. This might include disconnected mobile and
smart clients.
• Cloud friendly. We wanted to have the option of hosting parts of the RI on Windows Azure
and be able to illustrate how you can use CQRS for cloud-hosted applications.
• Large. We wanted to be able to show how our domain can be broken down into multiple
bounded contexts to highlight when to use and when not use CQRS. We also wanted to
illustrate how multiple architectural approaches (CQRS, CQRS/ES, and CRUD) and legacy
systems can co-exist within the same domain. We also wanted to show how multiple develop-
ment teams could carry out work in parallel.
• Easily deployable. The RI needed to be easily deployable so that you can install it and experi-
ment with it as you read this guidance.
As a result, we chose to implement the conference management system that Chapter 1, “Our Domain:
The Contoso Conference Management System,” introduces.
Arrow legend
Many illustrations in the guidance have arrows. Here is their associated meaning.
Figure 2
Legend for arrows
Event message
Command message
Method call
Flow of data
Object relationship
xxviii
Where to go for more information
There are a number of resources listed in text throughout the book. These resources will provide
additional background, bring you up to speed on various technologies, and so forth. For your conve-
nience, there is a bibliography online that contains all the links so that these resources are just a click
away.
You can find the bibliography on MSDN at: http://msdn.microsoft.com/en-us/library/jj619274.
xxix
The Crew
Captain Ernest Shackleton’s Antarctic expedition recruitment ad (1913) stated:
No fewer than 5000 people replied…
When we embarked on our journey half a
year ago, it felt almost the same. With no
fewer than 70 community members (both ex-
perts and enthusiastic novices) answering the
call for advisory board and offering to volun-
teer their time to help us steer this project!
We have now reached the end of the
journey. These are the members of the devel-
opment team who endured the challenges of
the journey and produced this guide:
Vision and Program Management Grigori Melnik (Microsoft Corporation)
Development Julián Domínguez (Microsoft Corporation), Daniel Cazzulino and Fernando Simon-
azzi (Clarius Consulting)
Testing Mani Subramanian (Microsoft Corporation), Hernan de Lahitte (Digit Factory), and Rathi
Velusamy (Infosys Technologies Ltd.)
Documentation Dominic Betts (Content Master Ltd.), Julián Domínguez, Grigori Melnik, and Mani
Subramanian (Microsoft Corporation), and Fernando Simonazzi (Clarius Consulting)
Graphic Design Alexander Ustinov and Anton Rusecki (JetStyle)
Editing and Production RoAnn Corbisier and Nelly Delgado (Microsoft Corporation), Nancy Mi-
chell (Content Master Ltd.), and Chris Burns (Linda Werner & Associates Inc)
The development team didn’t embark on this journey by themselves and didn’t work in isolation.
We actively sought input from industry experts and from a wider group of advisors to ensure that the
guidance is detailed, practical, and informed by real-world experience. We would like to thank our
advisory board members and the DDD/CQRS community members in general who have accompanied
us on this journey for their active participation, insights, critiques, challenges, and reviews. We have
learned and unlearned many things, we’ve explored and experimented a lot. The journey wasn’t easy
but it was so worth it and we enjoyed it. Thank you for keeping us grounded in the real-world chal-
lenges. Thank you for your ongoing support of our effort. We hope the community will continue
exploring the space, pushing the state of the practice further, and extending the reference implemen-
tation and the guidance.
xxx
Specifically, we’d like to acknowledge the following people who have contributed to the journey
in many different ways:
• Greg Young for your pragmatism, patience with us, continuous mentoring and irreplaceable
advice;
• Udi Dahan for challenging us and offering alternative views on many concepts;
• Clemens Vasters for pushing back on terminology and providing a very valuable perspective from
the distributed database field;
• Kelly Sommers for believing in us and bringing sanity to the community as well as for deep
technical insights;
• Adam Dymitruk for jumpstarting us on git and extending the RI;
• Glenn Block for encouraging us to go all the way with the OSS initiative and for introducing us
to many community members;
• Our GM Lori Brownell and our director Björn Rettig for providing sponsorship of the initiative
and believing in our vision;
• Scott Guthrie for supporting the project and helping amplify the message;
• Josh Elster for exploring and designing the MIL (Messaging Intermediate Language) and pushing
us to make it easier to follow the workflow of messages in code;
• Cesar De la Torre Llorente for helping us spike on the alternatives and bringing up terminological
incongruities between various schools and thought leaders;
• Rinat Abdullin for active participation at the beginning of the project and contributing a case
study;
• Bruno Terkaly and Ricardo Villalobos for exploring the disconnected client scenario that would
integrate with the RI;
• Einar Otto Stangvik for spiking on the Schedule Builder bounded context implementation in
Node.js;
• Mark Seemann for sending the very first pull request focusing on code quality;
• Christopher Bennage for helping us overcome GitHub limitations by creating the pundit review
system and the export-to-Excel script to manage iteration backlog more effectively;
• Bob Brumfield, Eugenio Pace, Carlos Farre, Hanz Zhang, and Rohit Sharma for many insights
especially on the perf and hardening challenges;
• Chris Tavares for putting out the first CQRS experiment at p&p and suggesting valuable scenarios;
• Tim Sharkinian for your perspectives on CQRS and for getting us on the SpecFlow train;
• Jane Sinyagina for helping solicit and process feedback from the advisors;
• Howard Wooten and Thomas Petchel for feedback on the UI style and usability;
• Kelly Leahy for sharing your experience and making us aware of potential pitfalls;
• Dylan Smith for early conversations and support of this project in pre-flight times;
• Evan Cooke, Tim Walton, Alex Dubinkov, Scott Brown, Jon Wagner, and Gabriel N. Schenker for
sharing your experiences and contributing mini-case studies.
We feel honored to be supported by such an incredible group of people.
Thank you!
1
“I am prepared to go anywhere, provided it be forward.”
David Livingstone
This chapter introduces a fictitious company named Contoso. It describes Contoso’s plans to launch
the Contoso Conference Management System, a new online service that will enable other companies
or individuals to organize and manage their own conferences and events. This chapter describes, at a
high-level, some of the functional and non-functional requirements of the new system, and why
Contoso wants to implement parts of it using the Command Query Responsibility Segregation
(CQRS) pattern and event sourcing (ES). As with any company considering this process, there are
many issues to consider and challenges to be met, particularly because this is the first time Contoso
has used both the CQRS pattern and event sourcing. The chapters that follow show, step by step,
how Contoso designed and built its conference management application.
This chapter also introduces a panel of fictional experts to comment on the development efforts.
The Contoso Corporation
Contoso is a startup ISV company of approximately 20 employees that specializes in developing solu-
tions using Microsoft technologies. The developers at Contoso are knowledgeable about various
Microsoft products and technologies, including the .NET Framework, ASP.NET MVC, and Windows
Azure. Some of the developers have previous experience using the domain-driven design (DDD) ap-
proach, but none of them have used the CQRS pattern previously.
The Conference Management System application is one of the first innovative online services that
Contoso wants to take to market. As a startup, Contoso wants to develop and launch these services
with a minimal investment in hardware and IT personnel. Contoso wants to be quick to market in
order to start growing market share, and cannot afford the time to implement all of the planned
functionality in the first releases. Therefore, it is important that the architecture it adopts can easily
accommodate changes and enhancements with minimal impact on existing users of the system. Con-
toso has chosen to deploy the application on Windows Azure in order to take advantage of its ability
to scale applications as demand grows.
Our Domain:
Conference Management System
The starting point: Where have we come from,
what are we taking, and who is coming with us?
Journey 1:
2 Journey one
Who is coming with us on the journey?
As mentioned earlier, this guide and the accompanying RI describe a CQRS journey. A panel of experts
will comment on our development efforts as we go. This panel includes a CQRS expert, a software
architect, a developer, a domain expert, an IT Pro, and a business manager. They will all comment from
their own perspectives.
Gary is a CQRS expert. He ensures that a CQRS-based solution will
work for a company and will provide tangible benefits. He is a
cautious person, for good reason.
“Defining the CQRS pattern is easy. Realizing the benefits that implementing the
CQRS pattern can offer is not always so straightforward.”
Jana is a software architect. She plans the overall structure of an
application. Her perspective is both practical and strategic. In other
words, she considers not only what technical approaches are needed
today, but also what direction a company needs to consider for the future.
Jana has worked on projects that used the domain-driven design approach.
“It’s not easy to balance the needs of the company, the users, the IT organization, the
developers, and the technical platforms we rely on.”
Markus is a software developer who is new to the CQRS pattern. He is
analytical, detail-oriented, and methodical. He’s focused on the task at
hand, which is building a great application. He knows that he’s the
person who’s ultimately responsible for the code.
“I don’t care what architecture you want to use for the application; I’ll make it work.”
Carlos is the domain expert. He understands all the ins and outs of
conference management. He has worked in a number of organizations that
help people run conferences. He has also worked in a number of different
roles: sales and marketing, conference management, and consultant.
“I want to make sure that the team understands how this business works so that we can
deliver a world-class online conference management system.”
3
Our Domain: Conference Management System
Poe is an IT professional who’s an expert in deploying and running
applications in the cloud. Poe has a keen interest in practical solutions;
after all, he’s the one who gets paged at 3:00 AM when there’s a problem.
“Running complex applications in the cloud involves challenges that are different than
the challenges in managing on-premises applications. I want to make sure our new
conference management system meets our published service-level agreements (SLA).”
Beth is a business manager. She helps companies to plan how their business will
develop. She understands the market that the company operates in, the resources
that the company has available, and the goals of the company. She has both a
strategic view and an interest in the day-to-day operations of the company.
“Organizations face many conflicting demands on their resources. I want to make sure that our
company balances those demands and adopts a business plan that will make us successful in the
medium and long term.”If you have a particular area of interest, look for notes provided by the
specialists whose interests align with yours.
The Contoso Conference Management System
This section describes the Contoso Conference Management System as the team envisaged it at the
start of the journey. The team has not used the CQRS pattern before; therefore, the system that is
delivered at the end of our journey may not match this description exactly because:
• What we learn as we go may impact what we ultimately deliver.
• Because this is a learning journey, it is more difficult to estimate what we can achieve in the
available time.
Overview of the system
Contoso plans to build an online conference management system that will enable its customers to
plan and manage conferences that are held at a physical location. The system will enable Contoso’s
customers to:
• Manage the sale of different seat types for the conference.
• Create a conference and define characteristics of that conference.
The Contoso Conference Management System will be a multi-tenant, cloud-hosted application. Busi-
ness customers will need to register with the system before they can create and manage their confer-
ences.
4 Journey one
Selling seats for a conference
The business customer defines the number of seats available for the conference. The business cus-
tomer may also specify events at a conference such as workshops, receptions, and premium sessions
for which attendees must have a separate ticket. The business customer also defines how many seats
are available for these events.
The system manages the sale of seats to ensure that the conference and sub-events are not
oversubscribed. This part of the system will also operate wait-lists so that if other attendees cancel,
their seats can be reallocated.
The system will require that the names of the attendees be associated with the purchased seats
so that an on-site system can print badges for the attendees when they arrive at the conference.
Creating a conference
A business customer can create new conferences and manage information about the conference such
as its name, description, and dates. The business customer can also make a conference visible on the
Contoso Conference Management System website by publishing it, or hide it by unpublishing it.
Additionally, the business customer defines the seat types and available quantity of each seat type
for the conference.
Contoso also plans to enable the business customer to specify the following characteristics of a
conference:
• Whether the paper submission process will require reviewers.
• What the fee structure for paying Contoso will be.
• Who key personnel, such as the program chair and the event planner, will be.
Nonfunctional requirements
Contoso has two major nonfunctional requirements for its conference management system—scal-
ability and flexibility—and it hopes that the CQRS pattern will help it meet them.
Scalability
The conference management system will be hosted in the cloud; one of the reasons Contoso chose a
cloud platform was its scalability and potential for elastic scalability.
Although cloud platforms such as Windows Azure enable you to scale applications by adding (or
removing) role instances, you must still design your application to be scalable. By splitting responsibil-
ity for the application’s read and write operations into separate objects, the CQRS pattern allows
Contoso to split those operations into separate Windows Azure roles that can scale independently of
each other. This recognizes the fact that for many applications, the number of read operations vastly
exceeds the number of write operations. This gives Contoso the opportunity to scale the conference
management system more efficiently, and make better use of the Windows Azure role instances it uses.
5
Our Domain: Conference Management System
Flexibility
The market that the Contoso Conference Management System oper-
ates in is very competitive, and very fast moving. In order to compete,
Contoso must be able to quickly and cost effectively adapt the con-
ference management system to changes in the market. This require-
ment for flexibility breaks down into a number of related aspects:
• Contoso must be able to evolve the system to meet new
requirements and to respond to changes in the market.
• The system must be able to run multiple versions of its software
simultaneously in order to support customers who are in the
middle of a conference and who do not wish to upgrade to a
new version immediately. Other customers may wish to migrate
their existing conference data to a new version of the software
as it becomes available.
• Contoso intends the software to last for at least five years. It
must be able to accommodate significant changes over that
period.
• Contoso does not want the complexity of some parts of the
system to become a barrier to change.
• Contoso would like to be able to use different developers for
different elements of the system, using cheaper developers for
simpler tasks and restricting its use of more expensive and
experienced developers to the more critical aspects of the
system.
Beginning the journey
The next chapter is the start of our CQRS journey. It provides more
information about the Contoso Conference Management System and
describes some of the high-level parts of the system. Subsequent
chapters describe the stages of the journey as Contoso implements
the conference management system.
More information
All links in this book are accessible from the book’s online bibliogra-
phy available at: http://msdn.microsoft.com/en-us/library/jj619274.
Contoso plans to compete
by being quick to respond
to changes in the market
and to changing customer
requirements. Contoso
must be able to evolve
the system quickly and
painlessly.
This is a big challenge:
keeping the system running
for all our customers while
we perform upgrades with
no down time.
There is some debate in the CQRS community about whether,
in practice, you can use different development teams for
different parts of the CQRS pattern implementation.
Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts
7
“Without stones there is no arch.”
Marco Polo
In this chapter, we provide a high-level overview of the Contoso Conference Management System.
The discussion will help you understand the structure of the application, the integration points, and
how the parts of the application relate to each other.
Here we describe this high-level structure in terms borrowed from the domain-driven design
(DDD) approach that Eric Evans describes in his book, Domain-Driven Design: Tackling Complexity in
the Heart of Software (Addison-Wesley Professional, 2003). Although there is no universal consensus
that DDD is a prerequisite for implementing the Command Query Responsibility Segregation (CQRS)
pattern successfully, our team decided to use many of the concepts from the DDD approach, such as
domain, bounded context, and aggregate, in line with common practice within the CQRS community.
Chapter 1, “CQRS in Context,” in the Reference Guide discusses the relationship between the DDD
approach and the CQRS pattern in more detail.
Definitions used in this chapter
Throughout this chapter we use a number of terms, which we’ll define in a moment. For more detail,
and possible alternative definitions, see Chapter 1, “CQRS in Context,” in the Reference Guide.
Domain: The domain refers to the business domain for the Contoso Conference Management
System (the reference implementation). Chapter 1, “Our Domain: The Contoso Conference Manage-
ment System,” provides an overview of this domain.
Decomposing the Domain
Planning the stops.
Journey 2:
8 Journey two
Bounded context: The term bounded context comes from Eric
Evans’ book. In brief, Evans introduces this concept as a way to de-
compose a large, complex system into more manageable pieces; a
large system is composed of multiple bounded contexts. Each bound-
ed context is the context for its own self-contained domain model,
and has its own ubiquitous language. You can also view a bounded
context as an autonomous business component defining clear consis-
tency boundaries: one bounded context typically communicates with
another bounded context by raising events.
Context map: According to Eric Evans, you should “Describe the
points of contact between the models, outlining explicit translation
for any communication and highlighting any sharing.” This exercise
results in what is called a context map, which serves several purposes
that include providing an overview of the whole system and helping
people to understand the details of how different bounded contexts
interact with each other.
Bounded contexts in the conference management
system
The Orders and Registrations bounded context: Within the orders
and registrations bounded context are the reservations, payment, and
registration items. When a registrant interacts with the system, the
system creates an order to manage the reservations, payment, and
registrations. An order contains one or more order items.
A reservation is a temporary reservation of one or more seats at a
conference. When a registrant begins the ordering process to pur-
chase a number of seats at a conference, the system creates reserva-
tions for that number of seats. Those seats are then unavailable for
other registrants to reserve. The reservations are held for 15 minutes,
during which time the registrant can complete the ordering process
by making a payment for the seats. If the registrant does not pay for
the tickets within 15 minutes, the system deletes the reservation and
the seats become available for other registrants to reserve.
The Conference Management bounded context: Within this
bounded context, a business customer can create new conferences
and manage them. After a business customer creates a new confer-
ence, he can access the details of the conference by using his email
address and conference locator access code. The system generates
the access code when the business customer creates the conference.
When you use the CQRS
pattern, you often use
events to communicate
between bounded contexts.
There are alternative
approaches to integration,
such as sharing data at the
database level.
We discussed making the
period of time that the
system holds reservations
a parameter that a business
customer can adjust for
each conference. This may
be a feature that we add if
we determine that there is
a requirement for this level
of control.
9
Decomposing the Domain
The business customer can specify the following information about a conference:
• The name, description, and slug (part of the URL used to access the conference).
• The start and end dates of the conference.
• The different types and quotas of seats available at the conference.
Additionally, the business customer can control the visibility of the conference on the public website
by either publishing or unpublishing the conference.
The business customer can also use the conference management website to view a list of orders
and attendees.
The Payments bounded context: The payments bounded context is responsible for managing the
interactions between the conference management system and external payment systems. It forwards
the necessary payment information to the external system and receives an acknowledgement that the
payment was either accepted or rejected. It reports the success or failure of the payment back to the
conference management system.
Initially, the payments bounded context will assume that the business customer has an account
with the third-party payment system (although not necessarily a merchant account), or that the busi-
ness customer will accept payment by invoice.
Bounded contexts not included
Although they didn’t make it into the final release of the Contoso Conference Management System,
some work was done on three additional bounded contexts. Members of the community are working
on these and other features, and any out-of-band releases and updates will be announced on the
Project “a CQRS Journey” website. If you would like to contribute to these bounded contexts or any
other aspect of the system, visit the Project “a CQRS Journey” website or let us know at cqrsjourney@
microsoft.com.
The Discounts bounded context: This is a bounded context to handle the process of managing
and applying discounts to the purchase of conference seats that would integrate with all three exist-
ing bounded contexts.
The Occasionally Disconnected Conference Management client: This is a bounded context to
handle management of conferences on-site with functionality to handle label printing, recording at-
tendee arrivals, and additional seat sales.
The Submissions And Schedule Management bounded context: This is a bounded context to
handle paper submissions and conference event scheduling written using Node.js.
Note: Wait listing is not implemented in this release, but members of the community are working
on this and other features. Any out-of-band releases and updates will be announced on the Project
“a CQRS Journey” website.
10 Journey two
The context map for the Contoso
Conference Management System
Figure 1 and the table that follows it represent a context map that
shows the relationships between the different bounded contexts
that make up the complete system, and as such it provides a high-
level overview of how the system is put together. Even though this
context map appears to be quite simple, the implementation of these
bounded contexts, and more importantly the interactions between
them, are relatively sophisticated; this enabled us to address a wide
range of issues relating to the CQRS pattern and event sourcing (ES),
and provided a rich source from which to capture many valuable les-
sons learned.
Figure 1 shows the three bounded contexts that make up the
Contoso Conference Management System. The arrows in the diagram
indicate the flow of data as events between them.
Figure 1
Bounded contexts in the Contoso Conference Management System
A frequent comment
about CQRS projects is
that it can be difficult to
understand how all of
the pieces fit together,
especially if there a great
many commands and events
in the system. Often, you
can perform some static
analysis on the code to
determine where events
and commands are handled,
but it is more difficult to
automatically determine
where they originate. At a
high level, a context map
can help you understand
the integration between
the different bounded
contexts and the events
involved. Maintaining
up-to-date documentation
about the commands
and events can provide
more detailed insight.
Additionally, if you have
tests that use commands as
inputs and then check for
events, you can examine
the tests to understand the
expected consequences
of particular commands
(see the section on testing
in Chapter 4, “Extending
and Enhancing the Orders
and Registrations Bounded
Context” for an example of
this style of test).
11
Decomposing the Domain
The following list provides more information about the arrows in
Figure 1. You can find additional details in the chapters that discuss
the individual bounded contexts.
1. Events that report when conferences have been created,
updated, or published. Events that report when seat types
have been created or updated.
2. Events that report when orders have been created or up-
dated. Events that report when attendees have been assigned
to seats.
3. Requests for a payment to be made.
4. Acknowledgement of the success or failure of the payment.
Why did we choose these bounded contexts?
During the planning stage of the journey, it became clear that these
were the natural divisions in the domain that could each contain their
own, independent domain models. Some of these divisions were eas-
ier to identify than others. For example, it was clear early on that the
conference management bounded context is independent of the re-
mainder of the domain. It has clearly defined responsibilities that re-
late to defining conferences and seat types and clearly defined points
of integration with the rest of the application.
On the other hand, it took some time to realize that the orders and
registrations bounded context is separate from the Payments bounded
context. For example, it was not until the V2 release of the application
that all concepts relating to payments disappeared from the orders and
registrations bounded context when the OrderPaymentConfirmed
event became the OrderConfirmed event.
More practically, from the perspective of the journey, we wanted
a set of bounded contexts that would enable us to release a working
application with some core functionality and that would enable us to
explore a number of different implementation patterns: CQRS,
CQRS/ES, as well as integration with a legacy, CRUD-style bounded
context.
More information
All links in this book are accessible from the book’s online bibliogra-
phy available at: http://msdn.microsoft.com/en-us/library/jj619274.
Some of the events
that the Conference
Management bounded
context raises are coarse-
grained and contain
multiple fields. Remember
that conference
management is a create,
read, update and delete
(CRUD)-style bounded
context and does
not raise fine-grained
domain-style events. For
more information, see
Chapter 5, “Preparing for
the V1 Release.”
We continued to
refine the domain
models right through
the journey as our
understanding of the
domain deepened.
Contoso wants to release a usable application as soon as possible, but
be able to add both planned features and customer-requested features
as they are developed and with no down time for the upgrades.
Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts
13
“The Allegator is the same, as the Crocodile, and differs only in Name.”
John Lawson
A description of the bounded context
The Orders and Registrations bounded context is partially responsible for the booking process for
attendees planning to come to a conference. In the Orders and Registrations bounded context, a
person (the registrant) purchases seats at a particular conference. The registrant also assigns names of
attendees to the purchased seats (this is described in Chapter 5, “Preparing for the V1 Release”).
This was the first stop on our CQRS journey, so the team decided to implement a core, but self-
contained part of the system—orders and registrations. The registration process must be as painless
as possible for attendees. The process must enable the business customer to ensure that the maximum
possible number of seats can be booked, and give them the flexibility set the prices for the different
seat types at a conference.
Because this was the first bounded context addressed by the team, we also implemented some
infrastructure elements of the system to support the domain’s functionality. These included command
and event message buses and a persistence mechanism for aggregates.
The Contoso Conference Management System described in this chapter is not the final version of
the system. This guidance describes a journey, so some of the design decisions and implementation
details change later in the journey. These changes are described in subsequent chapters.
Plans for enhancements to this bounded context in some future journey include support for wait
listing, whereby requests for seats are placed on a wait list if there aren’t sufficient seats available, and
enabling the business customer to set various types of discounts for seat types.
Wait listing is not implemented in this release, but members of the community are working on this
and other features. Any out-of-band releases and updates will be announced on the Project “a
CQRS Journey” website.
Orders and Registrations
Bounded Context
The first stop on our CQRS journey.
Journey 3:
14 Journey three
Working definitions for this chapter
This chapter uses a number of terms that we will define in a moment.
For more detail, and possible alternative definitions, see “A CQRS and
ES Deep Dive” in the Reference Guide.
Command. A command is a request for the system to perform an
action that changes the state of the system. Commands are impera-
tives; MakeSeatReservation is one example. In this bounded context,
commands originate either from the UI as a result of a user initiating
a request, or from a process manager when the process manager is
directing an aggregate to perform an action.
A single recipient processes a command. A command bus trans-
ports commands that command handlers then dispatch to aggregates.
Sending a command is an asynchronous operation with no return
value.
Event. An event, such as OrderConfirmed, describes something
that has happened in the system, typically as a result of a command.
Aggregates in the domain model raise events.
Multiple subscribers can handle a specific event. Aggregates pub-
lish events to an event bus; handlers register for specific types of
events on the event bus and then deliver the event to the subscriber.
In this bounded context, the only subscriber is a process manager.
Process manager. In this bounded context, a process manager is a
class that coordinates the behavior of the aggregates in the domain.
A process manager subscribes to the events that the aggregates raise,
and then follow a simple set of rules to determine which command or
commands to send. The process manager does not contain any busi-
ness logic; it simply contains logic to determine the next command to
send. The process manager is implemented as a state machine, so
when it responds to an event, it can change its internal state in addi-
tion to sending a new command.
Our process manager is an implementation of the Process Man-
ager pattern defined on pages 312 to 321 of the book by Gregor
Hohpe and Bobby Woolf, entitled Enterprise Integration Patterns:
Designing, Building, and Deploying Messaging Solutions (Addison-
Wesley Professional, 2003).
For a discussion of some
possible optimizations
that also involve a slightly
different definition of a
command, see Chapter 6,
“Versioning our System.”
It can be difficult for someone new to the code to follow
the flow of commands and events through the system. For
a discussion of a technique that can help, see the section
“Impact on testing” in Chapter 4, “Extending and Enhancing
the Orders and Registrations Bounded Contexts.”
15
Orders and Registrations Bounded Context
The process manager in this bounded context can receive com-
mands as well as subscribe to events.
The Reference Guide contains additional definitions and explana-
tions of CQRS-related terms.
Domain definitions (ubiquitous language)
The following list defines the key domain-related terms that the team
used during the development of this Orders and Registrations bound-
ed context.
Attendee. An attendee is someone who is entitled to attend a
conference. An Attendee can interact with the system to perform
tasks such as manage his agenda, print his badge, and provide feed-
back after the conference. An attendee could also be a person who
doesn’t pay to attend a conference such as a volunteer, speaker, or
someone with a 100% discount. An attendee may have multiple as-
sociated attendee types (speaker, student, volunteer, track chair, and
so on.)
Registrant. A registrant is a person who interacts with the sys-
tem to place orders and to make payments for those orders. A regis-
trant also creates the registrations associated with an order. A regis-
trant may also be an attendee.
User. A user is a person such as an attendee, registrant, speaker,
or volunteer who is associated with a conference. Each user has a
unique record locator code that the user can use to access user-spe-
cific information in the system. For example, a registrant can use a
record locator code to access her orders, and an attendee can use a
record locator code to access his personalized conference agenda.
Seat assignment. A seat assignment associates an attendee with
a seat in a confirmed order. An order may have one or more seat as-
signments associated with it.
Order. When a registrant interacts with the system, the system
creates an order to manage the reservations, payment, and registra-
tions. An order is confirmed when the registrant has successfully paid
for the order items. An order contains one or more order items.
Order item. An order item represents a seat type and quantity,
and is associated with an order. An order item exists in one of three
states: created, reserved, or rejected. An order item is initially in the
created state. An order item is in the reserved state if the system has
reserved the quantity of seats of the seat type requested by the regis-
trant. An order item is in the rejected state if the system cannot re-
serve the quantity of seats of the seat type requested by the registrant.
The team initially referred
to the process manager
class in the orders bounded
context as a saga. To find
out why we decided to
change the terminology,
see the section “Patterns
and concepts” later in this
chapter.
We intentionally
implemented a record
locator mechanism to
return to a previously
submitted order via the
mechanism. This eliminates
an often annoying
requirement for users to
create an account in the
system and sign in in order
to evaluate its usefulness.
Our customers were
adamant about this.
16 Journey three
Seat. A seat represents the right to be admitted to a conference or to access a specific session at
the conference such as a cocktail party, a tutorial, or a workshop. The business customer may change
the quota of seats for each conference. The business customer may also change the quota of seats for
each session.
Reservation. A reservation is a temporary reservation of one or more seats. The ordering process
creates reservations. When a registrant begins the ordering process, the system makes reservations
for the number of seats requested by the registrant. These seats are then not available for other
registrants to reserve. The reservations are held for n minutes during which the registrant can com-
plete the ordering process by making a payment for those seats. If the registrant does not pay for the
seats within n minutes, the system cancels the reservation and the seats become available to other
registrants to reserve.
Seat availability. Every conference tracks seat availability for each type of seat. Initially, all of the
seats are available to reserve and purchase. When a seat is reserved, the number of available seats of
that type is decremented. If the system cancels the reservation, the number of available seats of that
type is incremented. The business customer defines the initial number of each seat type to be made
available; this is an attribute of a conference. A conference owner may adjust the numbers for the
individual seat types.
Conference site. You can access every conference defined in the system by using a unique URL.
Registrants can begin the ordering process from this site.
Each of the terms defined here was formulated through active discussions between the devel-
opment team and the domain experts. The following is a sample conversation between devel-
opers and domain experts that illustrates how the team arrived at a definition of the term at-
tendee.
Developer 1: Here’s an initial stab at a definition for attendee. “An attendee is someone who
has paid to attend a conference. An attendee can interact with the system to perform tasks
such as manage his agenda, print his badge, and provide feedback after the conference.”
Domain Expert 1: Not all attendees will pay to attend the conference. For example, some
conferences will have volunteer helpers, also speakers typically don’t pay. And, there may be
some cases where an attendee gets a 100% discount.
Domain Expert 1: Don’t forget that it’s not the attendee who pays; that’s done by the regis-
trant.
Developer 1: So we need to say that Attendees are people who are authorized to attend a
conference?
Developer 2: We need to be careful about the choice of words here. The term authorized will
make some people think of security and authentication and authorization.
Developer 1: How about entitled?
Domain Expert 1: When the system performs tasks such as printing badges, it will need to
know what type of attendee the badge is for. For example, speaker, volunteer, paid attendee,
and so on.
17
Orders and Registrations Bounded Context
Developer 1: Now we have this as a definition that captures everything we’ve discussed. An
attendee is someone who is entitled to attend a conference. An attendee can interact with
the system to perform tasks such as manage his agenda, print his badge, and provide feedback
after the conference. An attendee could also be a person who doesn’t pay to attend a confer-
ence such as a volunteer, speaker, or someone with a 100% discount. An attendee may have
multiple associated attendee types (speaker, student, volunteer, track chair, and so on.)
Requirements for creating orders
A registrant is the person who reserves and pays for (orders) seats at a conference. Ordering is a
two-stage process: first, the registrant reserves a number of seats and then pays for the seats to
confirm the reservation. If registrant does not complete the payment, the seat reservations expire
after a fixed period and the system makes the seats available for other registrants to reserve.
Figure 1 shows some of the early UI mockups that the team used to explore the seat-ordering
story.
Figure 1
Ordering UI mockups
18 Journey three
These UI mockups helped the team in several ways, allowing them to:
• Communicate the core team’s vision for the system to the
graphic designers who are on an independent team at a third-
party company.
• Communicate the domain expert’s knowledge to the developers.
• Refine the definition of terms in the ubiquitous language.
• Explore “what if” questions about alternative scenarios and
approaches.
• Form the basis for the system’s suite of acceptance tests.
Architecture
The application is designed to deploy to Windows Azure. At this
stage in the journey, the application consists of a web role that con-
tains the ASP.NET MVC web application and a worker role that
contains the message handlers and domain objects. The application
uses a Windows Azure SQL Database instance for data storage, both
on the write side and the read side. The application uses the Win-
dows Azure Service Bus to provide its messaging infrastructure.
While you are exploring and testing the solution, you can run it
locally, either using the Windows Azure compute emulator or by run-
ning the MVC web application directly and running a console applica-
tion that hosts the handlers and domain objects. When you run the
application locally, you can use a local SQL Server Express database
instead of SQL Database, and use a simple messaging infrastructure
implemented in a SQL Server Express database.
For more information about the options for running the applica-
tion, see Appendix 1, “Release Notes.”
Patterns and concepts
The team decided to implement the first bounded context without us-
ing event sourcing in order to keep things simple. However, they did
agree that if they later decided that event sourcing would bring specific
benefits to this bounded context, then they would revisit this decision.
For a description of how event sourcing relates to the CQRS
pattern, see “Introducing Event Sourcing” in the Reference Guide.
One of the important discussions the team had concerned the choice
of aggregates and entities that they would implement. The following
images from the team’s whiteboard illustrate some of their initial
thoughts, and questions about the alternative approaches they could
take with a simple conference seat reservation scenario to try and
understand the pros and cons of alternative approaches.
A frequently cited
advantage of the CQRS
pattern is that it enables
you to scale the read
side and write side of the
application independently
to support the different
usage patterns. In this
bounded context,
however, the number of
read operations from the
UI is not likely to hugely
out-number the write
operations: this bounded
context focuses on
registrants creating orders.
Therefore, the read side and
the write side are deployed
to the same Windows Azure
worker role rather than
to two separate worker
roles that could be scaled
independently.
“A value I think developers
would benefit greatly from
recognizing is the de-emphasis
on the means and methods for
persistence of objects in terms
of relational storage. Teach
them to avoid modeling the
domain as if it was a rela-
tional store, and I think it will
be easier to introduce and
understand both domain-
driven design (DDD) and
CQRS.”
—Josh Elster, CQRS Advisors
Mail List
19
Orders and Registrations Bounded Context
This scenario considers what happens when a registrant tries to book several seats at a confer-
ence. The system must:
• Check that sufficient seats are available.
• Record details of the registration.
• Update the total number of seats booked for the conference.
We deliberately kept the scenario simple to avoid distractions while the team examines the
alternatives. These examples do not illustrate the final implementation of this bounded context.
The first approach considered by the team, shown in Figure 2, uses two separate aggregates.
These diagrams deliberately exclude details of how the
system delivers commands and events through command
and event handlers. The diagrams focus on the logical
relationships between the aggregates in the domain.
Figure 2
Approach 1: Two separate aggregates
20 Journey three
The numbers in the diagram correspond to the following steps:
1. The UI sends a command to register attendees X and Y for
conference 157. The command is routed to a new Order
aggregate.
2. The Order aggregate raises an event that reports that an
order has been created. The event is routed to the Seats-
Availability aggregate.
3. The SeatsAvailability aggregate with an ID of 157 is re-
hydrated from the data store.
4. The SeatsAvailability aggregate updates its total number of
seats booked.
5. The updated version of the SeatsAvailability aggregate is
persisted to the data store.
6. The new Order aggregate, with an ID of 4239, is persisted to
the data store.
You could consider using the Memento pattern to
handle the persistence and rehydration.
The term rehydration
refers to the process of
deserializing the aggregate
instance from a data store.
Another Random Document on
Scribd Without Any Related Topics
"Rather deft at times," replied Cazeby, arranging the dishes on the
larger table.
"Je te crois!" said Bibi, enthusiastically. "Without him—what?
Evidently, it was not Léon Treize who built Saint Pierre!"
The eggs had been peculiarly obstinate, as it happened, and a
growing irritability had taken possession of Anthony. As they ate in
silence, the full force of his tragic position returned to him. Even the
unwontedness of his chance encounter with Bibi-la-Raie had not
wholly dispelled the cloud that had been gradually settling around
him since he emerged from the Automobile Club, and, as they
finished the little repast, he turned suddenly upon his guest, in a
burst of irritation.
"Who are you?" he said. "And what does all this mean? Was I
mistaken, when you first spoke to me, in thinking you a mere voyou?
Surely not! You meant to rob me. You speak the argot of the
fortifications. Yet here I find you discoursing on Michel Angelo as
though you were the conservateur of the Uffizzi! What am I to
think?"
Bibi-la-Raie lit another cigarette, blew forth the smoke in a thin, gray
wisp, and thrust his thumbs into the arm-holes of his velveteen
waistcoat.
"And you," he said, slowly, abandoning the familiar address he had
been using, "who are you? No, you were not mistaken in thinking I
meant to rob you. Such is my profession. But does a gentleman
reply, in ordinary, to the summons of a thief by paying that thief a
drink? Does he invite him to his apartment and cook a supper for
him? What am I to think?"
There was a brief pause, and then he faced his host squarely.
"Are you absolutely resolved to put an end to it all to-night?" he
demanded.
Cazeby made a small sign of bewilderment.
"Ah, mon vieux," continued the other. "That, you know, is of no use
with me. You ask me who I am. For one thing, I am one who has
lived too long in touch with desperate men not to know the look in
the eyes when the end has come. You think you are going to blow
out your brains to-night."
"Your wits are wandering; that's all," said Cazeby, compassionately.
"Oh, far from it!" said Bibi-la-Raie, with a short laugh. "But one does
not fondle one's revolver in the daytime without a good reason, nor
does one leave it on top of letters postmarked this morning unless
one has been fondling it—quoi?"
Cazeby was at the marqueterie desk in two strides, tugging at the
upper right hand drawer. It was locked. He turned about slowly, and,
half seating himself on the edge of the desk, surveyed his guest
coolly.
"The revolver is in your pocket," he said.
"No," answered Bibi, with an air of cheerfulness. "I have one of my
own. But the key is."
"Why?" said Cazeby.
Bibi helped himself to yellow chartreuse, and appeared to reflect.
"I am not sure that I know why, myself," he said finally. "Perhaps,
because you have done me a kindness and I would not like to have
you burn your fingers in a moment of absent-mindedness. Perhaps,
because we might disagree, and I should not care to take the
chance of your shooting first!"
He squinted at the liqueur, swallowed it slowly and with extreme
appreciation, smacked his lips, and then, cocking his feet up on
Cazeby's brass club fender, began to smoke again, staring into the
dwindling fire. His host watched him in silence, until he should be
ready to speak, which he presently began to do, with his cigarette
drooping from the corner of his month and moving in time to his
words. He had suddenly and curiously become a man of the world—
of the grand monde—and his speech had shaken off all trace of
slang, and was tinged instead with the faint club sarcasm which one
hears in the glass card-room of the Volney or over coffee on the roof
of the Automobile. Moreover, it was beautiful French. Not Mounet
himself could have done better.
"The only man to whom one should confide personal secrets," said
Bibi-la-Raie, "is he whom one has never seen before and will, as is
probable, never see again. I could tell you many things, Monsieur
Cazeby, since that is your name,—I have seen your morning's mail,
you know!—but, for the moment, let it suffice to say that the voyou
who accosted you this evening is of birth as good as yours—pardon,
but probably better! Wein, weib, und gesang—you know the saying.
Add cards and the race-course, and you have, complete, the short
ladder of five rungs down which I have been successful in climbing. I
shall presume to the extent of supposing that you have just
accomplished the same descent. One learns much thereby, but more
after one has reached the ground. In many ways I am afraid
experience has made me cynical, but in one it has taught me
optimism. I have found, and I think I shall continue to find, that
there is always something worth looking into around the next corner
of even the darkest street. The rue des Sablons, for instance. It was
very dark to-night, very damp, and very cold. Assuredly, as I turned
into the avenue d'Eylau I had no reason to foresee a supper, Russian
cigarettes, and chartreuse jaune. And yet, me voilà! Now what most
of us lack—what you, in particular, seem to lack, Monsieur Cazeby—
is the tenacity needful if one is to get to that next turning."
"There are streets darker than the rue des Sablons," put in Anthony,
falling in with the other's whimsical humor, "and that have no
turning."
"You speak from conjecture, not experience," said Bibi-la-Raie. "You
can never have seen one."
He glanced about the room, with the air of one making a mental
inventory.
"First," he added, "there come the pawnshop, the exterior
boulevards, the somewhat insufficient shelter of the Pont Royal. No,
you have not come to the last corner."
"All that," said Cazeby, "is simply a matter of philosophy. Each of us
has his own idea of what makes life worth the while. When that is
no longer procurable, then that is the last corner."
"For instance—?"
"For instance, my own case. You have analyzed my situation
sufficiently well—though when you said I was about to blow out my
brains"—
"It was a mere guess," interrupted Bibi, "founded on circumstantial
evidence. Then I thought so. Now I know it."
"Let us grant you are right," continued Cazeby, with a smile. "I have
my own conception of what I require to make existence tolerable. It
includes this apartment, or its equivalent, a horse, two servants, two
clubs, and a sufficient income to dress, eat, entertain, and amuse
myself in the manner of my class,—an extravagant and
unreasonable standard, if you will, but such is my conviction. Now,
granted that the moment has come when it is no longer possible for
me to have these things, and when there is no prospect of my
situation being bettered, I cannot conceive what advantage there
can be in continuing to live."
"I perceive you are a philosopher," said the other. "How about the
religious view?"
Cazeby shrugged his shoulders.
"As to that," he said, "my religious views are, so far as I know,
stored away in the little church which I was forced to attend three
times on every Sunday of my boyhood. They did not come out with
me on the last occasion, and I have never met them since."
"Excellent!" said Bibi. "It is the same with me. But I think you are
mistaken in your conviction of what makes life worth living. I had my
own delusions in the time. But I have had a deal of schooling since
then. There are many things as amusing as luxury—even on the
exterior boulevards. Of course, actual experience is essential. One
never knows what one would do under given conditions."
He turned suddenly, and looked Cazeby in the eye.
"What, for example, would you do if you were in my place?" he
asked.
"As you say, one never knows," said his host. "I think that, in your
place, I should improve the opportunity you find open, and carry out
your late and laudable intention of robbing Monsieur Antoine Cazeby.
I may be influenced by my knowledge that such a proceeding would
not irritate or incommode him in the least, but that is what I think I
should do.
"I shall not need these things to-morrow," he added, indicating his
surroundings with a gesture. "You were quite right about the pistol.
As to your prospective booty, I regret to say that I spent my last
sixty centimes on our cognac, but there is a remarkably fine scarf-
pin on the table in my dressing-room."
"A sapphire, surrounded by black pearls," put in the other. "You were
rather long in cooking those eggs."
"A sapphire, surrounded by black pearls," agreed Cazeby. "Yes, upon
reflection, I am quite sure that that is what I should do."
Bibi-la-Raie smiled pleasantly.
"I am glad to find we are of one mind," he said. "Of course, mine
was made up, but it is more agreeable to know that I am causing
you no inconvenience. I suppose it is unnecessary to add that
resistance will be quite useless. I have the only available revolver,
and, moreover, I propose to tie you into this extremely comfortable
chair. It is not," he added, "that I do not trust you, although our
acquaintance is, unfortunately, too recent to inspire complete
confidence. No, I have my convictions as well as you, Monsieur
Cazeby, and one of them, curiously enough, is that, in spite of
appearances, I am doing you a kindness in putting it out of your
power, for tonight, at least, to do yourself an injury. Who knows?
Perhaps, in the morning, you may find that there is something
around the next corner, after all. If not, there is no harm done. Your
servants come in early?"
"At seven o'clock," said Anthony, briefly.
"Exactly. And I will leave the key in the drawer."
Bibi was expeditious. When he had bound Cazeby firmly, and with an
art that showed practice, he disappeared into the dressing-room,
returning in less than a minute with the sapphire scarf-pin and
several other articles of jewelry in his hand.
"I should like to add to these," he said, going to the book-case, "this
little copy of Omar Khayyám. He is a favorite of mine. There is
something about his philosophy which seems to accord with our
own. But—'the bird of time has but a little way to flutter'"—He
paused at the door.
"Can I do anything for you before I go?" he inquired politely.
"Be good enough to turn off the light," said the other. "The button is
on the right of the door."
"Good-night," said Bibi-la-Raie.
"Good-night,—brother!" said Cazeby.
Then he heard the door of the apartment close softly.
Anthony was awakened from a restless sleep by the sound of its
opening. Through the gap between the window draperies the gray
light of the winter morning was creeping in. His wrists and ankles
were aching from the pressure of the curtain cords with which he
had been bound, and he was gratified when, after a brief interval,
the salon door was opened in its turn and the invaluable Jules came
in, in shirt-sleeves and long white apron, carrying a handful of
letters.
That impassive person was probably never nearer to being visibly
surprised. For a breath he stopped, and the pupils of his round eyes
dilated like those of a cat in a dim light. But his training stood him in
good stead, and when he spoke his voice was as innocent of
emotion as if he had been announcing dinner.
"Monsieur desires to be untied?"
Left to himself, Cazeby turned his attention to his letters, and from
the top of the pile picked up a cablegram. He was still reflecting
upon the singular experience of the night, in an attempt to analyze
his present emotions. Was he in any whit changed by his enforced
reprieve? He was glad to think not. Above all minor faults he
abhorred vacillation of purpose. No, his situation and his purpose
remained unaltered. But he was conscious, nevertheless, of an
unwonted thrill at the thought that, but for the merest chance, it
would have been for others to open the envelope he was even now
fingering. Jules would already have found him—he wondered, with
the shadow of a smile, whether Jules would still have been
unsurprised!—and would have brought up the concierge and the
police—
Suddenly the cable message jumped at him through his revery as if,
at that moment, the words had been instantaneously printed on
what was before blank paper, and he realized that it was from his
father's solicitor.
Mr. Cazeby died eight o'clock this evening after making
will your favor whole property. Waiting instructions.
Milliken.
Anthony straightened himself with a long sigh, and, putting aside the
curtain, looked out across the mansardes, wet and gleaming under a
thin rain. His hand trembled a little on the heavy velvet, and he
frowned at it, and, going across to the table, poured himself out a
swallow of brandy.
With the glass at his lips he paused, his eyes upon the chair where
Bibi-la-Raie had sat and wherein he himself had passed five hours.
Then, very ceremoniously, he bowed and dipped his glass toward an
imaginary occupant.
"Merci, monsieur!" he said.
Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts
I
T h e O n l y S o n o f H i s
M o t h e r
N the limited understanding of Pépin dwelt one great Fact, in the
shadow of which all else shrank to insignificance, and that Fact
was the existence of Comte Victor de Villersexel, the extremely tall
and extraordinarily imposing person who was, first of all, Officier de
la Légion d'Honneur, second, Membre de l'Académie Française, and,
lastly, father to Pépin himself. It must be acknowledged that to the
more observing of his limited kinsfolk and extensive acquaintance
the clay feet of Pépin's idol were distinctly in evidence. How he had
contrived to attain to the proud eminence which he occupied was, in
the earlier days of his publicity, a matter of curious conjecture and
not over-plausible explanation. Certainly no inherent merit or ability
it was which formed the first step of the stairway he had climbed. In
diplomacy the Comte de Villersexel had never bettered his first
appointment as second secretary of legation at Belgrade; in
literature his achievements were limited to one ponderous work on
feudalism, remarkable chiefly for its surpassing futility; and in society
his sole claim to consideration lay in his marriage to a Brazilian
heiress, who had died within the year, leaving her husband an
income of two hundred thousand francs—and Pépin. In all this it was
difficult to find a sufficient reason for the crimson button and the
green embroidered coat, unless it was that the family of de
Villersexel went back to the Crusades. That is not always a prudent
thing for a family to do, but the present instance was an exception.
Born to the heritage of a name which his predecessors had made
notable, Comte Victor was one of those whose greatness is thrust
upon them rather than achieved, one of the bubbles in the ferment
of Paris which their very levity brings to the top, to show rainbow
tints in the sunlight of publicity. It is probable that no one was more
surprised than de Villersexel himself at the honors which fell to his
share, but one thing even the most contemptuous had, perforce, to
concede. Once secure of his laurels, he wore them with a confidence
that was akin to conviction. His reserve was iron-clad, his dignity
stupendous. It required considerable time for new acquaintances to
probe the secret of his insufficiency. Victor de Villersexel was, as the
irreverent young military attaché at the American Embassy once said
of him, "a dazzling imitation of the real thing."
But to Pépin the idol was an idol without flaw. Through what shrewd
appreciation of occasional words and chance comments he had
contrived to grasp the significance of that speck of scarlet upon the
Count's lapel and that apparently simple phrase, "de l'Académie
Française," which, in formal introductions, was wont to follow his
father's name, must be numbered among childhood's mysteries. But
before he was seven, Pépin had solved these problems for himself,
and the results of his reasoning were awestruck admiration and blind
allegiance to the will of this wonderful creature who never smiled.
His own small individuality was so completely overshadowed by that
of his father that in the latter's presence the child was scarcely
noticeable, dressed in his sober blouses, and creeping about the
stately rooms of the great apartment in the avenue d'Iéna with an
absolutely noiseless step. He was all brown, was Pépin: brown bare
legs, and brown hands, very small and slender, brown hair, cropped
short and primly parted, and deep brown eyes, eloquent of
unspoken and unspeakable things. He was earnest, his tutor said,
earnest and willing, but not bright, poor Pépin! He spoke English, to
be sure, with a curious accent caught from his Cornish nurse, but
that was due not so much to ability as to enforced association. In his
French grammar and such simple arithmetic as was required of him
he was slow and often stupid. But he was rarely scolded, and never
punished. Once, indeed, the Comte had been about to strike him for
some trifling fault, but somehow the blow, for which Pépin stood
waiting, never fell.
"He is like his mother," the légionnaire had muttered, as he turned
away, "an imbecile—but"—
Pépin, catching the unfinished phrase, grew sick with a great
discouragement, mingled with profound pity for the man before him.
It must be a dreadful thing for one so famous to be the father of an
imbecile! From that day on the child was more inconspicuous than
before.
Deliberately affected in the first instance, what was known in society
as de Villersexel's "academic manner" came in course of time to be
second nature. Practice made perfect the chill reserve which was
originally assumed as a precaution against possible discovery of his
vapidity; and as the image of what the academician had been,
before his election, grew dimmer in society's recollection, his
impressive solemnity, barely disguised by a veneer of superficial
courtesy, did not fail of its effect. He was spoken of as a man in
whom much lay below the surface, and his more recent
acquaintances coupled their estimate of his character with the
proverbial profundity of still waters, and the familiar gloved fist of
steel. Others, more observant, smiled at the similes, but did not go
to the pains of proving them ill applied. One of the most
characteristic things about the Comte de Villersexel was that he
inspired neither championship nor antagonism.
With all this, he was consistent, with that curious obstinacy which is
sometimes made manifest in the shallowest natures. His rôle, once
assumed, was, as we have said, played to perfection and never laid
aside. The domestic threshold, which is, for the majority of men, a
kind of uncloaking room, saw never an alteration, even of voice or
expression, in his pose. The household affairs were regulated with
almost military precision, and once a day, at noon, Pépin and his
father met in the large salon,—the Comte in his tall satin stock and
frock coat, and Pépin fresh from the careful hands of his nurse. They
shook hands gravely, and then waited in silence, until the maître
d'hôtel announced breakfast,—
"Ces messieurs sont servis!"
What meals they were, to be sure, those déjeuners, solemnly
served, and more solemnly eaten, under the rigid observation of
three menservants; de Villersexel, with his thin lips, his cold eyes,
and his finely pointed gray mustache, barely moving save to raise his
fork or break a morsel from his roll, and Pépin, all brown, perched
like a mouse on the edge of a great chair, and nibbling at tiny scraps
of food with downcast eyes!
At the very end, as the Comte was about to push back his chair, he
would invariably raise his glass of champagne and Pépin his, wherein
a few drops of red wine turned the Evian to a pale heliotrope, and
together they would glance toward the full-length portrait which
hung above the mantel.
"Ta mère!" said the Comte.
"Maman!" replied Pépin.
And so they drank the toast of tribute to the dead.
After breakfast, the father would read for an hour to the child, and
Pépin, seated on another large chair, would listen, perfectly
motionless, striving desperately to understand the long sentences
which fell in flawlessly pronounced succession from the
Academician's lips. De Villersexel had a fairly clear recollection of
what books had been the companions of his childhood, and these he
purchased in the rarest editions, and clothed in the richest bindings,
and read to Pépin: only his remembrance did not extend to a very
distinct differentiation between seven and fifteen, for it was at the
latter age that he read "Télémaque" to himself, and at the former
that he read "Télémaque" to his son.
Then would come a second formal handshake, and Pépin, pausing
an instant at the door to make a slow, stiff bow, would creep off
down the long corridor to the nursery, and the Comte turn again to
his papers with a consciousness of paternal duty done.
How Pépin contrived to spend the long hours which his daily walk
and his short lessons left at his disposal, only Pépin knew. He talked
rarely with the servants,—"a thing," his father told him, "that no
gentleman would wish to do;" and other children never entered at
the de Villersexel door, "for," said the Comte, "children sow
unfortunate ideas and spread disease."
But there were compensations. One was the full-length portrait over
the chimney-piece in the dining-room. Pépin had no conception of
how great was the signature it bore, or of the fabulous sum which it
had cost, but he knew it was very beautiful, and, besides, it was his
mother,—the sad-eyed, pale dream-mother he had never seen.
The portrait of the Comtesse de Villersexel had been one of the
sensations at the Salon of seven years before. The young Brazilian
was represented at the moment when the bow left the strings of her
violin, and on her lips and in her eyes yet dwelt the spirit of the
music she had been playing. A clinging gown of ivory-white silk
emphasized rather than hid the lines of her figure, of strangely
girlish slenderness, but straight and proud as that of a young
empress. In its frailty lay the keynote of the portrait's charm. It was
like a reflection in clear water that a touch might disturb, or a young
anemone that a breath might destroy,—not a picture before which
people disputed and proffered noisy opinions, but one which
imposed silence, like the barely audible note of a distant Angelus. It
stood before the memory of its original, as it had been a spirit,
finger on lip, at the doorway of a tomb.
This portrait of his mother dominated the life of Pépin like the half-
remembered substance of a dream. He had known nothing of her in
the life, for the breath of being had passed from her lips to his at the
moment of his birth, but with the intuition of childhood, he seemed
to know that this was one who would have loved him and whom he
would have loved. He spent hours before the picture, silent, spell-
bound, gazing into the deep and tender eyes that shone with the
same pathetic pleading that lay so eloquently in his own, and the
only outbreak of rage which had ever stirred his simple serenity was
on one occasion when his nurse had found him thus absorbed, and,
receiving no response to her summons, half alarmed and half
indignant, reproached him with wasting his time before a stupid
picture. Then Pépin had whirled around upon her, his lips
compressed, his small brown hands clenched, and a look in his eyes
that terrified even the stout and prosaic Cornish-woman out of her
accustomed attitude of fat complacency.
"A stupid picture?" he stormed. "But it is my mother, do you hear,
my mother! You are a wicked woman, Elizabeth!"
It was when Pépin was nearing his seventh birthday that a
wonderful thing happened. The Comte was giving a great reception
to the Russian Ambassador, and on an impulse which, perhaps, even
he himself could hardly have explained, sent for his son. The child
was aroused from sleep, and, but half awake and totally
uncomprehending, was submitted by the worthy Elizabeth to a
veritable cyclone of washing, combing, and brushing, and finally,
clad in spotless duck, was led by the maître d'hôtel down the long
corridor to the door of the grand salon, which, at his approach,
swung open under the touch of one of the under servants. Pépin,
dazed by the radiance of many lights and a great clamor of voices,
paused on the threshold, and, with a swift intuition of what was
demanded of him, made his slow, stiff bow.
"Le Vicomte de Villersexel," said the maître d'hôtel in a loud voice at
his side, and Pépin, seeing his father beckon to him from the group
where he stood, slipped close to him through the crowd, and was
surprised to find that the Comte took his hand in his, and bent
forward to say in a whisper,—
"You are to hear Pazzini play the violin. That is why I sent for you.
He was your mother's teacher."
Like all that had gone before, what followed was to Pépin like a
dream—a beautiful dream, never to be forgotten. A great hush had
settled upon the brilliant assemblage, for even in Paris there are still
things which society will check its chatter to hear, and the tall, gray-
bearded man, consulting with the pianist over there, was Pazzini, the
great Pazzini, whose services had been more than once commanded
by royalty in vain. De Villersexel had drawn Pépin nearer to the
piano in the brief interval, and as the opening chords of the
introduction were struck, he found himself but a few feet from the
famous violinist, his hand still linked in that of his father, his eyes
fixed in wonder upon this unknown man who had been his mother's
teacher.
The first low note of the violin fell upon the silence like a faint, far
voice, heard across a wide reach of calm water, and, as the
marvelous melody swelled into the fullness of its motif, something
new and strange stirred in Pépin's heart, mounted and tightened in
his throat, ran tingling to his finger-tips. Through his half parted lips
the breath tiptoed in and out, and his deep eyes grew every instant,
could he have known it, more like those of the picture that he loved.
So he stood entranced, seeing, hearing nothing but Pazzini and
Pazzini's violin, till the sonata drew imperceptibly toward its close.
Like the child, the great violinist seemed to be unconscious of all
that surrounded him. Slowly, tenderly, he led his music through the
last phrases, until he paused before the supreme high sweetness of
the final note. How it was he could never have told, but, in that
infinitesimal fraction of time, the training of years played him false.
He knew that his finger-tip slipped an incalculable atom of space,
but it was too late. The bow was on the string, and the
imperceptibly flatted note swelled, sank, and died away,
unrecognized, he thought, with a throb of thankfulness, by any save
his master ear. And then—
"Ah-h!" said Pépin.
The long ripple of applause drowned the child's whisper, and for an
instant the terror in his heart grew still, believing his exclamation
unheard. Then it leaped to life again, for Pazzini was looking at him,
his bow hovering above the instrument like his mother's in the
picture. In the mysterious solitude of the crowded room the eyes of
these two met, each reading the other's as they had been an open
book, and in Pépin's was the pain of a wounded animal, and in
Pazzini's a great wonder and sorrow, as of one who has hurt without
intention, and mutely pleads for pardon.
As the applause ceased, the violinist turned to the Comte, and
pointed to Pépin with his bow.
"Who is that child?" he asked.
The thaw in the de Villersexel's "academic manner" had been but
momentary. With the renewed hum of conversation he was himself
again, pale, proud, and immovable.
"It is my son, Pépin," he replied, with stiff courtesy. "How shall I
thank you for your playing? It was the essence of perfection, as it
has ever been, and ever will be."
But he could not know, as he turned away with Pépin, that in his
heart the violinist said, "Her boy! I understand!"
The miracle of his summons to the salon that night was not, as it
appeared, the actual climax of existence, for a new marvel awaited
Pépin on the morrow. The doors of the dining-room had barely slid
together behind them when the Comte turned to him.
"Yesterday was Christmas," he said.
Pépin made no reply. In fact, the stupor which descended upon him
at this infraction of the usual routine of life effectually deprived him,
for the moment, of the power of speech.
"It was Christmas," repeated the Comte, "and because of that you
are invited to a—a—soirée to-day. Do you know the English children
on the entresol?"
"I have seen them," faltered Pépin, "but we have never spoken. You
told me"—
"I have changed my mind," broke in his father. "Monsieur
'Ameelton"—stumbling desperately over the English name—"has
asked me to let you visit them this afternoon, and I have said yes to
him. Elizabeth will dress you. Now you may go."
Barely conscious that Pépin had added a timid "Merci, papa!" to his
customary bow, de Villersexel turned to his writing-table, as the door
closed behind the little Vicomte, and, unlocking a drawer, took
therefrom a letter which had come to him that morning, and,
burying himself in his arm-chair, proceeded to its careful reperusal. It
was in the fine Italian handwriting of Pazzini, and ran as follows:—
My dear Friend,—This is to be at once a confession and a
prayer. What would you say if I were to tell you that
Pazzini—the flawless Pazzini, as men are pleased to call
me!—murdered, yes, murdered last night's sonata by
flatting that wonderful final note? Oh, it was a very little
thing, and passed unnoticed, for they are stupid, these
wise people who listen to me, and they did not hear. Even
you, my poor friend, even you could not detect that tiny
flaw that was a monstrous crime. No, of all who listened,
there were but two that understood what I had done. I
was one of these, and the other was your son—Pépin.
Do you know what that means, Monsieur le Comte de
Villersexel? Do you understand that it is but one ear in
millions that is so finely keyed that this minutest deviation
could wound it like the most utter discord? And I wounded
him, your Pépin. I saw it in his eyes. Therefore I tell you—
I, who know—that he is a genius, a genius greater than
his mother, and that, like her, he must be my pupil. I have
none other now. It shall be the work of my old age to
make him the greatest violinist of his day. Give him to me,
my friend, if not for his own sake, then for hers!
Pazzini.
Prime feature of all the year to the little Hamiltons, on the entresol,
was their Christmas tree. It arrived in some unknowable way in the
corner of the grand salon on the morning after Christmas, and, from
the moment of its advent, the doors were sealed, and only the
privileged world of grown-ups went in and out, and could see the
splendors within. Inch by inch the hands of the tall clock in the
antichambre dragged themselves around successive circles toward
the hour of revelation, and, keyed to the snapping point of frenzy,
the slender figure of George and the round, squat form of John
stood motionless before the inexorable timepiece, awaiting the
stroke of four. This suspense was harrowing enough in itself, and
only made bearable by recourse to occasional mad caperings up and
down the hall, and whoops of mingled ecstasy and exasperation.
What was worse was the delay in the arrival of their guests. Later,
the latter would be an indispensable part of the festivities: just now
they were mere impediments in the path of bliss. Even the grown-
ups were more considerate, and came on time. Well they might,
since they were granted immediate admission to the enchanted
room, and came out with maddening accounts of what was to be
seen therein. They sat about the small salon, and talked the stupid
things of which they were so fond of talking,—Hamilton, tall,
straight, and with an amused twinkle in his eyes, while he watched
his wife vainly endeavoring to calm her sons as they foamed and
pranced at the sealed doors; Miss Kedgwick, who wrote books, and
invited boys to tea; Monsieur de Bercy, who was odd because he
spoke no English, but who cut heads out of nuts and apples, and
drew droll pictures on scraps of paper; Miss Lys, who played the
piano for "Going to Jerusalem;" and Mr. Sedgely, who talked very
low in her ear, and said the great trouble with "Going to Jerusalem"
was that the players couldn't go there in good earnest—whatever
that might mean.
But would the doors never open?
The children arrived by twos and threes, shook hands limply with
their elders, greeted their small hosts with embarrassed ceremony,
and then, as if suddenly inoculated with the latter's madness,
commenced to foam and prance in their turn before the unyielding
portals. Last of all came Pépin, all brown, who bowed at the door,
and then in turn to each of those who spoke to him.
Suddenly, with a shout, the children burst through the opened
doorway, and gathered in voluble groups about the glistening
miracle which shone like a hundred stars in the gathering twilight.
For a half hour all was chaos, and Pépin, standing a little apart,
marveled and was still. Dancing figures whirled about him, bearing
boxes of soldiers, toy villages, dolls, trumpets, drums. The air was
full of the wailing of whistles, the cries of mechanical animals, and
the clamor of childish comment.
But to Pépin even the dazzling novelty of his surroundings was as
nothing, compared to one object which drew and fixed his attention
from the first instant, as the needle is held rigid by the magnetic
pole. High up upon the tree, clearly outlined against its background
of deep green, and gleaming gorgeously with fresh varnish in the
light of the surrounding candles, hung a violin—not one like
Monsieur Pazzini's, large and of a dull brown, but small—a violin for
Pépin himself to hold, and new, and bright, and beyond all things
beautiful and to be desired!
Then his attention was distracted for a moment. From the time of his
entrance the eyes of Miss Lys had followed the dignified and silent
little Frenchman, and where Miss Lys went Mr. Sedgely followed, so
that now the two were so close that they brushed his elbow, and
Pépin, turning with an instinctive "Pardon," saw that they were
watching him curiously. When, with a feeling of restlessness under
their scrutiny, he looked once more towards the tree, the violin was
gone! An instant later, he saw it in the madly sawing hands of
George Hamilton, dancing like a faun down the room, and he was
conscious of a great faintness, such as he had known but once
before,—when he had cut his hand, and the doctor had sewed it, as
Elizabeth sewed rips in cloth.
"He is adorable," said Ethel Lys, "but I have never seen a sadder
face. What eyes!—two brown poems."
"He makes my heart ache," answered Sedgely, slowly, "and yet I
could hardly say why. Ask him what he wants off the tree."
The girl was on her knees by Pépin before the phrase was fairly
finished.
"What didst thou have for Christmas?" she asked, falling
unconsciously into that tender second singular which slips so
naturally from the lips at sight of a French child.
"I?—but nothing," replied the little Vicomte, pleased out of his
anguish by the sound of his own tongue amid the babel of English
phrases.
The girl at his side looked at him with so frank an astonishment that
he felt it necessary to explain.
"I have my gifts on the day of the year. Christmas is an English fête,
and I am French. So I have nothing."
"Nothing!" replied Miss Lys blankly, and then, of a sudden, slipped
her arm around him, and drew his head close to her own.
"What dost thou see on the tree that thou wouldst like to have?" she
asked, eagerly. "What is there, dearest?"
And, at the unwonted tenderness of her question, the floodgates of
Pépin's reserve suddenly gave way. Placing his hands upon the girl's
shoulders, he searched her face with his eyes.
"If there were another violin"—he began, and, faltering, stopped,
and turned away to hide the tears that would come, strive as he
might to hold them back.
"Did you hear him—and see him?" queried Miss Lys, a minute after,
furiously backing Sedgely into a corner by the lapels of his frock
coat. "You did—you know you did! And you are still here? Lord!
What a man!"
Sedgely shrugged his shoulders with a pretense of utter
bewilderment.
"What must I do?" he inquired, blankly.
"Do?" stormed Miss Lys. "Do? Why, scour Paris till you find a violin
precisely like that one George is doing his best to saw in half. Here!
Clément is at the door with the trois-quarts. Tell him to drive you like
mad to the Printemps—to the big place opposite the Grand Hotel—to
the Louvre—to the Bon Marché—anywhere—everywhere! But inside
of one hour I must have that violin!"
When Sedgely returned, thirty minutes later, violin in hand, Ethel
met him at the door.
"They are all at tea," she said. "We'll call Pépin out."
She placed the violin in the hands of the Vicomte without a word,
and without a word Pépin took it from her. The instrument slid to his
cheek as if impelled by its own desire.
"Canst thou play?" she asked him.
"No," said Pépin, "and, besides, it is but a toy. I do not want to hear
it. But I like to feel it—here." And he moved his cheek caressingly
against the cheap varnish.
"Don't you think you might"—began Sedgely, and then found himself
on the other side of the door, and Miss Lys facing him with an air of
hopeless resignation.
"I—act-u-ally—be-lieve," she said, with an effort at calm, "that you
were going to ask him to thank me for it!"
"Why not?" said Sedgely.
"Lord! What a man!" said Miss Lys.
In the dining-room of the de Villersexel apartment the Comte paced
slowly to and fro, with bent head, and fingers that locked and
unlocked behind his back. In the heavy chair before the fire, Pazzini
seemed shrunk to but half his normal size, a mere rack of clothes,
two lean white hands, that gripped the dragons' heads upon the
arms of the fauteuil, and a pale stern face that looked into the
smouldering embers, and beyond—immeasurably beyond.
"How did it happen?" he asked, after a time.
"Shall I ever know?" broke out de Villersexel irritably. "Pépin had
been to a children's party below there on the entresol, at the English
lawyer's. He and his imbecile of a bonne were entering the
ascenseur. She goes from spasm to spasm, so there is no telling. But
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
More than just a book-buying platform, we strive to be a bridge
connecting you with timeless cultural and intellectual values. With an
elegant, user-friendly interface and a smart search system, you can
quickly find the books that best suit your interests. Additionally,
our special promotions and home delivery services help you save time
and fully enjoy the joy of reading.
Join us on a journey of knowledge exploration, passion nurturing, and
personal growth every day!
ebookbell.com

More Related Content

PDF
Cqrs journey guide
PPTX
Applicare patterns di sviluppo con Azure
PPTX
Build 2015 – Azure overview
PPTX
Enterprise Software Development Patterns
PDF
Azure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
PDF
Download full ebook of Azure in Action 1st Edition Chris Hay instant download...
PPTX
Azure architecture design patterns - proven solutions to common challenges
PDF
Programming Windows Azure Programming The Microsoft Cloud 1st Edition Sriram ...
Cqrs journey guide
Applicare patterns di sviluppo con Azure
Build 2015 – Azure overview
Enterprise Software Development Patterns
Azure tales: a real world CQRS and ES Deep Dive - Andrea Saltarello
Download full ebook of Azure in Action 1st Edition Chris Hay instant download...
Azure architecture design patterns - proven solutions to common challenges
Programming Windows Azure Programming The Microsoft Cloud 1st Edition Sriram ...

Similar to Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts (20)

PDF
Developing Applications for the Cloud on the Microsoft Windows Azure Platform...
PDF
Business Process Configuration in the Cloud: How to Support and Analyze Multi...
PPTX
Pragmatic Approach to Microservices and Cell-based Architecture
PPTX
Introducing Windows Azure
PPTX
Novelty in Non-Greenfield
PPTX
Directions on microsoft_web_and_cloud_development
PDF
Programming Windows Azure Programming the Microsoft Cloud 1st Edition Sriram ...
PDF
Moving Applications to the Cloud on Windows Azure 3rd Edition Dominic Betts
PDF
70-534_architecturing Azure le complet.pdf
PDF
Moving Applications to the Cloud on Windows Azure 3rd Edition Dominic Betts
PPTX
DevDays 2011- Let’s get ready for the cloud: Building your applications so th...
PPTX
Architectural Patterns for the Cloud
PPTX
Designing microservices part2
PPTX
2 speed it powered by microsoft azure
PDF
Moving apps to the cloud 3rd edition
PPTX
2014.11.14 Data Opportunities with Azure
PDF
The Yin and Yang of Software
PDF
Digitization solutions - A new breed of software
PPTX
Seminar - Scalable Enterprise Application Development Using DDD and CQRS
PPTX
Super charged prototyping
Developing Applications for the Cloud on the Microsoft Windows Azure Platform...
Business Process Configuration in the Cloud: How to Support and Analyze Multi...
Pragmatic Approach to Microservices and Cell-based Architecture
Introducing Windows Azure
Novelty in Non-Greenfield
Directions on microsoft_web_and_cloud_development
Programming Windows Azure Programming the Microsoft Cloud 1st Edition Sriram ...
Moving Applications to the Cloud on Windows Azure 3rd Edition Dominic Betts
70-534_architecturing Azure le complet.pdf
Moving Applications to the Cloud on Windows Azure 3rd Edition Dominic Betts
DevDays 2011- Let’s get ready for the cloud: Building your applications so th...
Architectural Patterns for the Cloud
Designing microservices part2
2 speed it powered by microsoft azure
Moving apps to the cloud 3rd edition
2014.11.14 Data Opportunities with Azure
The Yin and Yang of Software
Digitization solutions - A new breed of software
Seminar - Scalable Enterprise Application Development Using DDD and CQRS
Super charged prototyping
Ad

Recently uploaded (20)

PPTX
Pharma ospi slides which help in ospi learning
PDF
01-Introduction-to-Information-Management.pdf
PDF
O5-L3 Freight Transport Ops (International) V1.pdf
PDF
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
PPTX
Institutional Correction lecture only . . .
PDF
Anesthesia in Laparoscopic Surgery in India
PDF
Computing-Curriculum for Schools in Ghana
PDF
Module 4: Burden of Disease Tutorial Slides S2 2025
PDF
Classroom Observation Tools for Teachers
PDF
A systematic review of self-coping strategies used by university students to ...
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
PPTX
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
PPTX
Pharmacology of Heart Failure /Pharmacotherapy of CHF
PDF
FourierSeries-QuestionsWithAnswers(Part-A).pdf
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PDF
Complications of Minimal Access Surgery at WLH
PDF
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
PPTX
202450812 BayCHI UCSC-SV 20250812 v17.pptx
PPTX
Introduction-to-Literarature-and-Literary-Studies-week-Prelim-coverage.pptx
PPTX
Final Presentation General Medicine 03-08-2024.pptx
Pharma ospi slides which help in ospi learning
01-Introduction-to-Information-Management.pdf
O5-L3 Freight Transport Ops (International) V1.pdf
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
Institutional Correction lecture only . . .
Anesthesia in Laparoscopic Surgery in India
Computing-Curriculum for Schools in Ghana
Module 4: Burden of Disease Tutorial Slides S2 2025
Classroom Observation Tools for Teachers
A systematic review of self-coping strategies used by university students to ...
human mycosis Human fungal infections are called human mycosis..pptx
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
Pharmacology of Heart Failure /Pharmacotherapy of CHF
FourierSeries-QuestionsWithAnswers(Part-A).pdf
STATICS OF THE RIGID BODIES Hibbelers.pdf
Complications of Minimal Access Surgery at WLH
Saundersa Comprehensive Review for the NCLEX-RN Examination.pdf
202450812 BayCHI UCSC-SV 20250812 v17.pptx
Introduction-to-Literarature-and-Literary-Studies-week-Prelim-coverage.pptx
Final Presentation General Medicine 03-08-2024.pptx
Ad

Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts

  • 1. Exploring Cqrs And Event Sourcing A Journey Into High Scalability Availability And Maintainability With Windows Azure 1st Edition Dominic Betts download https://ebookbell.com/product/exploring-cqrs-and-event-sourcing- a-journey-into-high-scalability-availability-and-maintainability- with-windows-azure-1st-edition-dominic-betts-4686082 Explore and download more ebooks at ebookbell.com
  • 2. Here are some recommended products that we believe you will be interested in. You can click the link to download. The Best Car Book In The World Exploring The Worlds Most Expensive Cars The Worlds Rarest Cars And Cars Of The Future Hedditch https://ebookbell.com/product/the-best-car-book-in-the-world- exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and- cars-of-the-future-hedditch-42118868 The Best Car Book In The World Exploring The Worlds Most Expensive Cars The Worlds Rarest Cars And Cars Of The Future Pdfdrivecom Hedditch https://ebookbell.com/product/the-best-car-book-in-the-world- exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and- cars-of-the-future-pdfdrivecom-hedditch-43618202 The Best Car Book In The World Exploring The Worlds Most Expensive Cars The Worlds Rarest Cars And Cars Of The Future Peter Hedditch https://ebookbell.com/product/the-best-car-book-in-the-world- exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and- cars-of-the-future-peter-hedditch-42118944 The Best Car Book In The World Exploring The Worlds Most Expensive Cars The Worlds Rarest Cars And Cars Of The Future Hedditch https://ebookbell.com/product/the-best-car-book-in-the-world- exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and- cars-of-the-future-hedditch-42083162
  • 3. The Best Car Book In The World Exploring The Worlds Most Expensive Cars The Worlds Rarest Cars And Cars Of The Future Peter Hedditch https://ebookbell.com/product/the-best-car-book-in-the-world- exploring-the-worlds-most-expensive-cars-the-worlds-rarest-cars-and- cars-of-the-future-peter-hedditch-5552660 Exploring Meditation Exploring Series Susan Shumsky https://ebookbell.com/product/exploring-meditation-exploring-series- susan-shumsky-44908504 Exploring Geographic Information Systems 2nd Edition Nicholas Chrisman https://ebookbell.com/product/exploring-geographic-information- systems-2nd-edition-nicholas-chrisman-44967472 Exploring Scale Symmetry Thomas Lowe https://ebookbell.com/product/exploring-scale-symmetry-thomas- lowe-44975766 Exploring Susceptibleinfectiousrecovered Sir Model For Covid19 Investigation Rahul Saxena https://ebookbell.com/product/exploring- susceptibleinfectiousrecovered-sir-model-for-covid19-investigation- rahul-saxena-45333430
  • 5. Exploring CQRS and Event Sourcing A journey into high scalability, availability, and maintainability with Windows Azure
  • 7. Exploring CQRS and Event Sourcing A journey into high scalability, availability, and maintainability with Windows Azure Dominic Betts Julián Domínguez Grigori Melnik Fernando Simonazzi Mani Subramanian
  • 8. 978-1-62114-016-0 This document is provided “as-is”. Information and views expressed in this document, including URL and other Internet Web site references, may change without notice. Some examples depicted herein are provided for illustration only and are fictitious. No real association or connection is intended or should be inferred. This document does not provide you with any legal rights to any intellectual property in any Microsoft product. You may copy and use this document for your internal, reference purposes. You may modify this document for your internal, reference purposes © 2012 Microsoft. All rights reserved. Microsoft, MSDN, SQL Azure, SQL Server, Visual Studio, Windows, and Windows Azure are trademarks of the Microsoft group of companies. All other trademarks are property of their respective owners.
  • 9. v What other readers are saying about this guide xvii Foreword by Greg Young xxi Preface xxiii Why we created this guidance now xxiii How is this guidance structured? xxiii A CQRS journey xxiv CQRS reference xxv Tales from the trenches xxv A CQRS journey xxv CQRS reference xxvi Tales from the trenches xxvi Selecting the domain for the RI xxvi Arrow legend xxvii Where to go for more information xxviii The Crew xxix Journey 1: Our Domain: Conference Management System 1 The Contoso Corporation 1 Who is coming with us on the journey? 2 The Contoso Conference Management System 3 Overview of the system 3 Selling seats for a conference 4 Creating a conference 4 Nonfunctional requirements 4 Scalability 4 Flexibility 5 Beginning the journey 5 More information 5 Contents
  • 10. vi Journey 2: Decomposing the Domain 7 Definitions used in this chapter 7 Bounded contexts in the conference management system 8 Bounded contexts not included 9 The context map for the Contoso Conference Management System 10 Why did we choose these bounded contexts? 11 More information 11 Journey 3: Orders and Registrations Bounded Context 13 A description of the bounded context 13 Working definitions for this chapter 14 Domain definitions (ubiquitous language) 15 Requirements for creating orders 17 Architecture 18 Patterns and concepts 18 Validation 23 Transaction boundaries 24 Concurrency 25 Aggregates and aggregate roots 25 Implementation details 25 High-level architecture 26 1. Querying the read model 27 2. Issuing commands 28 3. Handling commands 28 4. Initiating business logic in the domain 29 5. Persisting the changes 29 6. Polling the read model 29 Inside the write model 31 Aggregates 31 Aggregates and process managers 34 Infrastructure 40 Using the Windows Azure Service Bus 42 Delivering a command to a single recipient 44 Why have separate CommandBus and EventBus classes? 48 How scalable is this approach? 48 How robust is this approach? 48 What is the granularity of a topic and a subscription? 48 How are commands and events serialized? 49 Impact on testing 49 Summary 52 More information 52
  • 11. vii Journey 4: Extending and Enhancing the Orders and Registrations Bounded Context 53 Changes to the bounded context 53 Working definitions for this chapter 53 User stories 54 Implement a login using a record locator 54 Tell the registrant how much time remains to complete an order 55 Enable a registrant to create an order that includes multiple seat types 55 Architecture 55 Patterns and concepts 56 Record locators 56 Querying the read side 56 Storing denormalized views in a database 57 Making information about partially fulfilled orders available to the read side 60 CQRS command validation 61 The countdown timer and the read model 62 Implementation details 62 The order access code record locator 63 The countdown timer 64 Using ASP.NET MVC validation for commands 66 Pushing changes to the read side 69 Querying the read side 72 Refactoring the SeatsAvailability aggregate 73 The AddSeats method 74 Impact on testing 74 Acceptance tests and the domain expert 74 Defining acceptance tests using SpecFlow features 74 Making the tests executable 76 Using tests to help developers understand message flows 81 A journey into code comprehension: A tale of pain, relief, and learning 83 Testing is important 83 Domain tests 84 The other side of the coin 86 Summary 90 More information 90 Journey 5: Preparing for the V1 Release 91 The Contoso Conference Management System V1 release 91 Working definitions for this chapter 91 User stories 92 Ubiquitous language definitions 92 Conference Management bounded context user stories 92 Ordering and Registration bounded context user stories 92
  • 12. viii Architecture 93 Conference Management bounded context 97 Patterns and concepts 97 Event sourcing 97 Identifying aggregates 98 Task-based UI 99 CRUD 101 Integration between bounded contexts 101 Pushing changes from the Conference Management bounded context 102 Pushing changes to the Conference Management bounded context 104 Choosing when to update the read-side data 105 Distributed transactions and event sourcing 105 Autonomy versus authority 105 Favoring autonomy 106 Favoring authority 106 Choosing between autonomy and authority 106 Approaches to implementing the read side 107 Eventual consistency 107 Implementation details 108 The Conference Management bounded context 108 Integration with the Orders and Registration bounded context 108 The Payments bounded context 109 Integration with online payment services, eventual consistency, and command validation 111 Event sourcing 113 Raising events when the state of an aggregate changes 113 Persisting events to the event store 117 Replaying events to rebuild state 118 Issues with the simple event store implementation 120 Windows Azure table storage-based event store 120 Calculating totals 122 Impact on testing 123 Timing issues 123 Involving the domain expert 123 Summary 124 More information 124 Journey 6: Versioning Our System 125 Working definitions for this chapter 125 User stories 126 No down time upgrade 126 Display remaining seat quantities 126 Handle zero-cost seats 126 Architecture 126
  • 13. ix Patterns and concepts 127 Handling changes to events definitions 128 Mapping/filtering event messages in the infrastructure 128 Handling multiple message versions in the aggregates 128 Honoring message idempotency 128 Avoid processing events multiple times 129 Persisting integration events 131 Message ordering 133 Implementation details 133 Adding support for zero-cost orders 134 Changes to the RegistrationProcessManager class 134 Changes to the UI 134 Data migration 136 Displaying remaining seats in the UI 138 Adding information about remaining seat quantities to the read model 138 Modifying the UI to display remaining seat quantities 140 Data migration 140 De-duplicating command messages 141 Guaranteeing message ordering 142 Persisting events from the Conference Management bounded context 146 Adding additional metadata to the messages 146 Capturing and persisting messages to the message log 146 Data migration 148 Migrating from V1 to V2 150 Generating past log messages for the Conference Management bounded context 151 Migrating the event sourcing events 151 Rebuilding the read models 151 Impact on testing 151 SpecFlow revisited 152 Discovering a bug during the migration 155 Summary 155 More information 155 Journey 7: Adding Resilience and Optimizing Performance 157 Working definitions for this chapter 157 Architecture 158 Adding resilience 159 Making the system resilient when an event is reprocessed 161 Ensuring that commands are always sent 161 Optimizing performance 162 UI flow before optimization 162 Optimizing the UI 163 UI optimization 1 164 UI optimization 2 165
  • 14. x Optimizing the infrastructure 165 Sending and receiving commands and events asynchronously 165 Optimizing command processing 166 Using snapshots with event sourcing 166 Publishing events in parallel 167 Filtering messages in subscriptions 167 Creating a dedicated receiver for the SeatsAvailability aggregate 167 Caching conference information 167 Partitioning the Service Bus 168 Other optimizations 168 Further changes that would improve performance 169 Further changes that would enhance scalability 171 No down-time migration 172 Rebuilding the read models 173 Implementation details 174 Hardening the RegistrationProcessManager class 174 Detecting out-of-order SeatsReserved events 175 Detecting duplicate OrderPlaced events 178 Creating a pseudo transaction when the RegistrationProcessManager class saves its state and sends a command 178 Optimizing the UI flow 181 Receiving, completing, and sending messages asynchronously 186 Receiving messages asynchronously 186 Completing messages asynchronously 186 Sending messages asynchronously 186 Handling commands synchronously and in-process 186 Implementing snapshots with the memento pattern 189 Publishing events in parallel 191 Filtering messages in subscriptions 192 Creating a dedicated SessionSubscriptionReceiver instance for the SeatsAvailability aggregate 193 Caching read-model data 194 Using multiple topics to partition the service bus 195 Other optimizing and hardening changes 196 Sequential GUIDs 196 Asynchronous ASP.NET MVC controllers. 198 Using prefetch with Windows Azure Service Bus 198 Accepting multiple sessions in parallel 199 Adding an optimistic concurrency check 199 Adding a time-to-live value to the MakeSeatReservation command 199 Reducing the number of round-trips to the database 199
  • 15. xi Impact on testing 200 Integration tests 200 User interface tests 200 Summary 200 More information 200 Journey 8: Epilogue: Lessons Learned 201 What did we learn? 201 Performance matters 201 Implementing a message-driven system is far from simple 202 The cloud has challenges 203 CQRS is different 204 Event sourcing and transaction logging 205 Involving the domain expert 206 When to use CQRS 206 What would we do differently if we started over? 207 Start with a solid infrastructure for messaging and persistence 207 Leverage the capabilities of the infrastructure more 207 Adopt a more systematic approach to implementing process managers 208 Partition the application differently 208 Organize the development team differently 208 Evaluate how appropriate the domain and the bounded contexts are for the CQRS pattern 208 Plan for performance 208 Think about the UI differently 209 Explore some additional benefits of event sourcing 209 Explore the issues associated with integrating bounded contexts 210 More information 210 Reference 1: CQRS in Context 211 What is domain-driven design? 212 Domain-driven design: concepts and terminology 212 Domain model 213 Ubiquitous language 213 Entities, value objects, and services 214 Aggregates and aggregate roots 215 Bounded contexts 215 Anti-corruption layers 217 Context maps 218 Bounded contexts and multiple architectures 218 Bounded contexts and multiple development teams 219 Maintaining multiple bounded contexts 220 CQRS and DDD 220 More information 221
  • 16. xii Reference 2: Introducing the Command Query Responsibility Segregation Pattern 223 What is CQRS? 223 Read and write sides 225 CQRS and domain-driven design 227 Introducing commands, events, and messages 228 Why should I use CQRS? 230 Scalability 230 Reduced complexity 231 Flexibility 231 Focus on the business 232 Facilitates building task-based UIs 232 Barriers to adopting the CQRS pattern 232 When should I use CQRS? 232 Collaborative domains 233 Stale data 233 Moving to the cloud 234 When should I avoid CQRS? 234 Summary 234 More information 234 Reference 3: Introducing Event Sourcing 235 What is event sourcing? 236 Comparing using an ORM layer with event sourcing 236 Why should I use event sourcing? 240 Event sourcing concerns 242 CQRS/ES 243 Standalone event sourcing 245 Event stores 245 Basic requirements 245 Underlying storage 245 Performance, scalability, and consistency 245 More information 246 Reference 4: A CQRS and ES Deep Dive 247 Introduction 247 Read models and write models 247 Commands and data transfer objects 247 Domain-driven design (DDD) and aggregates 248 Data and normalization 248 Events and event sourcing 248 Eventual consistency 248 Defining aggregates in the domain model 249 Aggregates and object-relational mapping layers 249 Aggregates and event sourcing 250
  • 17. xiii Commands and command handlers 252 Commands 253 Example code 253 Command handlers 254 Commands and optimistic concurrency 256 Events and event handlers 256 Events and intent 256 How to model intent 258 Events 259 Sample Code 259 Event handlers 260 Sample code 260 Embracing eventual consistency 261 Eventual consistency and CQRS 263 Optimizing the read-side 266 Optimizing the write side 267 Concurrency and aggregates 267 Messaging and CQRS 268 Messaging considerations 268 Duplicate messages 268 Lost messages 269 Out-of-order messages 269 Unprocessed messages 269 Event versioning 269 Redundant events 270 New event types 270 Changing existing event definitions 270 Task-based UIs 271 Taking advantage of Windows Azure 272 Scaling out using multiple role instances 273 Implementing an event store using Windows Azure table storage 273 Persisting events 274 Retrieving events 275 Publishing events 276 Implementing a messaging infrastructure using the Windows Azure Service Bus 278 A word of warning 279 More information 279 Reference 5: Communicating Between Bounded Contexts 281 Introduction 281 Context maps 281 The anti-corruption layer 281
  • 18. xiv Integration with legacy systems 282 Reading the database 282 Generating events from the database 282 Modifying the legacy systems 282 Implications for event sourcing 282 More information 283 Reference 6: A Saga on Sagas 285 Clarifying the terminology 285 Process Manager 286 Messages and CQRS 286 What is a process manager? 286 When should I use a process manager? 290 When should I not use a process manager? 290 Sagas and CQRS 290 More information 290 Reference 7: Technologies Used in the Reference Implementation 291 Windows Azure Service Bus 291 Queues 292 Topics and Subscriptions 293 Useful API features 294 Reading messages 294 Sending messages 294 Expiring messages 294 Delayed message processing 294 Serializing messages 295 Further information 295 Unity Application Block 296 Further information 296 More information 296 Tales from the Trenches 297 Twilio 297 Product overview 297 Lessons learned 297 Separating reads and writes 297 Designing for high availability 297 Idempotency 298 No-downtime deployments 298 Performance 298 References 299 More information 299
  • 19. xv Tales from the Trenches: Lokad Hub 300 Project overview 300 Lessons learned 300 Benefits of DDD 301 Reducing dependencies 301 Using sagas 301 Testing and documentation 301 Migration to ES 301 Using projections 301 Event sourcing 301 Infrastructure 302 References 302 More information 302 Tales from the Trenches: DDD/CQRS for large financial company 303 Project overview 303 Lessons learned 304 Query performance 304 Commands 304 Working with legacy databases 304 Using an Inversion of Control (IoC) container 304 Key lessons learned 305 More information 305 Tales from the Trenches: Digital Marketing 306 Single Responsibility of Objects 309 More information 309 Tales from the Trenches: TOPAZ Technologies 310 What did we hope to accomplish by using CQRS/ES? 310 What were the biggest challenges and how did we overcome them? 310 What were the most important lessons learned? 311 With hindsight, what would we have done differently? 311 Further information 311 More information 311 Tales from the Trenches: eMoney Nexus 312 eMoney Nexus: Some CQRS lessons 312 About eMoney & the Nexus 312 System overview 313 The evolution of the system 314 Lessons learned 320 Making it better 321
  • 20. xvi Appendix 1: Release Notes 323 System evolution 323 Building and running the sample code (RI) 323 Prerequisites 324 Obtaining the code 325 Creating the databases 325 SQL Express Database 325 Windows Azure SQL Database instance 325 Creating the Settings.xml File 327 Building the RI 327 Build Configurations 328 Release 328 Debug 328 DebugLocal 328 Running the RI 328 Scenario 1. Local Web Server, SQL Event Bus, SQL Event Store 328 Scenario 2. Local Web Server, Windows Azure Service Bus, Table Storage Event Store 329 Scenario 3. Compute Emulator, SQL Event Bus, SQL Event Store 329 Scenario 4. Compute Emulator, Windows Azure Service Bus, Table Storage Event Store 329 Scenario 5. Windows Azure, Windows Azure Service Bus, Table Storage Event Store 329 Running the Tests 329 Running the Unit and Integration Tests 329 Running the Acceptance Tests 330 Known issues 330 More information 330 Appendix 2: Migrations 331 Migrating from the V1 to the V2 release 331 Running the migration program to migrate the data 331 If the data migration fails 332 Migrating from the V2 to the V3 Release 333 More information 333 Index 335
  • 21. xvii This is another excellent guide from the patterns & practices team—real software engineering with no comforting illusions taken or offered. This guide provides a detailed journal of the practitioners implementing a real production system using the CQRS and Event Sourcing patterns, and also high- lights the tradeoffs and teaches the principles that underlie them. The topics presented are relevant and useful, especially if you are building highly scalable Windows Azure applications. You’ll be both challenged and inspired! —Scott Guthrie, Corporate Vice-President, Azure App Platform, Microsoft Having participated and co-authored various guides from patterns & practices, the “CQRS Journey” follows the same walkthrough, scenario-based style, but adding even more fresh empirical content. It’s a true testament of a skilled development team without previous CQRS experience, going through the journey of implementing a complex system and documenting their adventures and lessons learnt in this diary. If I had to recommend to someone where to start with CQRS, I would definitely point them to this guide. —Matias Woloski, CTO, Auth10 LLC The “CQRS Journey” guide is an excellent resource for developers who want to begin developing a CQRS system or convert their current system. It’s a true “trial by fire” approach to the concepts and implementation hurdles that a team would encounter when adopting CQRS. I would recommend reading it twice as I picked up even more lessons the second time through. —Dan Piessens, Lead Software Architect, Zywave I think it’s a really big step in communication with the developer community. You not only share your development experience with a broad audience (which is very valuable by itself) but you’re also open for learning from the community. While working on real projects it’s difficult to stop, find some time to structure your knowledge, prepare it in the form understandable for others. It’s very cool that you found time and resources for such educational effort, I really appreciate this. —Ksenia Mukhortova, Business Applications Developer, Intel I’m very excited about A CQRS Journey for a number of reasons. It explores, with an even hand and a fair mind, a topic where opinions are both diverse and numerous. True to its name, the guide captures the progression of learning. Conclusions are not simply stated; they arrive as a result of experience. Additionally, the project embraced a passionate community with a spirit of inclusion and transparency. The result is friendly-to-read guidance that is both diligent in execution and rigorous in its research. —Christopher Bennage, Software Development Engineer, Microsoft What other readers are saying about this guide
  • 22. xviii The journey project used Windows Azure SQL Database (backing write & read models), Service Bus (for reliable messaging), and Tables (for event store). Production-quality, scalable cloud services that can be provisioned on-demand with a few mouse-clicks (or API calls) can turn some tough infrastruc- ture problems into trivial ones. —Bill Wilder, MVP, Independent Consultant Perhaps the best lessons out of this guidance will be just how easy it is to work with Microsoft now that they are embracing more community and open source. —Adam Dymitruk, Systems Architect The work that patterns & practices is doing here is very important as it is packaging the concepts in a digestible fashion and helping developers to wade through the ambiguities of CQRS. The real world experiences captured within the journey project will be invaluable to folks looking at applying CQRS within their application development” —Glenn Block, Senior Program Manager, Microsoft, Windows Azure SDK for Node.js, Organizer at ALT.NET Seattle Chapter The p&p team’s dedication and hard work go hand-in-hand with the very high level of competency present on the team. Their attention to detail, insistence on clarity, and open collaboration with the community all led to the creation of material representing enormous value to consumers of the guid- ance. I definitely plan on referencing this material and code in future engagements because I think my clients will derive many benefits from it–a win-win for everyone! —Josh Elster, Principal, Liquid Electron CQRS is a very important pattern, and a tool that any cloud developer should have in his or her tool- belt. It is particularly well-suited for the cloud since it allows for the implementation of massively scalable solutions based on simple, common patterns (like queues, event handlers, and view models, to name a few). Like all patterns, there are several concrete, correct ways of implementing CQRS. A journey of the type undertaken by Microsoft’s patterns & practices team is a great way to explore the different options, tradeoffs, and even possible mistakes one can make along the way, and accelerate one’s learning of the CQRS pattern. —Shy Cohen, Principal, Shy Cohen Consulting patterns & practices assembled many of the active and key people in the CQRS community to join them on the their journey with CQRS and along the way discovered confusing terminology and con- cepts that created opportunities for leaders in the community to bring clarity to a broad audience. The material produced is influenced from the results of building a real world application and ex- presses the experiences from advisors and the patterns & practices team during the development process. By request from the community to allow outside contributions, everything has been open sourced on GitHub. Anyone interested is encouraged to take a look at the guide or implementation. The patterns & practices team has been very welcoming to anyone who wants to collaborate on covering additional areas, alternative implementations or further extending what is currently in place. —Kelly Sommers, Developer
  • 23. xix Congratulations on getting to what looks to be nice guidance. I know that the announcement that p&p was going to embark on this project caused a twitter firestorm but you seem to have come through it well. I’m a fan of the p&p books and think you’ve done a great job in sharing good prac- tices with the community. —Neil Mackenzie, Windows Azure MVP CQRS is as much about architecture community as it is about concrete patterns—thus the project is aptly named “CQRS Journey.” The community involvement and engagement in this project is unprec- edented for Microsoft and reflects the enthusiasm amongst the many (if may say: young) software architects from across the industry who are rediscovering proven architecture patterns and are recom- posing them in new ways to solve today’s challenges. For me, one takeaway from this project is that the recipes developed here need to be carefully weighed against their alternatives. As with any soft- ware architecture approaches that promise easy scalability or evolvability of solutions, the proof will be in concrete, larger production implementations and how they hold up to changing needs over time. Thus, the results of this Journey project mark a start and not a finish line. —Clemens Vasters, Principal Technical Lead, Microsoft Corporation The experiences and conclusions of the p&p team match up very well with our own real-world expe- riences. Their conclusions in Chapter 8 are spot on. One of the best aspects of this guidance is that the p&p team exposes more of their thought processes and learning throughout the Journey than most write-ups that you may read. From arguments between Developer 1 and Developer 2 on the team, to discussions with experts such as Greg Young and Udi Dahan, to an excellent post-project review in Chapter 8, the thought process is out there for you to learn from. Thanks for this great work, guys. I hope you keep this style with your upcoming guidance pieces. —Jon Wagner, SVP & Chief Architect, eMoney Advisor The CQRS journey release by patterns & practices provides real world insight into the increasingly popular CQRS pattern used in distributed systems that rely upon asynchronous, message based ap- proaches to achieve very large scale. The exploration of the issues the team faced throughout the implementation of the pattern is extremely useful for organizations considering CQRS, both to de- termine where the pattern is appropriate for them, and to go into the design and implementation with a baseline understanding of the complexity it will introduce. I really enjoyed the candor around the approach taken, the issues encountered, and the early design choices that the team would change in hindsight. This is a must read for any organization embarking upon CQRS, regardless of what platform they are using. —Chris Keyser, VP Engineering, CaseNetwork It is a great resource on tactical and technical aspects of building a distributed system. —Rinat Abdullin, Technology Leader, Lokad I’d like to personally thank the team for putting together such a transparent journey throughout this project. I’m very pleased with the final release. —Truong Nguyen, CEO, Nepsoft It’s a good read. Lots to learn from it. —Christian Horsdal Gammelgaard, Lead Software Architect, Mjølner Informatics
  • 25. Foreword by Greg Young I started off the new year on January 3rd with a few hour long meeting showing the team at patterns & practices a bit about Command and Query Responsibility Segregation (CQRS) and Event Sourcing (ES). Most of the team had previously not been exposed to these ideas. Today is almost exactly six months later and they have produced a document of over 200 pages of discussions and guidance as well as a full end to end example hosted in Windows Azure. This is certainly not a small feat. When the announcement of the project came out, the twitter stream near instantly went nega- tive as many thought that Microsoft was building a CQRS framework; which was premature from the community. The process followed similar paths to other patterns & practices projects with a large advisor board being set up. I believe however that the most interesting part of the process was the decision to host the work on GitHub and allow pull requests which is an extremely open and transpar- ent way of communicating during the project. One of the main benefits for the community as a whole of going through such a process is that people were forced to refine their vocabularies. There are in the DDD/CQRS/ES communities many different voices and often times, especially in younger groups, vocabularies will go down divergent paths leading to fractured community. An example of nebulous terminologies can be seen in the terms ”saga,” ”process manager,” and ”workflow”; the community as a whole I believe benefited from the discussions over defining what it actually is. One of the most interesting conversations brought up for me person- ally was defining the difference between an Event Store and a Transaction Log as legitimate arguments can be made that either is a higher level abstraction of the other. This has led not only to many interest- ing discussions in the community but to a far stricter future definition of what an Event Store is. ”For the things we have to learn before we can do them, we learn by doing them. ~Aristotle” The quote above was the team motto during the project. Many will be looking towards the guidance presented as being authoritative guidance of how things should be done. This is however not the optimal way to look at the guidance as presented (though it does contain many bits of good authori- tative guidance). The main benefit of the guidance is the learning experience that it contains. It is important to remember that the team came into the ideas presented as non-experienced in CQRS and they learned in the process of doing. This gives a unique perspective throughout much of the text where things are learned along the way or are being seen through fresh eyes of someone recently having learned and attempted to apply the ideas. This perspective has also brought up many interest- ing conversations within the community. The patterns & practices team deserves credit for digging deep, facilitating these discussions, and bringing to light various incongruities, confusions and incon- sistencies as they went along. xxi
  • 26. xxii Keeping in mind the origination point of the team, the most valuable bits in the text that a reader should focus on aside from general explanations are places where tradeoffs are discussed. There is an unfortunate tendency to seek authoritative answers that ”things should be done in this way” when they in fact do not exist. There are many ways to proverbially skin a cat and all have their pros and cons. The text is quite good at discussing alternative points of view that came up as possible answers, or that received heavy discussion within the advisor group, these can often be seen in the “developer 1/developer 2 discussions.” One such discussion I mentioned previously in defining the difference between event sourcing and a transaction log. Many of these types of discussions come at the end of the guidance. How might things be approached differently? One of my favourite discussions towards the end of the guidance dealing with performance is the independent realization that messaging is not equivalent to distribution. This is a very hard lesson for many people to understand and the way that it comes up rather organically and much like it would on most teams as a performance problem is a great explanation. I can say 100 times to apply the first law of distributed computing, don’t distribute; however seeing it from the eyes of a team dealing with a performance problem who has already made the mistake of equating the two is a very understandable path and a great teaching tool. This section also contains a smörgåsbord of information and insights in terms of how to build performant applica- tions in Windows Azure. Out in the wild, there are plenty of naïve samples of CQRS/ES implementations, which are great for describing the concepts. There are details and challenges that will not surface till you work on a complex, real-world production system. The value of the p&p’s sample application is that it uses a fairly complex domain and the team went through multiple releases and focused on infrastructure hardening, performance optimizations, dealing with transient faults and versioning, etc. — many practical issues that you face when implementing CQRS and ES. As with any project, people may disagree with implementation choices and decisions made. It is important to remember the scoping of the project. The guidance is not coming from an expert view- point throughout the process, but that of a group “learning by doing.” The process was and remains open to contributions, and in fact this version has been reviewed, validated, and guided by experts in the community. In the spirit of OSS “send a pull request.” This guide can serve as a valuable point to start discussions, clear up misconceptions, and refine how we explain things, as well as drive improve- ment both in the guidance itself and in getting consistent viewpoints throughout the community. In conclusion I think patterns & practices has delivered to the community a valuable service in the presentation of this guidance. The view point the guidance is written from is both an uncommon and valuable one. It has also really been a good overall exercise for the community in terms of setting the bar for what is being discussed and refining of the vocabularies that people speak in. Combine this with the amount of previously difficult to find Windows Azure guidance and the guidance becomes quite valuable to someone getting into the ideas. Greg Young
  • 27. Preface Why are we embarking on this journey? “The best way to observe a fish is to become a fish.” Jacques Cousteau Why we created this guidance now The Command Query Responsibility Segregation (CQRS) pattern and event sourcing (ES) are cur- rently generating a great deal of interest from developers and architects who are designing and build- ing large-scale, distributed systems. There are conference sessions, blogs, articles, and frameworks all dedicated to the CQRS pattern and to event sourcing, and all explaining how they can help you to improve the maintainability, testability, scalability, and flexibility of your systems. However, like anything new, it takes some time before a pattern, approach, or methodology is fully understood and consistently defined by the community and has useful, practical guidance to help you to apply or implement it. This guidance is designed to help you get started with the CQRS pattern and event sourcing. It is not intended to be the guide to the CQRS pattern and event sourcing, but a guide that describes the experiences of a development team in implementing the CQRS pattern and event sourcing in a real- world application. The development team did not work in isolation; they actively sought input from industry experts and from a wider group of advisors to ensure that the guidance is both detailed and practical. The CQRS pattern and event sourcing are not mere simplistic solutions to the problems associ- ated with large-scale, distributed systems. By providing you with both a working application and written guidance, we expect you’ll be well prepared to embark on your own CQRS journey. How is this guidance structured? There are two closely related parts to this guidance: • A working reference implementation (RI) sample, which is intended to illustrate many of the concepts related to the CQRS pattern and event sourcing approaches to developing complex enterprise applications. • This written guidance, which is intended to complement the RI by describing how it works, what decisions were made during its development, and what trade-offs were considered. xxiii
  • 28. xxiv This written guidance is itself split into three distinct sections that you can read independently: a description of the journey we took as we learned about CQRS, a collection of CQRS reference ma- terials, and a collection of case studies that describe the experiences other teams have had with the CQRS pattern. The map in Figure 1 illustrates the relationship between the first two sections: a journey with some defined stopping points that enables us to explore a space. Figure 1 A CQRS journey A CQRS journey This section is closely related to the RI and the chapters follow the chronology of the project to de- velop the RI. Each chapter describes relevant features of the domain model, infrastructure elements, architecture, and user interface (UI) that the team was concerned with during that phase of the project. Some parts of the system are discussed in several chapters, and this reflects the fact that the team revisited certain areas during later stages. Each of these chapters discuss how and why particu- lar CQRS patterns and concepts apply to the design and development of particular bounded contexts, describe the implementation, and highlight any implications for testing.
  • 29. xxv Other chapters look at the big picture. For example, there is a chapter that explains the rationale for splitting the RI into the bounded contexts we chose, another chapter analyzes the implications of our approach for versioning the system, and other chapters look at how the different bounded con- texts in the RI communicate with each other. This section describes our journey as we learned about CQRS, and how we applied that learn- ing to the design and implementation of the RI. It is not prescriptive guidance and is not intended to illustrate the only way to apply the CQRS approach to our RI. We have tried wherever possible to capture alternative viewpoints through consultation with our advisors and to explain why we made particular decisions. You may disagree with some of those decisions; please let us know at cqrsjourney@microsoft.com. This section of the written guidance makes frequent cross-references to the material in the sec- ond section for readers who wish to explore any of the concepts or patterns in more detail. CQRS reference The second section of the written guidance is a collection of reference material collated from many sources. It is not the definitive collection, but should contain enough material to help you to under- stand the core patterns, concepts, and language of CQRS. Tales from the trenches This section of the written guidance is a collection of case studies from other teams that describe their experiences of implementing the CQRS pattern and event sourcing in the real world. These case studies are not as detailed as the journey section of the guidance and are intended to give an overview of these projects and to summarize some of the key lessons learned. The following is a list of the chapters that comprise both sections of the written guidance: A CQRS journey • Chapter 1, “The Contoso Conference Management System,” introduces our sample applica- tion and our team of (fictional) experts. • Chapter 2, “Decomposing the Domain,” provides a high-level view of the sample application and describes the bounded contexts that make up the application. • Chapter 3, “Orders and Registrations Bounded Context,” introduces our first bounded context, explores some CQRS concepts, and describes some elements of our infrastructure. • Chapter 4, “Extending and Enhancing the Orders and Registrations Bounded Context,” describes adding new features to the bounded context and discusses our testing approach. • Chapter 5, “Preparing for the V1 Release,” describes adding two new bounded contexts and handling integration issues between them, and introduces our event-sourcing implementa- tion. This is our first pseudo-production release. • Chapter 6, “Versioning Our System,” discusses how to version the system and handle upgrades with minimal down time. • Chapter 7, “Adding Resilience and Optimizing Performance,” describes what we did to make the system more resilient to failure scenarios and how we optimized the performance of the system. This was the last release of the system in our journey. • Chapter 8, “Lessons Learned,” collects the key lessons we learned from our journey and suggests how you might continue the journey.
  • 30. xxvi CQRS reference • Chapter 1, “CQRS in Context,” provides some context for CQRS, especially in relation to the domain-driven design approach. • Chapter 2, “Introducing the Command Query Responsibility Segregation Pattern,” provides a conceptual overview of the CQRS pattern. • Chapter 3, “Introducing Event Sourcing,” provides a conceptual overview of event sourcing. • Chapter 4, “A CQRS and ES Deep Dive,” describes the CQRS pattern and event sourcing in more depth. • Chapter 5, “Communicating between Bounded Contexts,” describes some options for communicating between bounded contexts. • Chapter 6, “A Saga on Sagas,” explains our choice of terminology: process manager instead of saga. It also describes the role of process managers. • Chapter 7, “Technologies Used in the Reference Implementation,” provides a brief overview of some of the other technologies we used, such as the Windows Azure Service Bus. • Appendix 1, “Release Notes,” contains detailed instructions for downloading, building, and running the sample application and test suites. • Appendix 2, “Migrations,” contains instructions for performing the code and data migrations between the pseudo-production releases of the Contoso Conference Management System. Tales from the trenches • Chapter 1, “Twilio,” describes a highly available, cloud-hosted, communications platform. Although the team who developed this product did not explicitly use CQRS, many of the architectural concepts they adopted are very closely related to the CQRS pattern. • Chapter 2, “Lokad Hub,” describes a project that made full use of domain-driven design, CQRS, and event sourcing in an application designed to run on multiple cloud platforms. • Chapter 3, “DDD/CQRS for large financial company,” describes a project that made full use of domain-driven design and CQRS to build a reference application for a large financial company. It used CQRS to specifically address the issues of performance, scalability, and reliability. • Chapter 4, “Digital Marketing,” describes how an existing application was refactored over time while delivering new features. This project adopted the CQRS pattern for one of its pieces as the project progressed. • Chapter 5, “TOPAZ Technologies,” describes a project that used the CQRS pattern and event sourcing to simplify the development of an off-the-shelf enterprise application. • Chapter 6, “eMoney Nexus,” describes migration project for an application that used legacy three-tier architecture to an architecture that used the CQRS pattern and event sourcing. Many of the conclusions drawn in this project are similar to our own experiences on our CQRS journey. Selecting the domain for the RI Before embarking on our journey, we needed to have an outline of the route we planned to take and an idea of what the final destination should be. We needed to select an appropriate domain for the RI. We engaged with the community and our advisory board to help us choose a domain that would enable us to highlight as many of the features and concepts of CQRS as possible. To help us select be- tween our candidate domains, we used the criteria in the following list. The domain selected should be:
  • 31. xxvii • Non-trivial. The domain must be complex enough to exhibit real problems, but at the same time simple enough for most people to understand without weeks of study. The problems should involve dealing with temporal data, stale data, receiving out-of-order events, and versioning. The domain should enable us to illustrate solutions using event sourcing, sagas, and event merging. • Collaborative. The domain must contain collaborative elements where multiple actors can operate simultaneously on shared data. • End to end. We wanted to be able illustrate the concepts and patterns in action from the back-end data store through to the user interface. This might include disconnected mobile and smart clients. • Cloud friendly. We wanted to have the option of hosting parts of the RI on Windows Azure and be able to illustrate how you can use CQRS for cloud-hosted applications. • Large. We wanted to be able to show how our domain can be broken down into multiple bounded contexts to highlight when to use and when not use CQRS. We also wanted to illustrate how multiple architectural approaches (CQRS, CQRS/ES, and CRUD) and legacy systems can co-exist within the same domain. We also wanted to show how multiple develop- ment teams could carry out work in parallel. • Easily deployable. The RI needed to be easily deployable so that you can install it and experi- ment with it as you read this guidance. As a result, we chose to implement the conference management system that Chapter 1, “Our Domain: The Contoso Conference Management System,” introduces. Arrow legend Many illustrations in the guidance have arrows. Here is their associated meaning. Figure 2 Legend for arrows Event message Command message Method call Flow of data Object relationship
  • 32. xxviii Where to go for more information There are a number of resources listed in text throughout the book. These resources will provide additional background, bring you up to speed on various technologies, and so forth. For your conve- nience, there is a bibliography online that contains all the links so that these resources are just a click away. You can find the bibliography on MSDN at: http://msdn.microsoft.com/en-us/library/jj619274.
  • 33. xxix The Crew Captain Ernest Shackleton’s Antarctic expedition recruitment ad (1913) stated: No fewer than 5000 people replied… When we embarked on our journey half a year ago, it felt almost the same. With no fewer than 70 community members (both ex- perts and enthusiastic novices) answering the call for advisory board and offering to volun- teer their time to help us steer this project! We have now reached the end of the journey. These are the members of the devel- opment team who endured the challenges of the journey and produced this guide: Vision and Program Management Grigori Melnik (Microsoft Corporation) Development Julián Domínguez (Microsoft Corporation), Daniel Cazzulino and Fernando Simon- azzi (Clarius Consulting) Testing Mani Subramanian (Microsoft Corporation), Hernan de Lahitte (Digit Factory), and Rathi Velusamy (Infosys Technologies Ltd.) Documentation Dominic Betts (Content Master Ltd.), Julián Domínguez, Grigori Melnik, and Mani Subramanian (Microsoft Corporation), and Fernando Simonazzi (Clarius Consulting) Graphic Design Alexander Ustinov and Anton Rusecki (JetStyle) Editing and Production RoAnn Corbisier and Nelly Delgado (Microsoft Corporation), Nancy Mi- chell (Content Master Ltd.), and Chris Burns (Linda Werner & Associates Inc) The development team didn’t embark on this journey by themselves and didn’t work in isolation. We actively sought input from industry experts and from a wider group of advisors to ensure that the guidance is detailed, practical, and informed by real-world experience. We would like to thank our advisory board members and the DDD/CQRS community members in general who have accompanied us on this journey for their active participation, insights, critiques, challenges, and reviews. We have learned and unlearned many things, we’ve explored and experimented a lot. The journey wasn’t easy but it was so worth it and we enjoyed it. Thank you for keeping us grounded in the real-world chal- lenges. Thank you for your ongoing support of our effort. We hope the community will continue exploring the space, pushing the state of the practice further, and extending the reference implemen- tation and the guidance.
  • 34. xxx Specifically, we’d like to acknowledge the following people who have contributed to the journey in many different ways: • Greg Young for your pragmatism, patience with us, continuous mentoring and irreplaceable advice; • Udi Dahan for challenging us and offering alternative views on many concepts; • Clemens Vasters for pushing back on terminology and providing a very valuable perspective from the distributed database field; • Kelly Sommers for believing in us and bringing sanity to the community as well as for deep technical insights; • Adam Dymitruk for jumpstarting us on git and extending the RI; • Glenn Block for encouraging us to go all the way with the OSS initiative and for introducing us to many community members; • Our GM Lori Brownell and our director Björn Rettig for providing sponsorship of the initiative and believing in our vision; • Scott Guthrie for supporting the project and helping amplify the message; • Josh Elster for exploring and designing the MIL (Messaging Intermediate Language) and pushing us to make it easier to follow the workflow of messages in code; • Cesar De la Torre Llorente for helping us spike on the alternatives and bringing up terminological incongruities between various schools and thought leaders; • Rinat Abdullin for active participation at the beginning of the project and contributing a case study; • Bruno Terkaly and Ricardo Villalobos for exploring the disconnected client scenario that would integrate with the RI; • Einar Otto Stangvik for spiking on the Schedule Builder bounded context implementation in Node.js; • Mark Seemann for sending the very first pull request focusing on code quality; • Christopher Bennage for helping us overcome GitHub limitations by creating the pundit review system and the export-to-Excel script to manage iteration backlog more effectively; • Bob Brumfield, Eugenio Pace, Carlos Farre, Hanz Zhang, and Rohit Sharma for many insights especially on the perf and hardening challenges; • Chris Tavares for putting out the first CQRS experiment at p&p and suggesting valuable scenarios; • Tim Sharkinian for your perspectives on CQRS and for getting us on the SpecFlow train; • Jane Sinyagina for helping solicit and process feedback from the advisors; • Howard Wooten and Thomas Petchel for feedback on the UI style and usability; • Kelly Leahy for sharing your experience and making us aware of potential pitfalls; • Dylan Smith for early conversations and support of this project in pre-flight times; • Evan Cooke, Tim Walton, Alex Dubinkov, Scott Brown, Jon Wagner, and Gabriel N. Schenker for sharing your experiences and contributing mini-case studies. We feel honored to be supported by such an incredible group of people. Thank you!
  • 35. 1 “I am prepared to go anywhere, provided it be forward.” David Livingstone This chapter introduces a fictitious company named Contoso. It describes Contoso’s plans to launch the Contoso Conference Management System, a new online service that will enable other companies or individuals to organize and manage their own conferences and events. This chapter describes, at a high-level, some of the functional and non-functional requirements of the new system, and why Contoso wants to implement parts of it using the Command Query Responsibility Segregation (CQRS) pattern and event sourcing (ES). As with any company considering this process, there are many issues to consider and challenges to be met, particularly because this is the first time Contoso has used both the CQRS pattern and event sourcing. The chapters that follow show, step by step, how Contoso designed and built its conference management application. This chapter also introduces a panel of fictional experts to comment on the development efforts. The Contoso Corporation Contoso is a startup ISV company of approximately 20 employees that specializes in developing solu- tions using Microsoft technologies. The developers at Contoso are knowledgeable about various Microsoft products and technologies, including the .NET Framework, ASP.NET MVC, and Windows Azure. Some of the developers have previous experience using the domain-driven design (DDD) ap- proach, but none of them have used the CQRS pattern previously. The Conference Management System application is one of the first innovative online services that Contoso wants to take to market. As a startup, Contoso wants to develop and launch these services with a minimal investment in hardware and IT personnel. Contoso wants to be quick to market in order to start growing market share, and cannot afford the time to implement all of the planned functionality in the first releases. Therefore, it is important that the architecture it adopts can easily accommodate changes and enhancements with minimal impact on existing users of the system. Con- toso has chosen to deploy the application on Windows Azure in order to take advantage of its ability to scale applications as demand grows. Our Domain: Conference Management System The starting point: Where have we come from, what are we taking, and who is coming with us? Journey 1:
  • 36. 2 Journey one Who is coming with us on the journey? As mentioned earlier, this guide and the accompanying RI describe a CQRS journey. A panel of experts will comment on our development efforts as we go. This panel includes a CQRS expert, a software architect, a developer, a domain expert, an IT Pro, and a business manager. They will all comment from their own perspectives. Gary is a CQRS expert. He ensures that a CQRS-based solution will work for a company and will provide tangible benefits. He is a cautious person, for good reason. “Defining the CQRS pattern is easy. Realizing the benefits that implementing the CQRS pattern can offer is not always so straightforward.” Jana is a software architect. She plans the overall structure of an application. Her perspective is both practical and strategic. In other words, she considers not only what technical approaches are needed today, but also what direction a company needs to consider for the future. Jana has worked on projects that used the domain-driven design approach. “It’s not easy to balance the needs of the company, the users, the IT organization, the developers, and the technical platforms we rely on.” Markus is a software developer who is new to the CQRS pattern. He is analytical, detail-oriented, and methodical. He’s focused on the task at hand, which is building a great application. He knows that he’s the person who’s ultimately responsible for the code. “I don’t care what architecture you want to use for the application; I’ll make it work.” Carlos is the domain expert. He understands all the ins and outs of conference management. He has worked in a number of organizations that help people run conferences. He has also worked in a number of different roles: sales and marketing, conference management, and consultant. “I want to make sure that the team understands how this business works so that we can deliver a world-class online conference management system.”
  • 37. 3 Our Domain: Conference Management System Poe is an IT professional who’s an expert in deploying and running applications in the cloud. Poe has a keen interest in practical solutions; after all, he’s the one who gets paged at 3:00 AM when there’s a problem. “Running complex applications in the cloud involves challenges that are different than the challenges in managing on-premises applications. I want to make sure our new conference management system meets our published service-level agreements (SLA).” Beth is a business manager. She helps companies to plan how their business will develop. She understands the market that the company operates in, the resources that the company has available, and the goals of the company. She has both a strategic view and an interest in the day-to-day operations of the company. “Organizations face many conflicting demands on their resources. I want to make sure that our company balances those demands and adopts a business plan that will make us successful in the medium and long term.”If you have a particular area of interest, look for notes provided by the specialists whose interests align with yours. The Contoso Conference Management System This section describes the Contoso Conference Management System as the team envisaged it at the start of the journey. The team has not used the CQRS pattern before; therefore, the system that is delivered at the end of our journey may not match this description exactly because: • What we learn as we go may impact what we ultimately deliver. • Because this is a learning journey, it is more difficult to estimate what we can achieve in the available time. Overview of the system Contoso plans to build an online conference management system that will enable its customers to plan and manage conferences that are held at a physical location. The system will enable Contoso’s customers to: • Manage the sale of different seat types for the conference. • Create a conference and define characteristics of that conference. The Contoso Conference Management System will be a multi-tenant, cloud-hosted application. Busi- ness customers will need to register with the system before they can create and manage their confer- ences.
  • 38. 4 Journey one Selling seats for a conference The business customer defines the number of seats available for the conference. The business cus- tomer may also specify events at a conference such as workshops, receptions, and premium sessions for which attendees must have a separate ticket. The business customer also defines how many seats are available for these events. The system manages the sale of seats to ensure that the conference and sub-events are not oversubscribed. This part of the system will also operate wait-lists so that if other attendees cancel, their seats can be reallocated. The system will require that the names of the attendees be associated with the purchased seats so that an on-site system can print badges for the attendees when they arrive at the conference. Creating a conference A business customer can create new conferences and manage information about the conference such as its name, description, and dates. The business customer can also make a conference visible on the Contoso Conference Management System website by publishing it, or hide it by unpublishing it. Additionally, the business customer defines the seat types and available quantity of each seat type for the conference. Contoso also plans to enable the business customer to specify the following characteristics of a conference: • Whether the paper submission process will require reviewers. • What the fee structure for paying Contoso will be. • Who key personnel, such as the program chair and the event planner, will be. Nonfunctional requirements Contoso has two major nonfunctional requirements for its conference management system—scal- ability and flexibility—and it hopes that the CQRS pattern will help it meet them. Scalability The conference management system will be hosted in the cloud; one of the reasons Contoso chose a cloud platform was its scalability and potential for elastic scalability. Although cloud platforms such as Windows Azure enable you to scale applications by adding (or removing) role instances, you must still design your application to be scalable. By splitting responsibil- ity for the application’s read and write operations into separate objects, the CQRS pattern allows Contoso to split those operations into separate Windows Azure roles that can scale independently of each other. This recognizes the fact that for many applications, the number of read operations vastly exceeds the number of write operations. This gives Contoso the opportunity to scale the conference management system more efficiently, and make better use of the Windows Azure role instances it uses.
  • 39. 5 Our Domain: Conference Management System Flexibility The market that the Contoso Conference Management System oper- ates in is very competitive, and very fast moving. In order to compete, Contoso must be able to quickly and cost effectively adapt the con- ference management system to changes in the market. This require- ment for flexibility breaks down into a number of related aspects: • Contoso must be able to evolve the system to meet new requirements and to respond to changes in the market. • The system must be able to run multiple versions of its software simultaneously in order to support customers who are in the middle of a conference and who do not wish to upgrade to a new version immediately. Other customers may wish to migrate their existing conference data to a new version of the software as it becomes available. • Contoso intends the software to last for at least five years. It must be able to accommodate significant changes over that period. • Contoso does not want the complexity of some parts of the system to become a barrier to change. • Contoso would like to be able to use different developers for different elements of the system, using cheaper developers for simpler tasks and restricting its use of more expensive and experienced developers to the more critical aspects of the system. Beginning the journey The next chapter is the start of our CQRS journey. It provides more information about the Contoso Conference Management System and describes some of the high-level parts of the system. Subsequent chapters describe the stages of the journey as Contoso implements the conference management system. More information All links in this book are accessible from the book’s online bibliogra- phy available at: http://msdn.microsoft.com/en-us/library/jj619274. Contoso plans to compete by being quick to respond to changes in the market and to changing customer requirements. Contoso must be able to evolve the system quickly and painlessly. This is a big challenge: keeping the system running for all our customers while we perform upgrades with no down time. There is some debate in the CQRS community about whether, in practice, you can use different development teams for different parts of the CQRS pattern implementation.
  • 41. 7 “Without stones there is no arch.” Marco Polo In this chapter, we provide a high-level overview of the Contoso Conference Management System. The discussion will help you understand the structure of the application, the integration points, and how the parts of the application relate to each other. Here we describe this high-level structure in terms borrowed from the domain-driven design (DDD) approach that Eric Evans describes in his book, Domain-Driven Design: Tackling Complexity in the Heart of Software (Addison-Wesley Professional, 2003). Although there is no universal consensus that DDD is a prerequisite for implementing the Command Query Responsibility Segregation (CQRS) pattern successfully, our team decided to use many of the concepts from the DDD approach, such as domain, bounded context, and aggregate, in line with common practice within the CQRS community. Chapter 1, “CQRS in Context,” in the Reference Guide discusses the relationship between the DDD approach and the CQRS pattern in more detail. Definitions used in this chapter Throughout this chapter we use a number of terms, which we’ll define in a moment. For more detail, and possible alternative definitions, see Chapter 1, “CQRS in Context,” in the Reference Guide. Domain: The domain refers to the business domain for the Contoso Conference Management System (the reference implementation). Chapter 1, “Our Domain: The Contoso Conference Manage- ment System,” provides an overview of this domain. Decomposing the Domain Planning the stops. Journey 2:
  • 42. 8 Journey two Bounded context: The term bounded context comes from Eric Evans’ book. In brief, Evans introduces this concept as a way to de- compose a large, complex system into more manageable pieces; a large system is composed of multiple bounded contexts. Each bound- ed context is the context for its own self-contained domain model, and has its own ubiquitous language. You can also view a bounded context as an autonomous business component defining clear consis- tency boundaries: one bounded context typically communicates with another bounded context by raising events. Context map: According to Eric Evans, you should “Describe the points of contact between the models, outlining explicit translation for any communication and highlighting any sharing.” This exercise results in what is called a context map, which serves several purposes that include providing an overview of the whole system and helping people to understand the details of how different bounded contexts interact with each other. Bounded contexts in the conference management system The Orders and Registrations bounded context: Within the orders and registrations bounded context are the reservations, payment, and registration items. When a registrant interacts with the system, the system creates an order to manage the reservations, payment, and registrations. An order contains one or more order items. A reservation is a temporary reservation of one or more seats at a conference. When a registrant begins the ordering process to pur- chase a number of seats at a conference, the system creates reserva- tions for that number of seats. Those seats are then unavailable for other registrants to reserve. The reservations are held for 15 minutes, during which time the registrant can complete the ordering process by making a payment for the seats. If the registrant does not pay for the tickets within 15 minutes, the system deletes the reservation and the seats become available for other registrants to reserve. The Conference Management bounded context: Within this bounded context, a business customer can create new conferences and manage them. After a business customer creates a new confer- ence, he can access the details of the conference by using his email address and conference locator access code. The system generates the access code when the business customer creates the conference. When you use the CQRS pattern, you often use events to communicate between bounded contexts. There are alternative approaches to integration, such as sharing data at the database level. We discussed making the period of time that the system holds reservations a parameter that a business customer can adjust for each conference. This may be a feature that we add if we determine that there is a requirement for this level of control.
  • 43. 9 Decomposing the Domain The business customer can specify the following information about a conference: • The name, description, and slug (part of the URL used to access the conference). • The start and end dates of the conference. • The different types and quotas of seats available at the conference. Additionally, the business customer can control the visibility of the conference on the public website by either publishing or unpublishing the conference. The business customer can also use the conference management website to view a list of orders and attendees. The Payments bounded context: The payments bounded context is responsible for managing the interactions between the conference management system and external payment systems. It forwards the necessary payment information to the external system and receives an acknowledgement that the payment was either accepted or rejected. It reports the success or failure of the payment back to the conference management system. Initially, the payments bounded context will assume that the business customer has an account with the third-party payment system (although not necessarily a merchant account), or that the busi- ness customer will accept payment by invoice. Bounded contexts not included Although they didn’t make it into the final release of the Contoso Conference Management System, some work was done on three additional bounded contexts. Members of the community are working on these and other features, and any out-of-band releases and updates will be announced on the Project “a CQRS Journey” website. If you would like to contribute to these bounded contexts or any other aspect of the system, visit the Project “a CQRS Journey” website or let us know at cqrsjourney@ microsoft.com. The Discounts bounded context: This is a bounded context to handle the process of managing and applying discounts to the purchase of conference seats that would integrate with all three exist- ing bounded contexts. The Occasionally Disconnected Conference Management client: This is a bounded context to handle management of conferences on-site with functionality to handle label printing, recording at- tendee arrivals, and additional seat sales. The Submissions And Schedule Management bounded context: This is a bounded context to handle paper submissions and conference event scheduling written using Node.js. Note: Wait listing is not implemented in this release, but members of the community are working on this and other features. Any out-of-band releases and updates will be announced on the Project “a CQRS Journey” website.
  • 44. 10 Journey two The context map for the Contoso Conference Management System Figure 1 and the table that follows it represent a context map that shows the relationships between the different bounded contexts that make up the complete system, and as such it provides a high- level overview of how the system is put together. Even though this context map appears to be quite simple, the implementation of these bounded contexts, and more importantly the interactions between them, are relatively sophisticated; this enabled us to address a wide range of issues relating to the CQRS pattern and event sourcing (ES), and provided a rich source from which to capture many valuable les- sons learned. Figure 1 shows the three bounded contexts that make up the Contoso Conference Management System. The arrows in the diagram indicate the flow of data as events between them. Figure 1 Bounded contexts in the Contoso Conference Management System A frequent comment about CQRS projects is that it can be difficult to understand how all of the pieces fit together, especially if there a great many commands and events in the system. Often, you can perform some static analysis on the code to determine where events and commands are handled, but it is more difficult to automatically determine where they originate. At a high level, a context map can help you understand the integration between the different bounded contexts and the events involved. Maintaining up-to-date documentation about the commands and events can provide more detailed insight. Additionally, if you have tests that use commands as inputs and then check for events, you can examine the tests to understand the expected consequences of particular commands (see the section on testing in Chapter 4, “Extending and Enhancing the Orders and Registrations Bounded Context” for an example of this style of test).
  • 45. 11 Decomposing the Domain The following list provides more information about the arrows in Figure 1. You can find additional details in the chapters that discuss the individual bounded contexts. 1. Events that report when conferences have been created, updated, or published. Events that report when seat types have been created or updated. 2. Events that report when orders have been created or up- dated. Events that report when attendees have been assigned to seats. 3. Requests for a payment to be made. 4. Acknowledgement of the success or failure of the payment. Why did we choose these bounded contexts? During the planning stage of the journey, it became clear that these were the natural divisions in the domain that could each contain their own, independent domain models. Some of these divisions were eas- ier to identify than others. For example, it was clear early on that the conference management bounded context is independent of the re- mainder of the domain. It has clearly defined responsibilities that re- late to defining conferences and seat types and clearly defined points of integration with the rest of the application. On the other hand, it took some time to realize that the orders and registrations bounded context is separate from the Payments bounded context. For example, it was not until the V2 release of the application that all concepts relating to payments disappeared from the orders and registrations bounded context when the OrderPaymentConfirmed event became the OrderConfirmed event. More practically, from the perspective of the journey, we wanted a set of bounded contexts that would enable us to release a working application with some core functionality and that would enable us to explore a number of different implementation patterns: CQRS, CQRS/ES, as well as integration with a legacy, CRUD-style bounded context. More information All links in this book are accessible from the book’s online bibliogra- phy available at: http://msdn.microsoft.com/en-us/library/jj619274. Some of the events that the Conference Management bounded context raises are coarse- grained and contain multiple fields. Remember that conference management is a create, read, update and delete (CRUD)-style bounded context and does not raise fine-grained domain-style events. For more information, see Chapter 5, “Preparing for the V1 Release.” We continued to refine the domain models right through the journey as our understanding of the domain deepened. Contoso wants to release a usable application as soon as possible, but be able to add both planned features and customer-requested features as they are developed and with no down time for the upgrades.
  • 47. 13 “The Allegator is the same, as the Crocodile, and differs only in Name.” John Lawson A description of the bounded context The Orders and Registrations bounded context is partially responsible for the booking process for attendees planning to come to a conference. In the Orders and Registrations bounded context, a person (the registrant) purchases seats at a particular conference. The registrant also assigns names of attendees to the purchased seats (this is described in Chapter 5, “Preparing for the V1 Release”). This was the first stop on our CQRS journey, so the team decided to implement a core, but self- contained part of the system—orders and registrations. The registration process must be as painless as possible for attendees. The process must enable the business customer to ensure that the maximum possible number of seats can be booked, and give them the flexibility set the prices for the different seat types at a conference. Because this was the first bounded context addressed by the team, we also implemented some infrastructure elements of the system to support the domain’s functionality. These included command and event message buses and a persistence mechanism for aggregates. The Contoso Conference Management System described in this chapter is not the final version of the system. This guidance describes a journey, so some of the design decisions and implementation details change later in the journey. These changes are described in subsequent chapters. Plans for enhancements to this bounded context in some future journey include support for wait listing, whereby requests for seats are placed on a wait list if there aren’t sufficient seats available, and enabling the business customer to set various types of discounts for seat types. Wait listing is not implemented in this release, but members of the community are working on this and other features. Any out-of-band releases and updates will be announced on the Project “a CQRS Journey” website. Orders and Registrations Bounded Context The first stop on our CQRS journey. Journey 3:
  • 48. 14 Journey three Working definitions for this chapter This chapter uses a number of terms that we will define in a moment. For more detail, and possible alternative definitions, see “A CQRS and ES Deep Dive” in the Reference Guide. Command. A command is a request for the system to perform an action that changes the state of the system. Commands are impera- tives; MakeSeatReservation is one example. In this bounded context, commands originate either from the UI as a result of a user initiating a request, or from a process manager when the process manager is directing an aggregate to perform an action. A single recipient processes a command. A command bus trans- ports commands that command handlers then dispatch to aggregates. Sending a command is an asynchronous operation with no return value. Event. An event, such as OrderConfirmed, describes something that has happened in the system, typically as a result of a command. Aggregates in the domain model raise events. Multiple subscribers can handle a specific event. Aggregates pub- lish events to an event bus; handlers register for specific types of events on the event bus and then deliver the event to the subscriber. In this bounded context, the only subscriber is a process manager. Process manager. In this bounded context, a process manager is a class that coordinates the behavior of the aggregates in the domain. A process manager subscribes to the events that the aggregates raise, and then follow a simple set of rules to determine which command or commands to send. The process manager does not contain any busi- ness logic; it simply contains logic to determine the next command to send. The process manager is implemented as a state machine, so when it responds to an event, it can change its internal state in addi- tion to sending a new command. Our process manager is an implementation of the Process Man- ager pattern defined on pages 312 to 321 of the book by Gregor Hohpe and Bobby Woolf, entitled Enterprise Integration Patterns: Designing, Building, and Deploying Messaging Solutions (Addison- Wesley Professional, 2003). For a discussion of some possible optimizations that also involve a slightly different definition of a command, see Chapter 6, “Versioning our System.” It can be difficult for someone new to the code to follow the flow of commands and events through the system. For a discussion of a technique that can help, see the section “Impact on testing” in Chapter 4, “Extending and Enhancing the Orders and Registrations Bounded Contexts.”
  • 49. 15 Orders and Registrations Bounded Context The process manager in this bounded context can receive com- mands as well as subscribe to events. The Reference Guide contains additional definitions and explana- tions of CQRS-related terms. Domain definitions (ubiquitous language) The following list defines the key domain-related terms that the team used during the development of this Orders and Registrations bound- ed context. Attendee. An attendee is someone who is entitled to attend a conference. An Attendee can interact with the system to perform tasks such as manage his agenda, print his badge, and provide feed- back after the conference. An attendee could also be a person who doesn’t pay to attend a conference such as a volunteer, speaker, or someone with a 100% discount. An attendee may have multiple as- sociated attendee types (speaker, student, volunteer, track chair, and so on.) Registrant. A registrant is a person who interacts with the sys- tem to place orders and to make payments for those orders. A regis- trant also creates the registrations associated with an order. A regis- trant may also be an attendee. User. A user is a person such as an attendee, registrant, speaker, or volunteer who is associated with a conference. Each user has a unique record locator code that the user can use to access user-spe- cific information in the system. For example, a registrant can use a record locator code to access her orders, and an attendee can use a record locator code to access his personalized conference agenda. Seat assignment. A seat assignment associates an attendee with a seat in a confirmed order. An order may have one or more seat as- signments associated with it. Order. When a registrant interacts with the system, the system creates an order to manage the reservations, payment, and registra- tions. An order is confirmed when the registrant has successfully paid for the order items. An order contains one or more order items. Order item. An order item represents a seat type and quantity, and is associated with an order. An order item exists in one of three states: created, reserved, or rejected. An order item is initially in the created state. An order item is in the reserved state if the system has reserved the quantity of seats of the seat type requested by the regis- trant. An order item is in the rejected state if the system cannot re- serve the quantity of seats of the seat type requested by the registrant. The team initially referred to the process manager class in the orders bounded context as a saga. To find out why we decided to change the terminology, see the section “Patterns and concepts” later in this chapter. We intentionally implemented a record locator mechanism to return to a previously submitted order via the mechanism. This eliminates an often annoying requirement for users to create an account in the system and sign in in order to evaluate its usefulness. Our customers were adamant about this.
  • 50. 16 Journey three Seat. A seat represents the right to be admitted to a conference or to access a specific session at the conference such as a cocktail party, a tutorial, or a workshop. The business customer may change the quota of seats for each conference. The business customer may also change the quota of seats for each session. Reservation. A reservation is a temporary reservation of one or more seats. The ordering process creates reservations. When a registrant begins the ordering process, the system makes reservations for the number of seats requested by the registrant. These seats are then not available for other registrants to reserve. The reservations are held for n minutes during which the registrant can com- plete the ordering process by making a payment for those seats. If the registrant does not pay for the seats within n minutes, the system cancels the reservation and the seats become available to other registrants to reserve. Seat availability. Every conference tracks seat availability for each type of seat. Initially, all of the seats are available to reserve and purchase. When a seat is reserved, the number of available seats of that type is decremented. If the system cancels the reservation, the number of available seats of that type is incremented. The business customer defines the initial number of each seat type to be made available; this is an attribute of a conference. A conference owner may adjust the numbers for the individual seat types. Conference site. You can access every conference defined in the system by using a unique URL. Registrants can begin the ordering process from this site. Each of the terms defined here was formulated through active discussions between the devel- opment team and the domain experts. The following is a sample conversation between devel- opers and domain experts that illustrates how the team arrived at a definition of the term at- tendee. Developer 1: Here’s an initial stab at a definition for attendee. “An attendee is someone who has paid to attend a conference. An attendee can interact with the system to perform tasks such as manage his agenda, print his badge, and provide feedback after the conference.” Domain Expert 1: Not all attendees will pay to attend the conference. For example, some conferences will have volunteer helpers, also speakers typically don’t pay. And, there may be some cases where an attendee gets a 100% discount. Domain Expert 1: Don’t forget that it’s not the attendee who pays; that’s done by the regis- trant. Developer 1: So we need to say that Attendees are people who are authorized to attend a conference? Developer 2: We need to be careful about the choice of words here. The term authorized will make some people think of security and authentication and authorization. Developer 1: How about entitled? Domain Expert 1: When the system performs tasks such as printing badges, it will need to know what type of attendee the badge is for. For example, speaker, volunteer, paid attendee, and so on.
  • 51. 17 Orders and Registrations Bounded Context Developer 1: Now we have this as a definition that captures everything we’ve discussed. An attendee is someone who is entitled to attend a conference. An attendee can interact with the system to perform tasks such as manage his agenda, print his badge, and provide feedback after the conference. An attendee could also be a person who doesn’t pay to attend a confer- ence such as a volunteer, speaker, or someone with a 100% discount. An attendee may have multiple associated attendee types (speaker, student, volunteer, track chair, and so on.) Requirements for creating orders A registrant is the person who reserves and pays for (orders) seats at a conference. Ordering is a two-stage process: first, the registrant reserves a number of seats and then pays for the seats to confirm the reservation. If registrant does not complete the payment, the seat reservations expire after a fixed period and the system makes the seats available for other registrants to reserve. Figure 1 shows some of the early UI mockups that the team used to explore the seat-ordering story. Figure 1 Ordering UI mockups
  • 52. 18 Journey three These UI mockups helped the team in several ways, allowing them to: • Communicate the core team’s vision for the system to the graphic designers who are on an independent team at a third- party company. • Communicate the domain expert’s knowledge to the developers. • Refine the definition of terms in the ubiquitous language. • Explore “what if” questions about alternative scenarios and approaches. • Form the basis for the system’s suite of acceptance tests. Architecture The application is designed to deploy to Windows Azure. At this stage in the journey, the application consists of a web role that con- tains the ASP.NET MVC web application and a worker role that contains the message handlers and domain objects. The application uses a Windows Azure SQL Database instance for data storage, both on the write side and the read side. The application uses the Win- dows Azure Service Bus to provide its messaging infrastructure. While you are exploring and testing the solution, you can run it locally, either using the Windows Azure compute emulator or by run- ning the MVC web application directly and running a console applica- tion that hosts the handlers and domain objects. When you run the application locally, you can use a local SQL Server Express database instead of SQL Database, and use a simple messaging infrastructure implemented in a SQL Server Express database. For more information about the options for running the applica- tion, see Appendix 1, “Release Notes.” Patterns and concepts The team decided to implement the first bounded context without us- ing event sourcing in order to keep things simple. However, they did agree that if they later decided that event sourcing would bring specific benefits to this bounded context, then they would revisit this decision. For a description of how event sourcing relates to the CQRS pattern, see “Introducing Event Sourcing” in the Reference Guide. One of the important discussions the team had concerned the choice of aggregates and entities that they would implement. The following images from the team’s whiteboard illustrate some of their initial thoughts, and questions about the alternative approaches they could take with a simple conference seat reservation scenario to try and understand the pros and cons of alternative approaches. A frequently cited advantage of the CQRS pattern is that it enables you to scale the read side and write side of the application independently to support the different usage patterns. In this bounded context, however, the number of read operations from the UI is not likely to hugely out-number the write operations: this bounded context focuses on registrants creating orders. Therefore, the read side and the write side are deployed to the same Windows Azure worker role rather than to two separate worker roles that could be scaled independently. “A value I think developers would benefit greatly from recognizing is the de-emphasis on the means and methods for persistence of objects in terms of relational storage. Teach them to avoid modeling the domain as if it was a rela- tional store, and I think it will be easier to introduce and understand both domain- driven design (DDD) and CQRS.” —Josh Elster, CQRS Advisors Mail List
  • 53. 19 Orders and Registrations Bounded Context This scenario considers what happens when a registrant tries to book several seats at a confer- ence. The system must: • Check that sufficient seats are available. • Record details of the registration. • Update the total number of seats booked for the conference. We deliberately kept the scenario simple to avoid distractions while the team examines the alternatives. These examples do not illustrate the final implementation of this bounded context. The first approach considered by the team, shown in Figure 2, uses two separate aggregates. These diagrams deliberately exclude details of how the system delivers commands and events through command and event handlers. The diagrams focus on the logical relationships between the aggregates in the domain. Figure 2 Approach 1: Two separate aggregates
  • 54. 20 Journey three The numbers in the diagram correspond to the following steps: 1. The UI sends a command to register attendees X and Y for conference 157. The command is routed to a new Order aggregate. 2. The Order aggregate raises an event that reports that an order has been created. The event is routed to the Seats- Availability aggregate. 3. The SeatsAvailability aggregate with an ID of 157 is re- hydrated from the data store. 4. The SeatsAvailability aggregate updates its total number of seats booked. 5. The updated version of the SeatsAvailability aggregate is persisted to the data store. 6. The new Order aggregate, with an ID of 4239, is persisted to the data store. You could consider using the Memento pattern to handle the persistence and rehydration. The term rehydration refers to the process of deserializing the aggregate instance from a data store.
  • 55. Another Random Document on Scribd Without Any Related Topics
  • 56. "Rather deft at times," replied Cazeby, arranging the dishes on the larger table. "Je te crois!" said Bibi, enthusiastically. "Without him—what? Evidently, it was not Léon Treize who built Saint Pierre!" The eggs had been peculiarly obstinate, as it happened, and a growing irritability had taken possession of Anthony. As they ate in silence, the full force of his tragic position returned to him. Even the unwontedness of his chance encounter with Bibi-la-Raie had not wholly dispelled the cloud that had been gradually settling around him since he emerged from the Automobile Club, and, as they finished the little repast, he turned suddenly upon his guest, in a burst of irritation. "Who are you?" he said. "And what does all this mean? Was I mistaken, when you first spoke to me, in thinking you a mere voyou? Surely not! You meant to rob me. You speak the argot of the fortifications. Yet here I find you discoursing on Michel Angelo as though you were the conservateur of the Uffizzi! What am I to think?" Bibi-la-Raie lit another cigarette, blew forth the smoke in a thin, gray wisp, and thrust his thumbs into the arm-holes of his velveteen waistcoat. "And you," he said, slowly, abandoning the familiar address he had been using, "who are you? No, you were not mistaken in thinking I meant to rob you. Such is my profession. But does a gentleman reply, in ordinary, to the summons of a thief by paying that thief a drink? Does he invite him to his apartment and cook a supper for him? What am I to think?" There was a brief pause, and then he faced his host squarely. "Are you absolutely resolved to put an end to it all to-night?" he demanded. Cazeby made a small sign of bewilderment.
  • 57. "Ah, mon vieux," continued the other. "That, you know, is of no use with me. You ask me who I am. For one thing, I am one who has lived too long in touch with desperate men not to know the look in the eyes when the end has come. You think you are going to blow out your brains to-night." "Your wits are wandering; that's all," said Cazeby, compassionately. "Oh, far from it!" said Bibi-la-Raie, with a short laugh. "But one does not fondle one's revolver in the daytime without a good reason, nor does one leave it on top of letters postmarked this morning unless one has been fondling it—quoi?" Cazeby was at the marqueterie desk in two strides, tugging at the upper right hand drawer. It was locked. He turned about slowly, and, half seating himself on the edge of the desk, surveyed his guest coolly. "The revolver is in your pocket," he said. "No," answered Bibi, with an air of cheerfulness. "I have one of my own. But the key is." "Why?" said Cazeby. Bibi helped himself to yellow chartreuse, and appeared to reflect. "I am not sure that I know why, myself," he said finally. "Perhaps, because you have done me a kindness and I would not like to have you burn your fingers in a moment of absent-mindedness. Perhaps, because we might disagree, and I should not care to take the chance of your shooting first!" He squinted at the liqueur, swallowed it slowly and with extreme appreciation, smacked his lips, and then, cocking his feet up on Cazeby's brass club fender, began to smoke again, staring into the dwindling fire. His host watched him in silence, until he should be ready to speak, which he presently began to do, with his cigarette drooping from the corner of his month and moving in time to his words. He had suddenly and curiously become a man of the world— of the grand monde—and his speech had shaken off all trace of
  • 58. slang, and was tinged instead with the faint club sarcasm which one hears in the glass card-room of the Volney or over coffee on the roof of the Automobile. Moreover, it was beautiful French. Not Mounet himself could have done better. "The only man to whom one should confide personal secrets," said Bibi-la-Raie, "is he whom one has never seen before and will, as is probable, never see again. I could tell you many things, Monsieur Cazeby, since that is your name,—I have seen your morning's mail, you know!—but, for the moment, let it suffice to say that the voyou who accosted you this evening is of birth as good as yours—pardon, but probably better! Wein, weib, und gesang—you know the saying. Add cards and the race-course, and you have, complete, the short ladder of five rungs down which I have been successful in climbing. I shall presume to the extent of supposing that you have just accomplished the same descent. One learns much thereby, but more after one has reached the ground. In many ways I am afraid experience has made me cynical, but in one it has taught me optimism. I have found, and I think I shall continue to find, that there is always something worth looking into around the next corner of even the darkest street. The rue des Sablons, for instance. It was very dark to-night, very damp, and very cold. Assuredly, as I turned into the avenue d'Eylau I had no reason to foresee a supper, Russian cigarettes, and chartreuse jaune. And yet, me voilà! Now what most of us lack—what you, in particular, seem to lack, Monsieur Cazeby— is the tenacity needful if one is to get to that next turning." "There are streets darker than the rue des Sablons," put in Anthony, falling in with the other's whimsical humor, "and that have no turning." "You speak from conjecture, not experience," said Bibi-la-Raie. "You can never have seen one." He glanced about the room, with the air of one making a mental inventory.
  • 59. "First," he added, "there come the pawnshop, the exterior boulevards, the somewhat insufficient shelter of the Pont Royal. No, you have not come to the last corner." "All that," said Cazeby, "is simply a matter of philosophy. Each of us has his own idea of what makes life worth the while. When that is no longer procurable, then that is the last corner." "For instance—?" "For instance, my own case. You have analyzed my situation sufficiently well—though when you said I was about to blow out my brains"— "It was a mere guess," interrupted Bibi, "founded on circumstantial evidence. Then I thought so. Now I know it." "Let us grant you are right," continued Cazeby, with a smile. "I have my own conception of what I require to make existence tolerable. It includes this apartment, or its equivalent, a horse, two servants, two clubs, and a sufficient income to dress, eat, entertain, and amuse myself in the manner of my class,—an extravagant and unreasonable standard, if you will, but such is my conviction. Now, granted that the moment has come when it is no longer possible for me to have these things, and when there is no prospect of my situation being bettered, I cannot conceive what advantage there can be in continuing to live." "I perceive you are a philosopher," said the other. "How about the religious view?" Cazeby shrugged his shoulders. "As to that," he said, "my religious views are, so far as I know, stored away in the little church which I was forced to attend three times on every Sunday of my boyhood. They did not come out with me on the last occasion, and I have never met them since." "Excellent!" said Bibi. "It is the same with me. But I think you are mistaken in your conviction of what makes life worth living. I had my own delusions in the time. But I have had a deal of schooling since
  • 60. then. There are many things as amusing as luxury—even on the exterior boulevards. Of course, actual experience is essential. One never knows what one would do under given conditions." He turned suddenly, and looked Cazeby in the eye. "What, for example, would you do if you were in my place?" he asked. "As you say, one never knows," said his host. "I think that, in your place, I should improve the opportunity you find open, and carry out your late and laudable intention of robbing Monsieur Antoine Cazeby. I may be influenced by my knowledge that such a proceeding would not irritate or incommode him in the least, but that is what I think I should do. "I shall not need these things to-morrow," he added, indicating his surroundings with a gesture. "You were quite right about the pistol. As to your prospective booty, I regret to say that I spent my last sixty centimes on our cognac, but there is a remarkably fine scarf- pin on the table in my dressing-room." "A sapphire, surrounded by black pearls," put in the other. "You were rather long in cooking those eggs." "A sapphire, surrounded by black pearls," agreed Cazeby. "Yes, upon reflection, I am quite sure that that is what I should do." Bibi-la-Raie smiled pleasantly. "I am glad to find we are of one mind," he said. "Of course, mine was made up, but it is more agreeable to know that I am causing you no inconvenience. I suppose it is unnecessary to add that resistance will be quite useless. I have the only available revolver, and, moreover, I propose to tie you into this extremely comfortable chair. It is not," he added, "that I do not trust you, although our acquaintance is, unfortunately, too recent to inspire complete confidence. No, I have my convictions as well as you, Monsieur Cazeby, and one of them, curiously enough, is that, in spite of appearances, I am doing you a kindness in putting it out of your
  • 61. power, for tonight, at least, to do yourself an injury. Who knows? Perhaps, in the morning, you may find that there is something around the next corner, after all. If not, there is no harm done. Your servants come in early?" "At seven o'clock," said Anthony, briefly. "Exactly. And I will leave the key in the drawer." Bibi was expeditious. When he had bound Cazeby firmly, and with an art that showed practice, he disappeared into the dressing-room, returning in less than a minute with the sapphire scarf-pin and several other articles of jewelry in his hand. "I should like to add to these," he said, going to the book-case, "this little copy of Omar Khayyám. He is a favorite of mine. There is something about his philosophy which seems to accord with our own. But—'the bird of time has but a little way to flutter'"—He paused at the door. "Can I do anything for you before I go?" he inquired politely. "Be good enough to turn off the light," said the other. "The button is on the right of the door." "Good-night," said Bibi-la-Raie. "Good-night,—brother!" said Cazeby. Then he heard the door of the apartment close softly. Anthony was awakened from a restless sleep by the sound of its opening. Through the gap between the window draperies the gray light of the winter morning was creeping in. His wrists and ankles were aching from the pressure of the curtain cords with which he had been bound, and he was gratified when, after a brief interval, the salon door was opened in its turn and the invaluable Jules came in, in shirt-sleeves and long white apron, carrying a handful of letters. That impassive person was probably never nearer to being visibly surprised. For a breath he stopped, and the pupils of his round eyes
  • 62. dilated like those of a cat in a dim light. But his training stood him in good stead, and when he spoke his voice was as innocent of emotion as if he had been announcing dinner. "Monsieur desires to be untied?" Left to himself, Cazeby turned his attention to his letters, and from the top of the pile picked up a cablegram. He was still reflecting upon the singular experience of the night, in an attempt to analyze his present emotions. Was he in any whit changed by his enforced reprieve? He was glad to think not. Above all minor faults he abhorred vacillation of purpose. No, his situation and his purpose remained unaltered. But he was conscious, nevertheless, of an unwonted thrill at the thought that, but for the merest chance, it would have been for others to open the envelope he was even now fingering. Jules would already have found him—he wondered, with the shadow of a smile, whether Jules would still have been unsurprised!—and would have brought up the concierge and the police— Suddenly the cable message jumped at him through his revery as if, at that moment, the words had been instantaneously printed on what was before blank paper, and he realized that it was from his father's solicitor. Mr. Cazeby died eight o'clock this evening after making will your favor whole property. Waiting instructions. Milliken. Anthony straightened himself with a long sigh, and, putting aside the curtain, looked out across the mansardes, wet and gleaming under a thin rain. His hand trembled a little on the heavy velvet, and he frowned at it, and, going across to the table, poured himself out a swallow of brandy. With the glass at his lips he paused, his eyes upon the chair where Bibi-la-Raie had sat and wherein he himself had passed five hours.
  • 63. Then, very ceremoniously, he bowed and dipped his glass toward an imaginary occupant. "Merci, monsieur!" he said.
  • 65. I T h e O n l y S o n o f H i s M o t h e r N the limited understanding of Pépin dwelt one great Fact, in the shadow of which all else shrank to insignificance, and that Fact was the existence of Comte Victor de Villersexel, the extremely tall and extraordinarily imposing person who was, first of all, Officier de la Légion d'Honneur, second, Membre de l'Académie Française, and, lastly, father to Pépin himself. It must be acknowledged that to the more observing of his limited kinsfolk and extensive acquaintance the clay feet of Pépin's idol were distinctly in evidence. How he had contrived to attain to the proud eminence which he occupied was, in the earlier days of his publicity, a matter of curious conjecture and not over-plausible explanation. Certainly no inherent merit or ability it was which formed the first step of the stairway he had climbed. In diplomacy the Comte de Villersexel had never bettered his first appointment as second secretary of legation at Belgrade; in literature his achievements were limited to one ponderous work on feudalism, remarkable chiefly for its surpassing futility; and in society his sole claim to consideration lay in his marriage to a Brazilian heiress, who had died within the year, leaving her husband an income of two hundred thousand francs—and Pépin. In all this it was difficult to find a sufficient reason for the crimson button and the green embroidered coat, unless it was that the family of de Villersexel went back to the Crusades. That is not always a prudent thing for a family to do, but the present instance was an exception. Born to the heritage of a name which his predecessors had made notable, Comte Victor was one of those whose greatness is thrust upon them rather than achieved, one of the bubbles in the ferment of Paris which their very levity brings to the top, to show rainbow
  • 66. tints in the sunlight of publicity. It is probable that no one was more surprised than de Villersexel himself at the honors which fell to his share, but one thing even the most contemptuous had, perforce, to concede. Once secure of his laurels, he wore them with a confidence that was akin to conviction. His reserve was iron-clad, his dignity stupendous. It required considerable time for new acquaintances to probe the secret of his insufficiency. Victor de Villersexel was, as the irreverent young military attaché at the American Embassy once said of him, "a dazzling imitation of the real thing." But to Pépin the idol was an idol without flaw. Through what shrewd appreciation of occasional words and chance comments he had contrived to grasp the significance of that speck of scarlet upon the Count's lapel and that apparently simple phrase, "de l'Académie Française," which, in formal introductions, was wont to follow his father's name, must be numbered among childhood's mysteries. But before he was seven, Pépin had solved these problems for himself, and the results of his reasoning were awestruck admiration and blind allegiance to the will of this wonderful creature who never smiled. His own small individuality was so completely overshadowed by that of his father that in the latter's presence the child was scarcely noticeable, dressed in his sober blouses, and creeping about the stately rooms of the great apartment in the avenue d'Iéna with an absolutely noiseless step. He was all brown, was Pépin: brown bare legs, and brown hands, very small and slender, brown hair, cropped short and primly parted, and deep brown eyes, eloquent of unspoken and unspeakable things. He was earnest, his tutor said, earnest and willing, but not bright, poor Pépin! He spoke English, to be sure, with a curious accent caught from his Cornish nurse, but that was due not so much to ability as to enforced association. In his French grammar and such simple arithmetic as was required of him he was slow and often stupid. But he was rarely scolded, and never punished. Once, indeed, the Comte had been about to strike him for some trifling fault, but somehow the blow, for which Pépin stood waiting, never fell.
  • 67. "He is like his mother," the légionnaire had muttered, as he turned away, "an imbecile—but"— Pépin, catching the unfinished phrase, grew sick with a great discouragement, mingled with profound pity for the man before him. It must be a dreadful thing for one so famous to be the father of an imbecile! From that day on the child was more inconspicuous than before. Deliberately affected in the first instance, what was known in society as de Villersexel's "academic manner" came in course of time to be second nature. Practice made perfect the chill reserve which was originally assumed as a precaution against possible discovery of his vapidity; and as the image of what the academician had been, before his election, grew dimmer in society's recollection, his impressive solemnity, barely disguised by a veneer of superficial courtesy, did not fail of its effect. He was spoken of as a man in whom much lay below the surface, and his more recent acquaintances coupled their estimate of his character with the proverbial profundity of still waters, and the familiar gloved fist of steel. Others, more observant, smiled at the similes, but did not go to the pains of proving them ill applied. One of the most characteristic things about the Comte de Villersexel was that he inspired neither championship nor antagonism. With all this, he was consistent, with that curious obstinacy which is sometimes made manifest in the shallowest natures. His rôle, once assumed, was, as we have said, played to perfection and never laid aside. The domestic threshold, which is, for the majority of men, a kind of uncloaking room, saw never an alteration, even of voice or expression, in his pose. The household affairs were regulated with almost military precision, and once a day, at noon, Pépin and his father met in the large salon,—the Comte in his tall satin stock and frock coat, and Pépin fresh from the careful hands of his nurse. They shook hands gravely, and then waited in silence, until the maître d'hôtel announced breakfast,— "Ces messieurs sont servis!"
  • 68. What meals they were, to be sure, those déjeuners, solemnly served, and more solemnly eaten, under the rigid observation of three menservants; de Villersexel, with his thin lips, his cold eyes, and his finely pointed gray mustache, barely moving save to raise his fork or break a morsel from his roll, and Pépin, all brown, perched like a mouse on the edge of a great chair, and nibbling at tiny scraps of food with downcast eyes! At the very end, as the Comte was about to push back his chair, he would invariably raise his glass of champagne and Pépin his, wherein a few drops of red wine turned the Evian to a pale heliotrope, and together they would glance toward the full-length portrait which hung above the mantel. "Ta mère!" said the Comte. "Maman!" replied Pépin. And so they drank the toast of tribute to the dead. After breakfast, the father would read for an hour to the child, and Pépin, seated on another large chair, would listen, perfectly motionless, striving desperately to understand the long sentences which fell in flawlessly pronounced succession from the Academician's lips. De Villersexel had a fairly clear recollection of what books had been the companions of his childhood, and these he purchased in the rarest editions, and clothed in the richest bindings, and read to Pépin: only his remembrance did not extend to a very distinct differentiation between seven and fifteen, for it was at the latter age that he read "Télémaque" to himself, and at the former that he read "Télémaque" to his son. Then would come a second formal handshake, and Pépin, pausing an instant at the door to make a slow, stiff bow, would creep off down the long corridor to the nursery, and the Comte turn again to his papers with a consciousness of paternal duty done. How Pépin contrived to spend the long hours which his daily walk and his short lessons left at his disposal, only Pépin knew. He talked rarely with the servants,—"a thing," his father told him, "that no
  • 69. gentleman would wish to do;" and other children never entered at the de Villersexel door, "for," said the Comte, "children sow unfortunate ideas and spread disease." But there were compensations. One was the full-length portrait over the chimney-piece in the dining-room. Pépin had no conception of how great was the signature it bore, or of the fabulous sum which it had cost, but he knew it was very beautiful, and, besides, it was his mother,—the sad-eyed, pale dream-mother he had never seen. The portrait of the Comtesse de Villersexel had been one of the sensations at the Salon of seven years before. The young Brazilian was represented at the moment when the bow left the strings of her violin, and on her lips and in her eyes yet dwelt the spirit of the music she had been playing. A clinging gown of ivory-white silk emphasized rather than hid the lines of her figure, of strangely girlish slenderness, but straight and proud as that of a young empress. In its frailty lay the keynote of the portrait's charm. It was like a reflection in clear water that a touch might disturb, or a young anemone that a breath might destroy,—not a picture before which people disputed and proffered noisy opinions, but one which imposed silence, like the barely audible note of a distant Angelus. It stood before the memory of its original, as it had been a spirit, finger on lip, at the doorway of a tomb. This portrait of his mother dominated the life of Pépin like the half- remembered substance of a dream. He had known nothing of her in the life, for the breath of being had passed from her lips to his at the moment of his birth, but with the intuition of childhood, he seemed to know that this was one who would have loved him and whom he would have loved. He spent hours before the picture, silent, spell- bound, gazing into the deep and tender eyes that shone with the same pathetic pleading that lay so eloquently in his own, and the only outbreak of rage which had ever stirred his simple serenity was on one occasion when his nurse had found him thus absorbed, and, receiving no response to her summons, half alarmed and half indignant, reproached him with wasting his time before a stupid
  • 70. picture. Then Pépin had whirled around upon her, his lips compressed, his small brown hands clenched, and a look in his eyes that terrified even the stout and prosaic Cornish-woman out of her accustomed attitude of fat complacency. "A stupid picture?" he stormed. "But it is my mother, do you hear, my mother! You are a wicked woman, Elizabeth!" It was when Pépin was nearing his seventh birthday that a wonderful thing happened. The Comte was giving a great reception to the Russian Ambassador, and on an impulse which, perhaps, even he himself could hardly have explained, sent for his son. The child was aroused from sleep, and, but half awake and totally uncomprehending, was submitted by the worthy Elizabeth to a veritable cyclone of washing, combing, and brushing, and finally, clad in spotless duck, was led by the maître d'hôtel down the long corridor to the door of the grand salon, which, at his approach, swung open under the touch of one of the under servants. Pépin, dazed by the radiance of many lights and a great clamor of voices, paused on the threshold, and, with a swift intuition of what was demanded of him, made his slow, stiff bow. "Le Vicomte de Villersexel," said the maître d'hôtel in a loud voice at his side, and Pépin, seeing his father beckon to him from the group where he stood, slipped close to him through the crowd, and was surprised to find that the Comte took his hand in his, and bent forward to say in a whisper,— "You are to hear Pazzini play the violin. That is why I sent for you. He was your mother's teacher." Like all that had gone before, what followed was to Pépin like a dream—a beautiful dream, never to be forgotten. A great hush had settled upon the brilliant assemblage, for even in Paris there are still things which society will check its chatter to hear, and the tall, gray- bearded man, consulting with the pianist over there, was Pazzini, the great Pazzini, whose services had been more than once commanded by royalty in vain. De Villersexel had drawn Pépin nearer to the
  • 71. piano in the brief interval, and as the opening chords of the introduction were struck, he found himself but a few feet from the famous violinist, his hand still linked in that of his father, his eyes fixed in wonder upon this unknown man who had been his mother's teacher. The first low note of the violin fell upon the silence like a faint, far voice, heard across a wide reach of calm water, and, as the marvelous melody swelled into the fullness of its motif, something new and strange stirred in Pépin's heart, mounted and tightened in his throat, ran tingling to his finger-tips. Through his half parted lips the breath tiptoed in and out, and his deep eyes grew every instant, could he have known it, more like those of the picture that he loved. So he stood entranced, seeing, hearing nothing but Pazzini and Pazzini's violin, till the sonata drew imperceptibly toward its close. Like the child, the great violinist seemed to be unconscious of all that surrounded him. Slowly, tenderly, he led his music through the last phrases, until he paused before the supreme high sweetness of the final note. How it was he could never have told, but, in that infinitesimal fraction of time, the training of years played him false. He knew that his finger-tip slipped an incalculable atom of space, but it was too late. The bow was on the string, and the imperceptibly flatted note swelled, sank, and died away, unrecognized, he thought, with a throb of thankfulness, by any save his master ear. And then— "Ah-h!" said Pépin. The long ripple of applause drowned the child's whisper, and for an instant the terror in his heart grew still, believing his exclamation unheard. Then it leaped to life again, for Pazzini was looking at him, his bow hovering above the instrument like his mother's in the picture. In the mysterious solitude of the crowded room the eyes of these two met, each reading the other's as they had been an open book, and in Pépin's was the pain of a wounded animal, and in Pazzini's a great wonder and sorrow, as of one who has hurt without intention, and mutely pleads for pardon.
  • 72. As the applause ceased, the violinist turned to the Comte, and pointed to Pépin with his bow. "Who is that child?" he asked. The thaw in the de Villersexel's "academic manner" had been but momentary. With the renewed hum of conversation he was himself again, pale, proud, and immovable. "It is my son, Pépin," he replied, with stiff courtesy. "How shall I thank you for your playing? It was the essence of perfection, as it has ever been, and ever will be." But he could not know, as he turned away with Pépin, that in his heart the violinist said, "Her boy! I understand!" The miracle of his summons to the salon that night was not, as it appeared, the actual climax of existence, for a new marvel awaited Pépin on the morrow. The doors of the dining-room had barely slid together behind them when the Comte turned to him. "Yesterday was Christmas," he said. Pépin made no reply. In fact, the stupor which descended upon him at this infraction of the usual routine of life effectually deprived him, for the moment, of the power of speech. "It was Christmas," repeated the Comte, "and because of that you are invited to a—a—soirée to-day. Do you know the English children on the entresol?" "I have seen them," faltered Pépin, "but we have never spoken. You told me"— "I have changed my mind," broke in his father. "Monsieur 'Ameelton"—stumbling desperately over the English name—"has asked me to let you visit them this afternoon, and I have said yes to him. Elizabeth will dress you. Now you may go." Barely conscious that Pépin had added a timid "Merci, papa!" to his customary bow, de Villersexel turned to his writing-table, as the door closed behind the little Vicomte, and, unlocking a drawer, took
  • 73. therefrom a letter which had come to him that morning, and, burying himself in his arm-chair, proceeded to its careful reperusal. It was in the fine Italian handwriting of Pazzini, and ran as follows:— My dear Friend,—This is to be at once a confession and a prayer. What would you say if I were to tell you that Pazzini—the flawless Pazzini, as men are pleased to call me!—murdered, yes, murdered last night's sonata by flatting that wonderful final note? Oh, it was a very little thing, and passed unnoticed, for they are stupid, these wise people who listen to me, and they did not hear. Even you, my poor friend, even you could not detect that tiny flaw that was a monstrous crime. No, of all who listened, there were but two that understood what I had done. I was one of these, and the other was your son—Pépin. Do you know what that means, Monsieur le Comte de Villersexel? Do you understand that it is but one ear in millions that is so finely keyed that this minutest deviation could wound it like the most utter discord? And I wounded him, your Pépin. I saw it in his eyes. Therefore I tell you— I, who know—that he is a genius, a genius greater than his mother, and that, like her, he must be my pupil. I have none other now. It shall be the work of my old age to make him the greatest violinist of his day. Give him to me, my friend, if not for his own sake, then for hers! Pazzini. Prime feature of all the year to the little Hamiltons, on the entresol, was their Christmas tree. It arrived in some unknowable way in the corner of the grand salon on the morning after Christmas, and, from the moment of its advent, the doors were sealed, and only the privileged world of grown-ups went in and out, and could see the splendors within. Inch by inch the hands of the tall clock in the antichambre dragged themselves around successive circles toward the hour of revelation, and, keyed to the snapping point of frenzy,
  • 74. the slender figure of George and the round, squat form of John stood motionless before the inexorable timepiece, awaiting the stroke of four. This suspense was harrowing enough in itself, and only made bearable by recourse to occasional mad caperings up and down the hall, and whoops of mingled ecstasy and exasperation. What was worse was the delay in the arrival of their guests. Later, the latter would be an indispensable part of the festivities: just now they were mere impediments in the path of bliss. Even the grown- ups were more considerate, and came on time. Well they might, since they were granted immediate admission to the enchanted room, and came out with maddening accounts of what was to be seen therein. They sat about the small salon, and talked the stupid things of which they were so fond of talking,—Hamilton, tall, straight, and with an amused twinkle in his eyes, while he watched his wife vainly endeavoring to calm her sons as they foamed and pranced at the sealed doors; Miss Kedgwick, who wrote books, and invited boys to tea; Monsieur de Bercy, who was odd because he spoke no English, but who cut heads out of nuts and apples, and drew droll pictures on scraps of paper; Miss Lys, who played the piano for "Going to Jerusalem;" and Mr. Sedgely, who talked very low in her ear, and said the great trouble with "Going to Jerusalem" was that the players couldn't go there in good earnest—whatever that might mean. But would the doors never open? The children arrived by twos and threes, shook hands limply with their elders, greeted their small hosts with embarrassed ceremony, and then, as if suddenly inoculated with the latter's madness, commenced to foam and prance in their turn before the unyielding portals. Last of all came Pépin, all brown, who bowed at the door, and then in turn to each of those who spoke to him. Suddenly, with a shout, the children burst through the opened doorway, and gathered in voluble groups about the glistening miracle which shone like a hundred stars in the gathering twilight. For a half hour all was chaos, and Pépin, standing a little apart,
  • 75. marveled and was still. Dancing figures whirled about him, bearing boxes of soldiers, toy villages, dolls, trumpets, drums. The air was full of the wailing of whistles, the cries of mechanical animals, and the clamor of childish comment. But to Pépin even the dazzling novelty of his surroundings was as nothing, compared to one object which drew and fixed his attention from the first instant, as the needle is held rigid by the magnetic pole. High up upon the tree, clearly outlined against its background of deep green, and gleaming gorgeously with fresh varnish in the light of the surrounding candles, hung a violin—not one like Monsieur Pazzini's, large and of a dull brown, but small—a violin for Pépin himself to hold, and new, and bright, and beyond all things beautiful and to be desired! Then his attention was distracted for a moment. From the time of his entrance the eyes of Miss Lys had followed the dignified and silent little Frenchman, and where Miss Lys went Mr. Sedgely followed, so that now the two were so close that they brushed his elbow, and Pépin, turning with an instinctive "Pardon," saw that they were watching him curiously. When, with a feeling of restlessness under their scrutiny, he looked once more towards the tree, the violin was gone! An instant later, he saw it in the madly sawing hands of George Hamilton, dancing like a faun down the room, and he was conscious of a great faintness, such as he had known but once before,—when he had cut his hand, and the doctor had sewed it, as Elizabeth sewed rips in cloth. "He is adorable," said Ethel Lys, "but I have never seen a sadder face. What eyes!—two brown poems." "He makes my heart ache," answered Sedgely, slowly, "and yet I could hardly say why. Ask him what he wants off the tree." The girl was on her knees by Pépin before the phrase was fairly finished. "What didst thou have for Christmas?" she asked, falling unconsciously into that tender second singular which slips so
  • 76. naturally from the lips at sight of a French child. "I?—but nothing," replied the little Vicomte, pleased out of his anguish by the sound of his own tongue amid the babel of English phrases. The girl at his side looked at him with so frank an astonishment that he felt it necessary to explain. "I have my gifts on the day of the year. Christmas is an English fête, and I am French. So I have nothing." "Nothing!" replied Miss Lys blankly, and then, of a sudden, slipped her arm around him, and drew his head close to her own. "What dost thou see on the tree that thou wouldst like to have?" she asked, eagerly. "What is there, dearest?" And, at the unwonted tenderness of her question, the floodgates of Pépin's reserve suddenly gave way. Placing his hands upon the girl's shoulders, he searched her face with his eyes. "If there were another violin"—he began, and, faltering, stopped, and turned away to hide the tears that would come, strive as he might to hold them back. "Did you hear him—and see him?" queried Miss Lys, a minute after, furiously backing Sedgely into a corner by the lapels of his frock coat. "You did—you know you did! And you are still here? Lord! What a man!" Sedgely shrugged his shoulders with a pretense of utter bewilderment. "What must I do?" he inquired, blankly. "Do?" stormed Miss Lys. "Do? Why, scour Paris till you find a violin precisely like that one George is doing his best to saw in half. Here! Clément is at the door with the trois-quarts. Tell him to drive you like mad to the Printemps—to the big place opposite the Grand Hotel—to the Louvre—to the Bon Marché—anywhere—everywhere! But inside of one hour I must have that violin!"
  • 77. When Sedgely returned, thirty minutes later, violin in hand, Ethel met him at the door. "They are all at tea," she said. "We'll call Pépin out." She placed the violin in the hands of the Vicomte without a word, and without a word Pépin took it from her. The instrument slid to his cheek as if impelled by its own desire. "Canst thou play?" she asked him. "No," said Pépin, "and, besides, it is but a toy. I do not want to hear it. But I like to feel it—here." And he moved his cheek caressingly against the cheap varnish. "Don't you think you might"—began Sedgely, and then found himself on the other side of the door, and Miss Lys facing him with an air of hopeless resignation. "I—act-u-ally—be-lieve," she said, with an effort at calm, "that you were going to ask him to thank me for it!" "Why not?" said Sedgely. "Lord! What a man!" said Miss Lys. In the dining-room of the de Villersexel apartment the Comte paced slowly to and fro, with bent head, and fingers that locked and unlocked behind his back. In the heavy chair before the fire, Pazzini seemed shrunk to but half his normal size, a mere rack of clothes, two lean white hands, that gripped the dragons' heads upon the arms of the fauteuil, and a pale stern face that looked into the smouldering embers, and beyond—immeasurably beyond. "How did it happen?" he asked, after a time. "Shall I ever know?" broke out de Villersexel irritably. "Pépin had been to a children's party below there on the entresol, at the English lawyer's. He and his imbecile of a bonne were entering the ascenseur. She goes from spasm to spasm, so there is no telling. But
  • 78. Welcome to our website – the perfect destination for book lovers and knowledge seekers. We believe that every book holds a new world, offering opportunities for learning, discovery, and personal growth. That’s why we are dedicated to bringing you a diverse collection of books, ranging from classic literature and specialized publications to self-development guides and children's books. More than just a book-buying platform, we strive to be a bridge connecting you with timeless cultural and intellectual values. With an elegant, user-friendly interface and a smart search system, you can quickly find the books that best suit your interests. Additionally, our special promotions and home delivery services help you save time and fully enjoy the joy of reading. Join us on a journey of knowledge exploration, passion nurturing, and personal growth every day! ebookbell.com