-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
331 lines (235 loc) · 10.4 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Akka Persistence - CQRS-ES</title>
<meta name="description" content="Presentation for Trivento about Akka Persistence and how to use it for CQRS-ES and why I created the process framework.">
<meta name="author" content="Jeroen Gordijn">
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/theme/league.css" id="theme">
<!-- Code syntax highlighting -->
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/highlight.js/8.6/styles/railscasts.min.css"
<!-- Printing and PDF exports -->
<script>
var link = document.createElement( 'link' );
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match( /print-pdf/gi ) ? 'css/print/pdf.css' : 'css/print/paper.css';
document.getElementsByTagName( 'head' )[0].appendChild( link );
</script>
<!--[if lt IE 9]>
<script src="lib/js/html5shiv.js"></script>
<![endif]-->
</head>
<body>
<div class="reveal">
<!-- Any section element inside of this container is displayed as a slide -->
<div class="slides">
<section>
<h1>Akka Persistence</h1>
<h3>CQRS-Event Sourcing</h3>
<p>
<small>Why I created <a href="https://github.com/jgordijn/process">Process Framework</a></small>
</p>
</section>
<section>
<h2>Agenda</h2>
<ul>
<li>Refresh CQRS & Event Sourcing (ES)</li>
<li>Akka Persistence</li>
<li>Modelling a process</li>
<li>Process Framework</li>
</ul>
</section>
<!-- Example of nested vertical slides -->
<section>
<section>
<h2>CQRS</h2>
<p>Command Query Responsibility Segregation.</p>
<img src="/images/cqrs.png" height="460px"/>
<p style="position: absolute; bottom: 0px; left:0px; font-size: x-small">source: <a hlink="http://www.udidahan.com/2009/12/09/clarified-cqrs/">http://www.udidahan.com/2009/12/09/clarified-cqrs</a></p>
</section>
<section>
<h2>Event Sourcing</h2>
<img src="images/eventsourcing.png" height="480px"/>
<p style="position: absolute; bottom: 0px; left:0px; font-size: x-small">source: <a hlink="https://msdn.microsoft.com/en-us/library/jj591559.aspx">https://msdn.microsoft.com/en-us/library/jj591559.aspx</a></p>
</section>
<section>
<h2>Event Sourcing</h2>
<p align="left">
Remember everything
</p>
<ol>
<li>Restore state by loading events (if needed)</li>
<li>Do work</li>
<li>Save event</li>
<li>Update internal state with <em><strong><u>saved event</u></strong></em><br/>
Ensures written events can be read</li>
</ol>
<aside class="notes" data-markdown>
Crucial written events are used in update.
1. Forces enough info in events
2. Forces events can be read
</aside>
</section>
<section>
<h2>Pseudo code</h2>
<pre><code class="scala" data-trim contenteditable>
val result = doSomething()
val event = Done(result)
persist(event).andThen {
updateState(event)
}
def updateState = {
case evt: Done => globalState.something = evt.thing}
}
</code></pre>
</section>
<section data-markdown>
<script type="text/template">
## CQRS-ES: Perfect match?
1. Commands lead to events
2. ES just stores these events
3. View can use stored events
</script>
</section>
<section>
<h2>CQRS & ES</h2>
<img src="images/cqrs_es.png" height="520px"/>
<p style="position: absolute; bottom: 0px; left:0px; font-size: x-small">source: <a hlink="https://msdn.microsoft.com/en-us/library/jj591559.aspx">https://msdn.microsoft.com/en-us/library/jj591559.aspx</a></p>
</section>
</section>
<section data-markdown data-separator="^\n---\n$" data-separator-vertical="^\n--\n$" data-separator-notes="^Note:">
<script type="text/template">
## Akka Persistence
1. No longer Experimental in 2.4
2. PersistentActor
3. PersistentView
4. AtLeastOnceDelivery
--
## PersistentActor
* Command Processor backed by Event Store
* <span style="color:rgb(255, 198, 109);">`persistenceId`</span> (key in the store)
* <span style="color:rgb(255, 198, 109);">`reveiveCommand`</span> process incoming commands
* <span style="color:rgb(255, 198, 109);">`receiveRecover`</span> process events on recovery
* <span style="color:rgb(255, 198, 109);">`persist(`</span>`evt`<span style="color:rgb(255, 198, 109);">`){`</span> `fn: evt => Unit` <span style="color:rgb(255, 198, 109);">`}`</span>
Save event to eventstore and call `fn` when persisted
--
## PersistentActor
![showcode](images/talkcheapshowcode.jpg)
Note:
Geef duidelijk aan volgorde, Send, Persist, Update
Functionaliteit van recovery end receiveCommand
--
## PersistentView
* <span style="color:rgb(255, 198, 109);">`persistenceId`</span> key in the store of events
* <span style="color:rgb(255, 198, 109);">`viewId`</span> view id to persist snapshots
* <span style="color:rgb(255, 198, 109);">`receive`</span> process events (either persistent or not)
* Polls event store !!
--
## PersistentView
![letslook](images/letslook.jpg)
---
## Generic Akka usage
![general](images/Normal Actor Interaction.png)
Note:
Stimulus from outside
--
## (Long) Running Process
* Actor is started with initial data
* Resond to sender
* Actor autonomously performs tasks to complete
* Process flow is important
--
## Simple Process
![Simple](images/Basic flow.png)
--
###Traditional Akka
![yell](images/showmethecode.jpg)
Note:
Open Intellij
--
## Problems
* Business logic part of recovery
* Hard to see flow
* Huge file (Order flow in OHM 993 lines)
--
## Advanced Process
![Advanced](images/advanced flow.png)
---
# Process Framework
--
## What is a process?
- Flow <!-- .element: class="fragment" data-fragment-index="1" -->
One step after another <!-- .element: class="fragment" data-fragment-index="1" -->
- Steps <!-- .element: class="fragment" data-fragment-index="2" -->
The logic of a process state <!-- .element: class="fragment" data-fragment-index="2" -->
--
## Step
1. Action
2. Result ⇒ Event
3. Update state
<strong>Event Sourcing</strong>: First persist (2.), then update state (3.)
--
## Process Flow
- Chain of steps
--
## Features
* Retry step until successful
* Execute steps in parallel
* Control Flow with `IfThenElse`
* Callback on steps (`onComplete`)
--
![codeplease](images/codeplease.jpg)
--
## Problems
* One big mutable state
This gives many `Option[T]` in state
* Isolation Recovery does not completely follow flow
Note:
Steps are not completely isolated. Playback is done in flow
--
## Future features
* Make more typesafe/functional
Steps should be a function from `State ⇒ State'`
* Better isolation of steps
* Flow visualizer (both compile- & runtime)
Note:
More typesafety will make compiler help with flow.
--
![help](images/helpme.jpg)
---
![questions](images/questions.jpg)
</script>
</section>
</div>
</div>
<script src="lib/js/head.min.js"></script>
<script src="js/reveal.js"></script>
<script>
// Full list of configuration options available at:
// https://github.com/hakimel/reveal.js#configuration
Reveal.initialize({
controls: true,
progress: true,
history: true,
center: true,
// Display the page number of the current slide
slideNumber: true,
transition: 'slide', // none/fade/slide/convex/concave/zoom
// Optional reveal.js plugins
dependencies: [
{ src: 'lib/js/classList.js', condition: function() { return !document.body.classList; } },
{ src: 'plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
{ src: 'plugin/highlight/highlight.js', async: true, condition: function() { return !!document.querySelector( 'pre code' ); }, callback: function() { hljs.initHighlightingOnLoad(); } },
{ src: 'plugin/zoom-js/zoom.js', async: true },
{ src: 'plugin/notes/notes.js', async: true }
]
});
</script>
</body>
</html>