ista 2016: event sourcing
TRANSCRIPT
15 – 16 November, SofiaISTACon.org
Event Sourcing
By Vladik Khononov
A New Dimension in Software Design
15 – 16 November, SofiaISTACon.org
Agenda• How it happened
• Why it happened
• How event sourcing solves the problem
• Why event sourcing benefits the company
15 – 16 November, SofiaISTACon.org
LEAD• Id• Name• Email• Phone• Status (Available / Follow-up / Closed / Converted)
15 – 16 November, SofiaISTACon.org
Name Email Phone Status
Stefan Ivanov [email protected] 03-27243457 Available
Viktor Kovachev [email protected] 08-8332491 Available
Martin Mateev [email protected] 04-8537112 Available
Lilyana Yankov [email protected] 04-6092212 Available
15 – 16 November, SofiaISTACon.org
Name Email Phone Status
Stefan Ivanov [email protected] 03-27243457 Available
Viktor Kovachev [email protected] 08-8332491 Available
Martin Mateev [email protected] 04-8537112 Available
Lilyana Yankov [email protected] 04-6092212 Available
15 – 16 November, SofiaISTACon.org
public class Lead {
public long Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public LeadStatus Status { get; set; }
public DateTime? FollowupOn { get; set; }
}
15 – 16 November, SofiaISTACon.org
SELECT * FROM leads
WHERE [name] LIKE ‘%name%’ OR
[phone] LIKE ‘%phone%’ OR
[email] LIKE ‘%email%’;
15 – 16 November, SofiaISTACon.org
Lead #1410
Name Viktor Radkov
Email [email protected]
Phone 09-9801298
Status Available
15 – 16 November, SofiaISTACon.org
public class Lead {
public long Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public LeadStatus Status { get; set; }
public DateTime? FollowupOn { get; set; }
}
15 – 16 November, SofiaISTACon.org
Name Email Phone Status Follow-up
Stefan Ivanov [email protected] 03-27243457 Available
15 – 16 November, SofiaISTACon.org
Name Email Phone Status Follow-up Date
Stefan Ivanov [email protected] 050-8139904 Follow-up 23/11/2016
15 – 16 November, SofiaISTACon.org
Name Email Phone Status Follow-up Date
Stefan Ivanov [email protected] 050-8139904 Converted
15 – 16 November, SofiaISTACon.org
Name Email Phone Status Follow-up Date
Stefan Ivanov [email protected] 050-8139904 Converted
15 – 16 November, SofiaISTACon.org
Lead Events• Lead Was Initialized (Id)
• Status Changed (NewStatus)
• Name Changed (NewName)
• Contact Information Changed (NewEmail, NewPhone)
• Followup Set (Date)
15 – 16 November, SofiaISTACon.org
Lead: Stefan Ivanov• Lead Was Initialized (1410)• Status Changed (Available)• Contact Information Changed ([email protected], 03-27243457)• Status Changed (Followup)• Followup Set (23/11/2016)• Contact Information Changed ([email protected], 050-8139904)• Status Changed (Converted)
15 – 16 November, SofiaISTACon.org
public class Lead {public long Id { get; set; }public string Name { get; set; }public string Email { get; set; }public string Phone { get; set; }public LeadStatus Status { get; set; }public DateTime? FollowupOn { get; set; }public void Apply(LeadWasInitialized event) {…}public void Apply(StatusChanged event) {…}public void Apply(NameChanged event) {…}public void Apply(ContactInfoChanged event) {…}public void Apply(FollowupSet event) {…}
}
15 – 16 November, SofiaISTACon.org
public class Lead {public long Id { get; set; }public string Name { get; set; }public string Email { get; set; }public string Phone { get; set; }public LeadStatus Status { get; set; }public DateTime? FollowupOn { get; set; }public void Apply(LeadWasInitialized event) {…}public void Apply(StatusChanged event) {…}public void Apply(NameChanged event) {…}public void Apply(ContactInfoChanged event) {…}public void Apply(FollowupSet event) {…}
}
Apply(StatusChanged event) {this.Status = event.NewStatus;
}
15 – 16 November, SofiaISTACon.org
public class Lead {public long Id { get; set; }public string Name { get; set; }public string Email { get; set; }public string Phone { get; set; }public LeadStatus Status { get; set; }public DateTime? FollowupOn { get; set; }public void Apply(LeadWasInitialized event) {…}public void Apply(StatusChanged event) {…}public void Apply(NameChanged event) {…}public void Apply(ContactInfoChanged event) {…}public void Apply(FollowupSet event) {…}
}
Apply(NameChanged event) {this.Name = event.NewName;
}
15 – 16 November, SofiaISTACon.org
public class Lead {public long Id { get; set; }public string Name { get; set; }public string Email { get; set; }public string Phone { get; set; }public LeadStatus Status { get; set; }public DateTime? FollowupOn { get; set; }public void Apply(LeadWasInitialized event) {…}public void Apply(StatusChanged event) {…}public void Apply(NameChanged event) {…}public void Apply(ContactInfoChanged event) {…}public void Apply(FollowupSet event) {…}
}
Apply(ContactInfoChanged event) {this.Phone = event.NewPhone;this.Email = event.NewEmail;
}
15 – 16 November, SofiaISTACon.org
public class Lead {public long Id { get; set; }public string Name { get; set; }public string Email { get; set; }public string Phone { get; set; }public LeadStatus Status { get; set; }public DateTime? FollowupOn { get; set; }public void Apply(LeadWasInitialized event) {…}public void Apply(StatusChanged event) {…}public void Apply(NameChanged event) {…}public void Apply(ContactInfoChanged event) {…}public void Apply(FollowupSet event) {…}
}
Apply(FollowupSet event) {this.FollowUpOn = event.Date;
}
15 – 16 November, SofiaISTACon.org
Lead: Stefan IvanovLead Was Initialized (1410)Status Changed (Available)
Contact Information Changed ([email protected],03-27243457)
Status Changed (Converted)
Status Changed (Followup)Followup Set (23/11/2016)
Contact Information Changed ([email protected], 050-8139904)
15 – 16 November, SofiaISTACon.org
Name Email Phone Status Follow-up Date
Stefan Ivanov [email protected] 050-8139904 Converted
15 – 16 November, SofiaISTACon.org
Lead: Stefan IvanovLead Was Initialized (1410)Status Changed (Available)
Contact Information Changed ([email protected],03-27243457)
Status Changed (Converted)
Status Changed (Followup)Followup Set (23/11/2016)
Contact Information Changed ([email protected], 050-8139904)
15 – 16 November, SofiaISTACon.org
Lead: Stefan IvanovLead Was Initialized (1410)Status Changed (Available)
Contact Information Changed ([email protected],03-27243457)
15 – 16 November, SofiaISTACon.org
Lead: Stefan IvanovLead Was Initialized (1410)Status Changed (Available)
Contact Information Changed ([email protected],03-27243457)
Status Changed (Followup)Followup Set (23/11/2016)
Contact Information Changed ([email protected], 050-8139904)
15 – 16 November, SofiaISTACon.org
Lead: Stefan IvanovLead Was Initialized (1410)Status Changed (Available)
Contact Information Changed ([email protected],03-27243457)
Status Changed (Converted)
Status Changed (Followup)Followup Set (23/11/2016)
Contact Information Changed ([email protected], 050-8139904)
15 – 16 November, SofiaISTACon.org
public class Lead {
public long Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Phone { get; set; }
public LeadStatus Status { get; set; }
public DateTime? FollowupOn { get; set; }
}
15 – 16 November, SofiaISTACon.org
Lead: Stefan IvanovLead Was Initialized (1410)Status Changed (Available)
Contact Information Changed ([email protected],03-27243457)
Status Changed (Converted)
Status Changed (Followup)Followup Set (23/11/2016)
Contact Information Changed ([email protected], 050-8139904)
15 – 16 November, SofiaISTACon.org
public class LeadSearch {public long Id { get; private set; }…public List<string> Emails;public List<string> Phones;…public void Apply(ContactInfoChanged event) {…}…
}
Apply(ContactInfoChanged event) {this.Phones.Append(event.NewPhone);this.Emails.Append(event.NewEmail);
}
15 – 16 November, SofiaISTACon.org
public class LeadStatusChangesModel {public long Id { get; set; }public List<StatusLog> StatusChangesLog;…public void Apply(StatusChanged event) {…}…
}Apply(StatusChanged event) {this.StatusChangesLog.Append(
new StatusLog(event.NewStatus, DateTime.Now);
);
15 – 16 November, SofiaISTACon.org
public class LeadStatusChangesModel {public long Id { get; set; }public List<StatusLog> StatusChangesLog;…
}
public class Lead {public long Id { get; set; }public string Name { get; set; }public string Email { get; set; }public string Phone { get; set; }public LeadStatus Status { get; set; }public DateTime? FollowupOn { get; set; }…
}
public class LeadSearch {public long Id { get; private set; }public List<string> Emails;public List<string> Phones;…
}
15 – 16 November, SofiaISTACon.org
Lead: Stefan IvanovLead Was Initialized (1410)Status Changed (Available)
Contact Information Changed ([email protected],03-27243457)
Status Changed (Converted)
Status Changed (Followup)Followup Set (23/11/2016)
Contact Information Changed ([email protected], 050-8139904)
15 – 16 November, SofiaISTACon.org
Event Store API: The Good News
Append(Entity Id + New events)
GetEvents(Entity Id)Event1,Event2,Event3,
….
15 – 16 November, SofiaISTACon.org
Key (Entity Id) Value (Events list)
Lead #1410 1. LeadWasInitialized(1410)
2. StatusChanged(Available)
3. NameChanged(“Martin Mateev”)
4. StatusChanged(Converted)
Lead #1406 1. LeadWasInitialized(1406)
2. StatusChanged(Available’’’)
3. NameChanged(“Lilyana Yankov”)
15 – 16 November, SofiaISTACon.org
Event Store API: The Good News
Append(Entity Id + New events)
GetEvents(Entity Id)Event1,Event2,Event3,
….
15 – 16 November, SofiaISTACon.org
Event Store API: The Bad News
Append(Entity Id + New events)
GetEvents(Entity Id)Event1,Event2,Event3,
….
15 – 16 November, SofiaISTACon.org
CQRS• Command - write data• Query - read data• A use case can be either Command or Query. Never both
15 – 16 November, SofiaISTACon.org
Queries
Read Model
Read DB
Commands
Write Model
Writes DBProjection engine
15 – 16 November, SofiaISTACon.org
Event Sourced Model (Write)
Lead #1410 1. LeadWasInitialized(1410)
2. StatusChanged(Available)
3. NameChanged(“Martin Mateev”)
4. StatusChanged(Closed)
…
1000. StatusChanged(FollowUp)
1001. FollowupSet(16/11/2017)
Read Model
Id 1410
Name Martin Mateev
Status Followup
FollowupOn (Empty)
Email …
Phone …
15 – 16 November, SofiaISTACon.org
Queries
Read Model
Read DB
Commands
Write Model
Writes DBProjection engine
15 – 16 November, SofiaISTACon.org
Event Sourced Model (Write)
Lead #1410 1. LeadWasInitialized(1410)
2. StatusChanged(Available)
3. NameChanged(“Martin Mateev”)
4. StatusChanged(Closed)
5. StatusChanged(Available)
6. NameChanged(“Viktor Rumenov”)
Read Model
Id 1410
Phone …
Status Available
FollowupOn (Empty)
Email …
Name Martin Mateev
15 – 16 November, SofiaISTACon.org
public class Lead {public long Id { get; set; }public string Name { get; set; }public string Email { get; set; }public string Phone { get; set; }public LeadStatus Status { get; set; }public DateTime? FollowupOn { get; set; }public void Apply(LeadWasInitialized event) {…}public void Apply(StatusChanged event) {…}public void Apply(NameChanged event) {…}public void Apply(ContactInfoChanged event) {…}public void Apply(FollowupSet event) {…}
}
Apply(NameChanged event) {this.Name = event.NewName;
}
15 – 16 November, SofiaISTACon.org
Queries
Read Model
Read DB
Commands
Event Sourcing
Event StoreProjection engine
15 – 16 November, SofiaISTACon.org
Queries
Read Model
Read DB
Commands
Write Model
Writes DBProjection
engine
Projection• RDBMS• Documents• Graphs• Files
15 – 16 November, SofiaISTACon.org
Queries
Read Model
Commands
Write Model
Writes DBProjection
engine
Projection• RDBMS• Documents• Graphs• Files• Multiple DBs
Read DBs
15 – 16 November, SofiaISTACon.org
Queries
Read Model
Commands
Write Model
Writes DBProjection
engine
Read DBs
Concurrency• Pessimistic• Optimistic• Optimistic on steroids
15 – 16 November, SofiaISTACon.org
SetFollowupCommand + StatusChangeEvent => Collision
ChangeNameCommand + StatusChangeEvent => OK
15 – 16 November, SofiaISTACon.org
Event Sourcing + CQRS• Flexible business domain modeling• Insane scalability and availability• Rock solid infrastructure
• …look great on your C.V.
15 – 16 November, SofiaISTACon.org
CREATIVE CATALOG
CAMPAIGN PUBLISHING
BILLING USERS MANAGEMENT
LEAD MANAGEMENTCOMMISSIONS CALCULATION
DESK MANAGEMENTVOIP MANAGEMENT
EMAIL CAMPAIGNS
15 – 16 November, SofiaISTACon.org
CREATIVE CATALOG
CAMPAIGN PUBLISHING
BILLING USERS MANAGEMENT
LEAD MANAGEMENTCOMMISSIONS CALCULATION
DESK MANAGEMENTVOIP MANAGEMENT
EMAIL CAMPAIGN
15 – 16 November, SofiaISTACon.org
CREATIVE CATALOG
CAMPAIGN PUBLISHING
BILLING USERS MANAGEMENT
LEAD MANAGEMENTCOMMISSIONS CALCULATION
DESK MANAGEMENTVOIP MANAGEMENT
EMAIL CAMPAIGN
15 – 16 November, SofiaISTACon.org
CREATIVE CATALOG
CAMPAIGN PUBLISHING
BILLING USERS MANAGEMENT
LEAD MANAGEMENTCOMMISSIONS CALCULATION
DESK MANAGEMENTVOIP MANAGEMENT
EMAIL CAMPAIGN
15 – 16 November, SofiaISTACon.org
CREATIVE CATALOG
CAMPAIGN PUBLISHING
BILLING USERS MANAGEMENT
LEAD MANAGEMENTCOMMISSIONS CALCULATION
DESK MANAGEMENTVOIP MANAGEMENT
EMAIL CAMPAIGN
15 – 16 November, SofiaISTACon.org
CREATIVE CATALOG
CAMPAIGN PUBLISHING
BILLING USERS MANAGEMENT
LEAD MANAGEMENTCOMMISSIONS CALCULATION
DESK MANAGEMENTVOIP MANAGEMENT
EMAIL CAMPAIGN
15 – 16 November, SofiaISTACon.org
Available Event Stores
• http://GetEventStore.com
• NEventStore
• Akka Persistence
• Elastic Event Store (Coming soon)
15 – 16 November, SofiaISTACon.org
€100 Discount for attendees of ISTA 2016https://ti.to/webengineers/ddd17/discount/istacon2016
15 – 16 November, SofiaISTACon.org
Domain-Driven Design
• How to identify subdomains?
• How to define business entities?
• How do define events?
• How to talk to business experts?