WHAT THIS TALK IS NOT ABOUT
„Best Practices“
Deep dive into DDD, CQRS, Event Sourcing
Refactoring
WHAT IT IS ABOUT
Common (for some of us) software complexity
issues
Techniques that might help and were tried in
production
Continuous/Iterative decoupling
OTHER POSSIBLE WAYS
SQL Server replications
Depends on consumer count and your system load
Replicates the same relational structure
SQL Server Message Broker
Queue based message publishing
Custom data messages
Re-use write-model + caching
Be careful with excessive indexing – this might harm your
writes
Cache rebuild and invalidation issues
MEET NEW ENEMIES (FRIENDS?)
Eventual consistency
Consistency is a myth
Talk with your business people
Tradeoffs
Idempotency and ordering
Event versions
Read-model versions
What about 1 thread?
Desynchronization
Create sync tools
LEVEL 2 – SYNERGY BETWEEN SYSTEMS
Avoid adding new features into monolith
Avoid big-bang reworks
Use strategic design to handle complexity
REWORK != REFACTORING
Two systems side-by-
side works together
Iterative functionality
migration
In-syncOld
System
New
System
Sync
TIP: Sometimes it is
better to start over
TIP: Having backup
strategy keeps your
blood pressure low
TIP: Go live ASAP
LEVEL 3: WRITE MODEL DESIGN
Accepts commands
only
Does not provide
reading operations
Commands results into
sequence of events
Events are immutable
and persisted into
EventStore
Commands RabbitMQ
Banner
Management
Service
Event Store
Events
OR ANY OTHER ORM FRAMEWORK
Aggregates emit events
Aggregates are de-hydrated by replaying historical
events
No setters/getters
Respect encapsulation
NO HIBERNATE
TIP: Events and
commands can be very
natural constructs
TIP: Excluding query
operations can
simplify code a lot
LEVEL 4: EVENT STORE
Stores series of immutable events
There is no delete
Acts as “Event Log”
Has built in projection engine
Is not designed for querying
BannerCreated BannerClickUrlsAdded BannerRenamed BannerRenamed
SYNC: NEW TO OLD
Banner
Event
Event Store
Dispatcher
ACL Service
RabbitMQ
AdministrationDB
Reacts to domain
events
Makes changes into
AdsministrationDB
within small
transactions
Uses Dapper to
simplify persistence
SYNC: OLD TO NEW
Legacy event
ACL Service
RabbitMQ
Reacts to legacy
events
(AdCreated/AdUpd
ated)
ACL transforms
events into
commands
Aggregates are
updated
Banner
Management
Service
Commands From old
system
Events
TIP: Build UI to solve
business cases but
not to edit data
TIP: Exposing tasks
can reduce overhead
for users and for
developers
TIP: Build UI on top
of the API
LEVEL 9: TROUBLESHOOTING AND
DEBUGGING
There is no F5 in distributed systems
Correlate all your requests and messages
Use centralized logging services
INSIDE THE RABBIT HOLE
REST
API
Domain
Service
ACL
Service
ES
Dispatcher
Service
Creative
Upload
API
Creative
Upload
Service
Ad
Analyzer
Service
File
Checker
Service
File
Generation
Service
Publishing
Service
Preview
Service
YOU DON’T NEED THEM ALL - CHOOSE WISELY
De-normalized read models
Strategic design
CQRS
Event sourcing
Projections
ACLs
REST API
Task based UI
Centralized logs
LOTS OF GUNS
ADAPT TO BUSINESS THINKING
Avoid – technical arguments
Code quality is poor
We need to refactor
Technology is old
Everyone is using Angular
now…
Missing “best practices”
We want to try NoSQL…
Prefer – economical arguments
Releases every day
Faster feature development
New products
Involve more developers
MS licenses are expensive…
DON’T GET LOST IN A DUNGEON
Have a VISION
COMMIT
Define Your STRATEGY
Create TACTICS
FIGHT
ADOPT new tactics
Fight HARDER
WIN