Slide 1

Slide 1 text

Event Sourcing The Story Telling of (Business) Processes

Slide 2

Slide 2 text

No content

Slide 3

Slide 3 text

Event Sourcing The Story Telling of (Business) Processes

Slide 4

Slide 4 text

No content

Slide 5

Slide 5 text

It’s a Tool

Slide 6

Slide 6 text

Every single program can be reduced to Input Transformation Output * Former Boss

Slide 7

Slide 7 text

Example Time

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

Every team plays every other team twice 306 Matches

Slide 10

Slide 10 text

Home Team Away Team

Slide 11

Slide 11 text

Home Team Away Team +3 +0

Slide 12

Slide 12 text

Home Team Away Team +3 +0 +1 +1

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

Transformation Input Output

Slide 16

Slide 16 text

Transformation Input Output

Slide 17

Slide 17 text

Transformation Input Output

Slide 18

Slide 18 text

Transformation Input Output ?

Slide 19

Slide 19 text

https://www.kaggle.com/mkhvalchik/soccer/data

Slide 20

Slide 20 text

Match Team1 Team2 League SoSo Soccer

Slide 21

Slide 21 text

No content

Slide 22

Slide 22 text

sum(m.away_team_points) as points from (select *, case when away_team_goal > home_team_goal then 3 when home_team_goal = away_team_goal then 1 else 0 end as away_team_points, case when away_team_goal > home_team_goal then 1 else 0 end as away_team_wins, case when away_team_goal = home_team_goal then 1 else 0 end as away_team_draws, case when away_team_goal < home_team_goal then 1 else 0 end as away_team_losses from matches) m join leagues l on m.league_id = l.id group by season, away_team_api_id) t join leagues l on t.league_id = l.id join teams te on te.api_id = t.team_id group by (t.team_id, t.season) order by points desc, goal_difference desc, goals_for desc;

Slide 23

Slide 23 text

sum(m.away_team_points) as points from (select *, case when away_team_goal > home_team_goal then 3 when home_team_goal = away_team_goal then 1 else 0 end as away_team_points, case when away_team_goal > home_team_goal then 1 else 0 end as away_team_wins, case when away_team_goal = home_team_goal then 1 else 0 end as away_team_draws, case when away_team_goal < home_team_goal then 1 else 0 end as away_team_losses from matches) m join leagues l on m.league_id = l.id group by season, away_team_api_id) t join leagues l on t.league_id = l.id join teams te on te.api_id = t.team_id group by (t.team_id, t.season) order by points desc, goal_difference desc, goals_for desc;

Slide 24

Slide 24 text

def standings(season, league_id) Repo.all(m in Match, where: m.season == ^season and m.league_id == ^league_id) |> Map.merge(%{row.home_team_api_id => home_team_values(row) }, &add_up/3) |> Map.merge(%{row.away_team_api_id => away_team_values(row) }, &add_up/3) |> Enum.sort_by(fn s -> {s.points, s.goal_difference, s.goals_for} end, &>=/2) end defp home_team_values(row) do %{ games: 1, wins: Rules.wins(row.home_team_goal, row.away_team_goal), draws: Rules.draws(row.home_team_goal, row.away_team_goal), losses: Rules.losses(row.home_team_goal, row.away_team_goal), goals_for: row.home_team_goal, goals_against: row.away_team_goal, points: Rules.points(row.home_team_goal, row.away_team_goal) } end defp add_up(_k, nil, v2), do: v2 defp add_up(_k, v1, v2) when is_integer(v1), do: v1 + v2 defp add_up(_k, v1, v2) when is_map(v1), do: Map.merge(v1, v2, &add_up/3)

Slide 25

Slide 25 text

Problem?

Slide 26

Slide 26 text

Simplicity?

Slide 27

Slide 27 text

Performance?

Slide 28

Slide 28 text

Change!

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

No content

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

T1 T2 T3

Slide 37

Slide 37 text

T1 T2 T3

Slide 38

Slide 38 text

There are only two hard things in Computer Science …

Slide 39

Slide 39 text

Rethink

Slide 40

Slide 40 text

It’s a Tool

Slide 41

Slide 41 text

It’s a Tool that helps you capture stuff that happened

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

TeamFounded TeamFounded TeamFounded TeamFounded TeamFounded

Slide 44

Slide 44 text

TeamFounded TeamFounded TeamFounded TeamFounded TeamFounded TeamQualified TeamQualified TeamQualified

Slide 45

Slide 45 text

TeamFounded TeamFounded TeamFounded TeamFounded TeamFounded TeamQualified TeamQualified TeamQualified SeasonStarted

Slide 46

Slide 46 text

MatchStarted MatchStarted MatchStarted TeamFounded TeamFounded TeamFounded TeamFounded TeamFounded TeamQualified TeamQualified TeamQualified SeasonStarted

Slide 47

Slide 47 text

MatchStarted MatchStarted MatchStarted TeamFounded TeamFounded TeamFounded TeamFounded TeamFounded TeamQualified TeamQualified TeamQualified MachEnded MachEnded MachEnded SeasonStarted

Slide 48

Slide 48 text

MatchStarted MatchStarted MatchStarted TeamFounded TeamFounded TeamFounded TeamFounded TeamFounded TeamQualified TeamQualified TeamQualified MachEnded MachEnded MachEnded SeasonEnded SeasonStarted

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

project %TeamQualifiedForSeason{} = qualified do Ecto.Multi.insert(multi, :standings, %Standing{ season_id: qualified.season_id, team_api_id: qualified.team_api_id, team_long_name: qualified.team_long_name, league_id: qualified.league_id, sort_key: sort_key(0, 0, 0) }) end project %MatchEnded{} = ended do season_id = id_from_stream_id(ended.season_id) home_team = Standing.by_team_and_season(ended.home_team_api_id, season_id) away_team = Standing.by_team_and_season(ended.away_team_api_id, season_id) home_team_diff = team_changeset(home_team, ended.home_team_goal, ended.away_team_goal) away_team_diff = team_changeset(away_team, ended.away_team_goal, ended.home_team_goal) multi |> Ecto.Multi.update(:home_team, home_team_changeset) |> Ecto.Multi.update(:away_team, away_team_changeset) end

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

(Re)Tell (Re)Tell (Re)Tell Capture

Slide 53

Slide 53 text

It’s a Tool that helps you capture events …

Slide 54

Slide 54 text

… and tell a story from them

Slide 55

Slide 55 text

Commands Aggregates Process Handlers

Slide 56

Slide 56 text

Greg Young (yt/LDW0QWie21s) SoSo Soccer (gh/leifg/so_so_soccer) Commanded (gh/commanded) leif.io