-
Notifications
You must be signed in to change notification settings - Fork 2
/
feed.xml
787 lines (567 loc) · 64 KB
/
feed.xml
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
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title></title>
<description>blog for veblush, programmer</description>
<link>http://veblush.github.io/</link>
<atom:link href="http://veblush.github.io/feed.xml" rel="self" type="application/rss+xml"/>
<pubDate>Fri, 15 Jul 2016 23:17:05 +0900</pubDate>
<lastBuildDate>Fri, 15 Jul 2016 23:17:05 +0900</lastBuildDate>
<generator>Jekyll v3.1.3</generator>
<item>
<title>Online game server works on Akka.NET for the last 2 months</title>
<description><p>I’ve been working on works related to <a href="http://veblush.github.io/posts/online-game-server-on-akkanet/">Online game server on Akka.NET</a>
which I made a speech about at NDC 2016. Most of work is for polishing and paying down the technical debt.
This article explains what has been done and what will be (maybe) done later.</p>
<h3 id="works-done">Works done</h3>
<h4 id="expressive-interface">Expressive Interface</h4>
<p><a href="https://github.com/SaladLab/Akka.Interfaced">Akka.Interfaced</a> uses C# <code class="highlighter-rouge">interface</code> to define a contract
for communicating with an actor. It’s natural for C# programmer and makes easy to send and receive messages with actors.
However <code class="highlighter-rouge">interface</code> is used and programmers seem to expect that major interface features are possible to use,
generic and inheritance are supported to satisfy this.</p>
<h6 id="generic">Generic</h6>
<p>Generic interface and method are supported and following interface can be defined.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="c1">// generic interface
</span><span class="k">interface</span> <span class="n">IGreeter</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="p">:</span> <span class="n">IInterfacedActor</span> <span class="p">{</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Greet</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;(</span><span class="n">U</span> <span class="n">name</span><span class="p">);</span> <span class="c1">// generic method
</span> <span class="n">Task</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="nf">GetCount</span><span class="p">();</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Actor can implement the previous interface like:</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">class</span> <span class="nc">class</span> <span class="n">GreetingActor</span> <span class="p">:</span> <span class="n">InterfacedActor</span><span class="p">,</span> <span class="n">IGreeter</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="p">{</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="nf">Greet</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">Greet</span><span class="p">&lt;</span><span class="n">U</span><span class="p">&gt;(</span><span class="n">U</span> <span class="n">name</span><span class="p">)</span> <span class="p">{</span> <span class="p">...</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Supporting generic interface was quite simple because generic parameters are determined at the time of creating an actor.
But for generic method, it was not because new generic handler should be instantiated
whenever new message containing different parameters arrives.</p>
<p>Related issue: <a href="https://github.com/SaladLab/Akka.Interfaced/issues/30">Generic interface #30</a></p>
<h6 id="inheritance">Inheritance</h6>
<p><code class="highlighter-rouge">Interface</code> inheritance can be used like following. Work to support it was simple.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">public</span> <span class="k">interface</span> <span class="n">IGreeter</span> <span class="p">:</span> <span class="n">IInterfacedActor</span> <span class="p">{</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="nf">Greet</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">);</span>
<span class="p">}</span>
<span class="k">public</span> <span class="k">interface</span> <span class="n">IGreeterEx</span> <span class="p">:</span> <span class="n">IGreeter</span> <span class="p">{</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="nf">GreetEx</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">);</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Related issue: <a href="https://github.com/SaladLab/Akka.Interfaced/issues/27">Support interface inheritance #27</a></p>
<h4 id="polishing-api">Polishing API</h4>
<p>At the previous Proof-Of-Concept stage, all works were for implementing and verifying the idea, not for polishing.
Because polishing itself costs many hours than expected and doesn’t always end up with good result.
But this time is good for this polishing.</p>
<h6 id="remove-crtp-curiously-recurring-template-pattern">Remove CRTP (Curiously Recurring Template Pattern)</h6>
<p>Base class, <code class="highlighter-rouge">InterfacedActor</code> needs a dedicate place to store a message dispatch table for each class.
CRTP is convenient to handle this because generic class always allocate new static storage when being instantiated.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">GreeterActor</span> <span class="p">:</span> <span class="n">InterfacedActor</span><span class="p">&lt;</span><span class="n">GreeterActor</span><span class="p">&gt;,</span> <span class="n">IGreeter</span> <span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
</code></pre>
</div>
<p>But this pattern causes programmer make a silly mistake like providing a wrong generic parameter.
For previous case, wrong base class such as <code class="highlighter-rouge">InterfacedActor&lt;GuestActor&gt;</code> cannot prevent compiler to build it
but will throw runtime exception. It’s not good for safe programming environment so it’s improved like following.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">public</span> <span class="k">class</span> <span class="nc">GreeterActor</span> <span class="p">:</span> <span class="n">InterfacedActor</span><span class="p">,</span> <span class="n">IGreeter</span> <span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Related issue: <a href="https://github.com/SaladLab/Akka.Interfaced/issues/20">Change InterfacedActor&lt;T&gt; to InterfacedActor #20</a></p>
<h6 id="unhandled-exception-policy">Unhandled exception policy</h6>
<p>Previous version of <code class="highlighter-rouge">InterfacedActor</code> always returns an exception back to a requester
an unhandler exception is thrown while processing requests.
This decision was made because Requester-Responder is similar with Caller-Callee.
But Akka.NET doesn’t work like this and it becomes a problem.
Akka.NET actor always propagates unhandled exceptions to a supervisor (usually parent) not to a requester. (<a href="http://getakka.net/docs/Fault%20tolerance">Fault Tolerance</a>)
If the interfaced actor works different from Akka.NET standard way, it could be a source of confusion.
Because of this, <code class="highlighter-rouge">InterfacedActor</code> is updated to follow the standard way but the other option is provided.
If you want to propagate an unhandled exception to requester like before, <code class="highlighter-rouge">ResponsiveException</code> can be used.
Following <code class="highlighter-rouge">Greet</code> method will propagate only <code class="highlighter-rouge">ArgumentException</code> to requester and others to supervisor.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">class</span> <span class="nc">GreeterActor</span> <span class="p">:</span> <span class="n">InterfacedActor</span><span class="p">,</span> <span class="n">IGreeter</span> <span class="p">{</span>
<span class="p">[</span><span class="nf">ResponsiveException</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">ArgumentException</span><span class="p">))]</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">&gt;</span> <span class="n">IGreeter</span><span class="p">.</span><span class="nf">Greet</span><span class="p">(</span><span class="kt">string</span> <span class="n">name</span><span class="p">)</span> <span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Related issue: <a href="https://github.com/SaladLab/Akka.Interfaced/issues/21">Exception policy for handling request, notification and message. #21</a></p>
<h6 id="add-extensions-to-observer-and-message-handler-like-request-handler">Add extensions to observer and message handler like request handler</h6>
<p><code class="highlighter-rouge">InterfacedActor</code> can handle 3 different types of message.</p>
<ul>
<li>Request: Request messages which are defined at <code class="highlighter-rouge">IInterfacedActor</code>.</li>
<li>Notification: Event notification messages which are defined at <code class="highlighter-rouge">IInterfacedObserver</code>.</li>
<li>Message: Message which have a handler annotated by <code class="highlighter-rouge">[MessageHandler]</code>.</li>
</ul>
<p>Among these kinds of message, only Request handler could make use of filter and the extended handler.
But programmers expect that these kinds of message are equally supported so same features are added to notification and message handler.</p>
<p><code class="highlighter-rouge">LogFilter</code> can be used for message handler now.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">class</span> <span class="nc">TestActor</span> <span class="p">:</span> <span class="n">InterfacedActor</span> <span class="p">{</span>
<span class="p">[</span><span class="n">MessageHandler</span><span class="p">,</span> <span class="n">Log</span><span class="p">]</span>
<span class="k">private</span> <span class="k">void</span> <span class="nf">OnMessage</span><span class="p">(</span><span class="kt">string</span> <span class="n">message</span><span class="p">)</span> <span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Notification handler for observer can be implemented with an extended handler.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">class</span> <span class="nc">TestActor</span> <span class="p">:</span> <span class="n">InterfacedActor</span><span class="p">,</span> <span class="n">IExtendedInterface</span><span class="p">&lt;</span><span class="n">ISubjectObserver</span><span class="p">&gt;</span>
<span class="p">[</span><span class="n">ExtendedHandler</span><span class="p">]</span>
<span class="k">void</span> <span class="nf">Event</span><span class="p">(</span><span class="kt">string</span> <span class="n">eventName</span><span class="p">)</span> <span class="p">{</span>
<span class="p">...</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Related issue: <a href="https://github.com/SaladLab/Akka.Interfaced/issues/16">Let observer handler work with ExtendedHandler and Filter like Interfaced handler. #16</a></p>
<h6 id="terse-slimclient-api">Terse SlimClient API</h6>
<p>SlimClient does not depend on Akka.NET to make actors accessible from clients outside of Akka.NET.
Because <code class="highlighter-rouge">ActorRef</code> for SlimClient is implemented quite differently, interpretation is required to
send and receive <code class="highlighter-rouge">InterfacedActorRef</code> and <code class="highlighter-rouge">InterfacedObserver</code> across the boundary between SlimClient and Akka.NET.</p>
<p>For example, following code shows IUserLogin.Login which gets an observer created at SlimClient and
returns User actorRef created at Akka.NET to SlimClient.
Previous version of library forced you to use ID and translate it manually to pass and construct UserRef.
It is not a transparent API and makes bloated code.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">interface</span> <span class="n">IUserLogin</span> <span class="p">:</span> <span class="n">IInterfacedActor</span> <span class="p">{</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="nf">Login</span><span class="p">(</span><span class="kt">int</span> <span class="n">observerId</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">var</span> <span class="n">userId</span> <span class="p">=</span> <span class="n">await</span> <span class="n">userLogin</span><span class="p">.</span><span class="nf">Login</span><span class="p">(...);</span>
<span class="n">var</span> <span class="n">user</span> <span class="p">=</span> <span class="k">new</span> <span class="nf">UserRef</span><span class="p">(</span><span class="k">new</span> <span class="nf">SlimActor</span><span class="p">(</span><span class="n">userId</span><span class="p">),</span> <span class="nf">SlimRequestWaiter</span><span class="p">(</span><span class="n">_comm</span><span class="p">,</span> <span class="k">this</span><span class="p">)));</span>
</code></pre>
</div>
<p>It’s improved like following. <code class="highlighter-rouge">InterfacedActorRef</code> and <code class="highlighter-rouge">InterfacedObserver</code> can be used directly like Akka.NET.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">interface</span> <span class="n">IUserLogin</span> <span class="p">:</span> <span class="n">IInterfacedActor</span> <span class="p">{</span>
<span class="n">Task</span><span class="p">&lt;</span><span class="n">IUser</span><span class="p">&gt;</span> <span class="nf">Login</span><span class="p">(</span><span class="n">IUserObserver</span> <span class="n">observer</span><span class="p">);</span>
<span class="p">}</span>
<span class="n">var</span> <span class="n">user</span> <span class="p">=</span> <span class="n">await</span> <span class="n">userLogin</span><span class="p">.</span><span class="nf">Login</span><span class="p">(...);</span>
</code></pre>
</div>
<p>Related issue: <a href="https://github.com/SaladLab/Akka.Interfaced/issues/23">Concise way for retrieving InterfacedActorRef on slim-client. #23</a></p>
<h4 id="extend-slimclient-channel">Extend SlimClient channel</h4>
<p>Single TCP channel has been extended.</p>
<h5 id="udp-support">UDP Support</h5>
<p>UDP channel is introduced in addition to TCP. Rationale for adding UDP channnel is:</p>
<ul>
<li>
<p>HandOver: There is an issue on TCP for handling handover on mobile environment.
To make it happen, reliable data transfer layer should be implemented on top of TCP.
Instead of hard work on TCP, how about using reliable UDP?
It’s better for fast hand-over because it doesn’t establish the connection.</p>
</li>
<li>
<p>Various QOS:
TCP allows only reliable and ordered transmission but UDP allows many options
such as reliable-unoredered and unreliable. For sending player movement notification message,
unreliable-sequenced is enough and more performant than TCP.</p>
</li>
</ul>
<p><a href="https://github.com/lidgren/lidgren-network-gen3">Lidgren Network Library</a> is chosen to be used
even it is not designed for server environment because writing robust communication library
takes lots of effort. Just <a href="https://github.com/SaladLab/LidgrenUdpNet">forked</a> it and updated it to meet my own requirements.
Following works are done.</p>
<ul>
<li>Support .NET 3.5 for nuget package: <a href="https://www.nuget.org/packages/LidgrenUdpNet/">LidgrenUdpNet</a></li>
<li>Support UnityPackage: <a href="https://github.com/SaladLab/LidgrenUdpNet/releases">LidgrenUdpNet for Unity3D</a></li>
<li>Add fast message handler.</li>
<li>Connection is defined not by EndPoint but by ConnectionID to allow hand-over between WiFi and 3G.</li>
</ul>
<p>And also Lidgren Network Library provides a P2P network feature which is a good tool for network game.</p>
<h5 id="remote-channel-binding">Remote channel binding</h5>
<p>Remote channel binding allow clients to connect another servers owning specfic actors directly.
Previous one allowed clients to access remote actor only via a channel establised at first connection.
(Forwarding Channel in the following figure)
This method is quite simple to use but it causes unncessary traffic for forwarding channel.</p>
<div class="highlighter-rouge"><pre class="highlight"><code> * Forwarding Channel * Direct Channel
Client -&gt; Channel1 -&gt; UserActor Client -&gt; Channel1 -&gt; UserActor
| |
~~~|~~~~ | ~~~~~~~~
| |
+---- -&gt; GameActor +----&gt; Channel2 -&gt; GameActor
</code></pre>
</div>
<p>To deal with this problem, client can establish a channel on remote server to access remote actors.
(Direct Channel in the previous figure)</p>
<p>Following code shows how server open a remote channel to allow client to access GameActor directly.
It opens a remote channel and returns connection information to a client.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="n">async</span> <span class="n">Task</span><span class="p">&lt;</span><span class="n">IGamePlayer</span><span class="p">&gt;</span> <span class="n">IUser</span><span class="p">.</span><span class="nf">JoinGame</span><span class="p">(</span><span class="kt">long</span> <span class="n">id</span><span class="p">)</span> <span class="p">{</span>
<span class="n">var</span> <span class="n">game</span> <span class="p">=</span> <span class="nf">GetGame</span><span class="p">(</span><span class="n">id</span><span class="p">);</span>
<span class="n">await</span> <span class="n">game</span><span class="p">.</span><span class="nf">Join</span><span class="p">(</span><span class="n">_id</span><span class="p">,</span> <span class="p">...);</span>
<span class="n">var</span> <span class="n">boundTarget</span> <span class="p">=</span> <span class="n">await</span> <span class="n">_channel</span><span class="p">.</span><span class="nf">BindActorOrOpenChannel</span><span class="p">(</span>
<span class="n">game</span><span class="p">.</span><span class="nf">CastToIActorRef</span><span class="p">(),</span> <span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="k">new</span> <span class="nf">TaggedType</span><span class="p">(</span><span class="k">typeof</span><span class="p">(</span><span class="n">IGamePlayer</span><span class="p">),</span> <span class="n">_id</span><span class="p">)</span> <span class="p">},</span>
<span class="n">ActorBindingFlags</span><span class="p">.</span><span class="n">OpenThenNotification</span> <span class="p">|</span> <span class="n">ActorBindingFlags</span><span class="p">.</span><span class="n">CloseThenNotification</span><span class="p">,</span>
<span class="s">"GameGateway"</span><span class="p">,</span> <span class="n">_id</span><span class="p">);</span>
<span class="k">return</span> <span class="n">boundTarget</span><span class="p">.</span><span class="n">Cast</span><span class="p">&lt;</span><span class="n">GamePlayerRef</span><span class="p">&gt;();</span>
<span class="p">}</span>
</code></pre>
</div>
<p>After client receives connection information from server, it establishes new connection to reach GameActor
and commuicate with it as a regular actor.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="n">var</span> <span class="n">gamePlayer</span> <span class="p">=</span> <span class="n">User</span><span class="p">.</span><span class="nf">JoinGame</span><span class="p">(</span><span class="n">gameId</span><span class="p">,</span> <span class="p">...);</span>
<span class="k">if</span> <span class="p">(</span><span class="n">gamePlayer</span><span class="p">.</span><span class="nf">IsChannelConnected</span><span class="p">()</span> <span class="p">==</span> <span class="k">false</span><span class="p">)</span>
<span class="n">await</span> <span class="n">gamePlayer</span><span class="p">.</span><span class="nf">ConnectChannelAsync</span><span class="p">();</span>
<span class="n">gamePlayer</span><span class="p">.</span><span class="nf">CallSomething</span><span class="p">();</span>
</code></pre>
</div>
<h5 id="bind-multiple-interfaces-to-a-bound-actor">Bind multiple interfaces to a bound actor</h5>
<p>Bound actor to channel could be accessed via one bound interface. (Not means that actor can implement only one interface.)
It changed to bind multiple interfaces to an actor and the following use case can be implemented with this feature.</p>
<p>For example, <code class="highlighter-rouge">UserActor</code> has two kinds of permission to access. Normal access and administrative access.
Normal access is only permitted before client is confirmed to have an administrative priviledge.
At first, write <code class="highlighter-rouge">UserActor</code> implementing <code class="highlighter-rouge">IUser</code> and <code class="highlighter-rouge">IUserForAdmin</code> as separate methods by permission and
bind only <code class="highlighter-rouge">IUser</code> to bound user actor.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="k">class</span> <span class="nc">UserActor</span> <span class="p">:</span> <span class="n">IInterfacedActor</span><span class="p">,</span> <span class="n">IUser</span><span class="p">,</span> <span class="n">IUserForAdmin</span> <span class="p">{</span>
<span class="n">Task</span> <span class="n">IUser</span><span class="p">.</span><span class="nf">NormalMethod</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
<span class="n">Task</span> <span class="n">IUserForAdmin</span><span class="p">.</span><span class="nf">PowerMethod</span><span class="p">()</span> <span class="p">{</span> <span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>After verifying client is an administrator, tell channel to allow a client to access <code class="highlighter-rouge">IUserForAdmin</code> methods
by binding <code class="highlighter-rouge">IUserForAdmin</code> to bound actor. After binding, client can access methods of <code class="highlighter-rouge">IUserForAdmin</code>.</p>
<div class="language-csharp highlighter-rouge"><pre class="highlight"><code><span class="n">Task</span> <span class="nf">Authorize</span><span class="p">(...)</span> <span class="p">{</span>
<span class="n">await</span> <span class="n">_channel</span><span class="p">.</span><span class="nf">BindType</span><span class="p">(</span><span class="n">Self</span><span class="p">,</span> <span class="k">new</span> <span class="n">TaggedType</span><span class="p">[]</span> <span class="p">{</span> <span class="k">typeof</span><span class="p">(</span><span class="n">IUserForAdmin</span><span class="p">)</span> <span class="p">});</span>
<span class="p">}</span>
</code></pre>
</div>
<h4 id="example-works">Example works</h4>
<p>Writing examples has been an important part through the whole development process.
In developing libraries, it could be the first way to make sure it works well and
show how easy programmer can write features that libraries want to help with.
And it let me know what is missing and what is bad quickly.
Also it is really helpful to let newcomer understand how the library works and learn best practices.
Because of this several advantages, I have been updating examples even it costs tons of efforts.</p>
<h5 id="keep-reference-applications-up-to-date">Keep reference applications up-to-date</h5>
<p>There are three reference applications: <a href="https://github.com/SaladLab/Chatty">Chatty</a>,
<a href="https://github.com/SaladLab/TicTacToe">TicTacToe</a>, <a href="https://github.com/SaladLab/Snake">Snake</a>.
These have been updated by the changes of library. (More hours were spent than expected)</p>
<p>These three diffrent applications share common parts and help for extracting common reusable parts.
In this period, <a href="https://github.com/SaladLab/Aim.ClusterNode">Aim.ClusterNode</a> are written for covering
common cluster node behaviours.</p>
<p>Also all servers in application can run as a service now.</p>
<h5 id="project-scaffolding">Project scaffolding</h5>
<p>New tool, <a href="https://github.com/SaladLab/Akka.ProjectScaffolding">Akka.ProjectScaffolding</a> is introduced
to help for initiating new project with akka.net and unity.
For building online game, at least 3 projects should be created and many libraries have to be installed and configurated,
which are boring and time-consuming. At first, Visual Studio <a href="https://msdn.microsoft.com/en-us/library/ms185301.aspx">Project Template</a>
was being considered but it is not easy to support other IDEs such as Visual Sutio Code and to maintain template project without burden
so standalone scaffolding tool was chosen.</p>
<p>Run a program from <a href="https://github.com/SaladLab/Akka.ProjectScaffolding/releases">Release</a> and
it will create new project configured to work on right now. Following command generates new project using cluster.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>akka-unity-cluster NewProjectName
</code></pre>
</div>
<h4 id="writing-test-and-documentation">Writing test and documentation</h4>
<p>Some tests and documentationwere skipped because of a rapid development. Missing parts have been written.
For tests, writing test itself is a little bit easy, whereas building testing environment is sometimes really hard.
And writing documentation is always difficult. :)</p>
<p>New tests</p>
<ul>
<li><a href="https://github.com/SaladLab/Akka.Interfaced/tree/master/core/CodeGenerator.Tests">Akka.Interfaced CodeGenerator</a> :
Make simple test code for verifying result code not by comparing generated code source but by analyzing generated semantic trees.</li>
<li><a href="https://github.com/SaladLab/Akka.Interfaced.SlimSocket/tree/master/core/Akka.Interfaced.SlimSocket.Tests">Akka.Interfaced.SlimSocket</a> :
It was impossible to write test code because SlimClient and Akka.Interfaced were mutual exclusive but it became possible to write after removing SlimClient project.</li>
</ul>
<p>New documentation</p>
<ul>
<li><a href="https://github.com/SaladLab/Akka.Interfaced/blob/master/docs/Manual.md">Akka.Interfaced Manual</a></li>
</ul>
<h3 id="futher-work">Futher work</h3>
<p>These are short summary that want to be implemented. But when and how are not determined.</p>
<h4 id="encrypting-udp-communication">Encrypting UDP communication</h4>
<p>Add encryption to UDP communication. UDP channel identifies each connection by connection ID (not endpoint)
so someone can insert a malicious packet into other’s connection if he can guess connection ID and sequence number.
To prevent this, encryption have to be adopted.
For the same reason, <a href="https://en.wikipedia.org/wiki/QUIC">QUIC</a> specifies that TLS/SSL is mandatory for keeping connection safe.</p>
<h4 id="wire-instead-of-protobufnet">Wire instead of Protobuf.NET</h4>
<p>SlimSocket uses <a href="https://github.com/mgravell/protobuf-net">protobuf-net</a> for a message serializer.
Because of limits of protobuf, it is practically impossible to use inheritance and generic for serializing a message.
Also protobuf-net always make a empty container variable null, which surprises a programmer. (maybe me alone?)
To alleviate this problem, alternative serializer can be used such as <a href="https://github.com/akkadotnet/Wire">wire</a>.</p>
<h4 id="distributed-actortable">Distributed ActorTable</h4>
<p>Current implementation <a href="https://github.com/SaladLab/Akka.Cluster.Utility/blob/master/docs/DistributedActorTable.md">DistributedActorTable</a>
at <a href="https://github.com/SaladLab/Akka.Cluster.Utility">Akka.Cluster.Utility</a> provides a distribued actor table across cluster nodes.
But table should be placed at one node, which make this SPOF/B.
To make fault tolerant distributed system, this table should be improved.</p>
<h4 id="net-core-support">.NET Core Support</h4>
<p>Let’s support .NET Core which is the future of .NET. It provides a lot of benefits such as
hosting services on Linux or Windows nano server. But we need to wait for all dependent libraries to
support .NET core first.</p>
<h3 id="closing">Closing</h3>
<p>All these works were estimated for my 1 month work but turned out 2 months. :cry:
But I finished all planned works and I’m happy about it.</p>
</description>
<pubDate>Fri, 15 Jul 2016 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/akkanet-online-game-works-for-the-last-2-months/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/akkanet-online-game-works-for-the-last-2-months/</guid>
<category>akkanet</category>
</item>
<item>
<title>Online game server on Akka.NET</title>
<description><p>I made a speech about “Online game server on Akka.NET” at <a href="https://ndc.nexon.com">NDC</a> 2016.
Following are slides and Q&amp;As in the session.</p>
<h2 id="slides">Slides</h2>
<ul>
<li><a href="http://www.slideshare.net/veblush/online-game-server-on-akkanet-ndc2016">Slideshare</a></li>
<li><a href="/assets/posts/2016-05-16-online-game-server-on-akkanet/NDC2016_OnlineGameServer_With_AkkaNet_English.pptx">PPT</a></li>
</ul>
<h2 id="qa">Q&amp;A</h2>
<h4 id="basic">Basic</h4>
<h6 id="should-i-concern-about-multi-thread-synchronization-and-thread-blocking-on-akkanet"># Should I concern about multi-thread synchronization and thread-blocking on Akka.NET?</h6>
<p>Basically, No.
Actor model which akka provides is the another way to write concurrent code
without complex issues such as multi-threading and thread-blocking.</p>
<h6 id="is-message-passing-only-method-for-accessing-the-state-of-actor-any-latency-or-io-overhead-related-with"># Is message passing only method for accessing the state of actor? Any latency or IO overhead related with?</h6>
<p>Yes. Message passing only and it adds more latency and IO overhead but it’s well-optimized and good to go.</p>
<h6 id="what-does-happen-to-child-actors-when-their-parent-actor-stops-is-it-could-be-spof"># What does happen to child actors when their parent actor stops? Is it could be SPOF?</h6>
<p>Child actors will stop when their parent actor stops.
SPOF could be handled with high level tools such as akka.cluster not with actor itself.</p>
<h6 id="any-performance-problem-when-there-are-lots-of-messages-in-one-actor-mailbox"># Any performance problem when there are lots of messages in one actor mailbox.</h6>
<p>One actor processes one message at a time. So that actor will be busy in processing all messages
and takes more time to respond requests. But it doesn’t affect other actors because they are isolated from each others.</p>
<h6 id="how-can-i-synchronize-data-when-one-actor-is-shared-from-several-nodes-in-a-cluster-any-lock-is-required"># How can I synchronize data when one actor is shared from several nodes in a cluster. Any lock is required?</h6>
<p>Actor is only accessable via ActorRef so nodes cannot access data of actor just can send a message to it.
When several messages received from nodes, the actor will process a message at a time so no lock is required to synchronize requests.</p>
<h6 id="is-there-a-way-to-broadcast-a-message-to-many-actors-on-akkanet"># Is there a way to broadcast a message to many actors on Akka.NET?</h6>
<p>Yes. There are two ways for that. First one is using wildcard included
<a href="http://getakka.net/docs/Working%20with%20actors#identifying-actors-via-actor-selection">ActorSelection</a> and
second one is using
<a href="http://getakka.net/docs/working-with-actors/Routers#broadcast">Broadcast Router</a>.</p>
<h4 id="programming-pattern">Programming Pattern</h4>
<h6 id="deadlock-may-occur-when-two-actors-send-a-message-to-each-other-and-await-how-can-we-handle-it"># Deadlock may occur when two actors send a message to each other and await. How can we handle it?</h6>
<p>Yes it can cause deadlock. Because of this problem, send and await pattern is <a href="http://bartoszsypytkowski.com/dont-ask-tell-2/">not recommended</a>.
But if you want, there are three workarounds.</p>
<ul>
<li>
<p>Like a lock-use scenario, you can set await hierarchies for actors.
For more info about lock hierarchy, read <a href="http://www.drdobbs.com/parallel/use-lock-hierarchies-to-avoid-deadlock/204801163">Use Lock Hierarchies to Avoid Deadlock</a>.</p>
</li>
<li>
<p>ReentrantAttribute in Akka.Interfaced allows an actor to handle other messages while waiting await response.
This can makes you avoid deadlock but you need to take care of reentrancy in await state.</p>
</li>
</ul>
<h6 id="mmorpg-can-be-implemented-with-the-actor-model-there-could-be-many-interactions-between-actors-in-mmorpg-and-it-seems-hard-to-build-it"># MMORPG can be implemented with the actor model? There could be many interactions between actors in MMORPG and it seems hard to build it.</h6>
<p>If actors depend on each others’ state and need lots of synchronized interactions, it will be hard to build a system with actors.
Therefore we need a system to make this easy. In case of TicTacToe, there is a GameActor for handling this problem.
This GameActor receives all game commands from users in a game and processes it easily. (It’s like a single-threaded programming.)
If a MMORPG whose world is separate into several isolated zones, you can use same approch for each zones.
But for a MMORPG whose world is not separate such as a seemless world, it will be a challenging work.</p>
<h6 id="transaction-for-multiple-actors-for-examples-trade-between-two-users-requires-transaction-to-implement-it"># Transaction for multiple actors? For examples, trade between two users requires transaction to implement it.</h6>
<p>If we can sqeeze multiple entities into one actor like zone actor, it will be solve easily.
But an user inventory doesn’t seem to work like this. In this case, regular distributed transation will be an answer.
<a href="https://en.wikipedia.org/wiki/Two-phase_commit_protocol">Two-Phase commit protocol</a> is a common solution and
you can check
<a href="http://www.slideshare.net/petabridge/distributed-transactions-in-akkanet">How do I do transactions across a distributed system?</a>.</p>
<h6 id="any-race-condition-for-trackabledata-set"># Any race condition for TrackableData Set?</h6>
<p>No. TrackableData is not for concurrent data modification.
It just tracks the changes of data and propages changes to other systems such as DB and client.
There is no race condition because an actor owns trackabledata instances and processes a message at a time.</p>
<h4 id="integration">Integration</h4>
<h6 id="languages-other-than-c-can-interoperate-with-akkanet"># Languages other than C# can interoperate with Akka.NET?</h6>
<p>Yes. Any languages supporting .NET such as C#, F# and VB.NET can interoperate with Akka.NET.
However, it’s not easy now for the environment beyond .NET.</p>
<h6 id="it-it-easy-or-hard-to-write-test-code-on-akkanet"># It it easy or hard to write test code on Akka.NET?</h6>
<p>Fundamentally it is harder than writing test code consisting of calling synchronized methods
because the environment with multiple actors sending messages to each others is not deterministic.
But Akka.NET provides handy tools helping for writing unit tests.
Check out <a href="https://petabridge.com/blog/how-to-unit-test-akkadotnet-actors-akka-testkit/">How to Unit Test Akka.NET Actors with Akka.TestKit</a>.</p>
<h6 id="can-akkanet-interop-with-akka-on-jvm"># Can Akka.NET interop with Akka on JVM?</h6>
<p>Unfortunately, No. Check this <a href="https://github.com/akkadotnet/akka.net/issues/1629">Issue</a>.</p>
<h4 id="performance">Performance</h4>
<h6 id="it-seems-to-have-performance-issues-do-you-have-stress-tests"># It seems to have performance issues. Do you have stress tests?</h6>
<p>Still I don’t have any benchmark on whole system but I did tests on components and results looked good.
From the Akka.NET manual, 50 million msg/sec on a single machine and ~2.5 million actors per GB of heap.</p>
<h6 id="latency-could-be-problematic-when-hundreds-of-servers-send-messages-on-network"># Latency could be problematic when hundreds of servers send messages on network?</h6>
<p>When an actor send a message to other actor in same machine,
it doens’t use network just put a message in a recipient’s mailbox.
So you need to put actors interacting with each others alot in same machine to avoid network stress.</p>
<h4 id="etc">Etc</h4>
<h6 id="you-said-that-monstersweeperz-uses-c-iocp-but-there-is-no-iocp-api-on-net-how-did-you-do"># You said that MonsterSweeperz uses C# IOCP but there is no IOCP API on .NET how did you do?</h6>
<p>Yes, there is no IOCP API on .NET and I didn’t make a lib for that.
MonsterSweeperz uses .NET socket which is implemented on IOCP so I said like that.</p>
<h6 id="any-problem-with-full-gc-latency-if-not-could-you-tell-me-the-maximum-size-of-heap"># Any problem with full GC latency? If not, could you tell me the maximum size of heap?</h6>
<p>MonsterSweeperz has not suffered any GC problems because basic memory optimization already has been done
and quick responsiveness was not a requirement of system. The maximum size of heap was about 1-2 GB.</p>
</description>
<pubDate>Mon, 16 May 2016 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/online-game-server-on-akkanet/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/online-game-server-on-akkanet/</guid>
<category>akkanet</category>
</item>
<item>
<title>How I build my blog using Jekyll</title>
<description><p>Recently I has been building blog. It was expected to take
at most 2 days but more time spent because of some traps.
But anyway it’s done!</p>
<h2 id="requirements">Requirements</h2>
<ul>
<li>Simple UI</li>
<li>Easy to insert code blocks and math expressions</li>
<li>Supports both english and korean</li>
</ul>
<h2 id="works">Works</h2>
<h5 id="create-github-repository"># Create Github repository</h5>
<p>Personal github repository
<a href="https://github.com/veblush/veblush.github.io">veblush.github.io</a> is created
for hosting blog by <a href="https://pages.github.com/">Github Pages</a> service.
Github provides the neat way to build sites from Jekyll source pages automatically
but it cannot be used because using plugins is not allowed by github.
So manual build process have to be prepared.</p>
<h5 id="install-jekyll-3"># Install Jekyll 3</h5>
<p><a href="https://jekyllrb.com/">Jekyll</a> 3.1.3 is installed.
With ruby gem utility, it is quite easy.</p>
<div class="highlighter-rouge"><pre class="highlight"><code>&gt; gem install jekyll
</code></pre>
</div>
<h5 id="theme"># Theme</h5>
<p>I don’t have the ability to design web sites and don’t have time to do it, either.
So I decided to use theme but choosing right theme among tons of themes is really
time-consuming and hard-to-pick work.
But accidently tidy blog <a href="http://nithinbekal.com">nithinbekal</a> was found and
the theme of that was chosen to use. It looks simple and best fit to my requirement.
Based on this theme, layout and css has been modified slightly.</p>
<h5 id="setup-polyglot-plugin"># Setup Polyglot plugin</h5>
<p>Official i18n support is not provided by Jekyll. There are a few ways for supporting it.
<a href="http://untra.github.io/polyglot/">Polyglot</a> was chosen for this blog
because it seemed simple to use and neat.
However it took many hours to setup it because I was not familar with
the detail of Jekyll and there was a weird bug of polyglot active on windows.
Finally this bug is <a href="https://github.com/untra/polyglot/commit/3280a2d84da1a36929fb5615426349dc6cccf4c3">fixed</a>
and it works well now.</p>
<h5 id="setup-asset-path-plugin"># Setup Asset Path plugin</h5>
<p>It seems better to allocate local storage for each post because some of post have
lots of images or diagrams generated with graphviz which are not shared by other posts.
<a href="https://github.com/samrayner/jekyll-asset-path-plugin">Jekyll Asset Path</a> is installed for this.
It works well and is slightly modified to support Polyglot and my own directory naming rule.</p>
<h5 id="import-old-blogs"># Import old blogs</h5>
<p>All posts from previous blog can be imported as HTML format. These HTML articles are tranformed
to markdown with <a href="https://www.pandadoc.com/">Pandadoc</a>. Most of them are good but there are some
incorrect markdowns that should be corrected by hand.
Image links are changed to fit asset directory and math expressions are converted to
kramdown <a href="http://kramdown.gettalong.org/math_engine/mathjax.html">form</a>.
Fortunately it doens’t take long because there are not many articles to be imported.</p>
<h5 id="write-publish-script"># Write publish script</h5>
<p>Two branches are created on Github repository.</p>
<ul>
<li>site branch: Working branch for storing original source of blog.</li>
<li>master branch: Output branch for storing the result of Jekyll from site branch.</li>
</ul>
<p><a href="https://github.com/veblush/veblush.github.io/blob/site/publish.cmd">Publish script</a>
will run Jekyll at site branch and copy output to master branch to update blog.</p>
</description>
<pubDate>Sat, 14 May 2016 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/how-build-blog-using-jekyll/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/how-build-blog-using-jekyll/</guid>
<category>blog</category>
</item>
<item>
<title>Why I move to Jekyll for my blog</title>
<description><p>I used common blog service in creating my blog at 2012.
Blog service was good to write blog right after a few clicks even
it had some drawbacks.
Theseday I have some spare time for this and decide to change it.</p>
<h2 id="drawbacks-of-blog-service">Drawbacks of blog service</h2>
<h5 id="not-easy-to-embed-code-and-math-expression"># Not easy to embed code and math expression</h5>
<p>Embeding code is not easy. My blog has lots of code blocks to be embeded.
Whenever code need to be inserted, I switch blog to HTML mode and insert
a few HTML code for that and switch it back to writing mode,
which is quite bothersome.</p>
<p>Embeding math expression is not easy, too. There is a nice web service to
provide the way to convert LaTeX math expression to an image dynamically.
I used it happily but it requires some manual steps. Also my blog depends on
external service that could be down for maintenance or disappear forever.</p>
<h5 id="need-to-store-original-data-of-diagram-separately"># Need to store original data of diagram separately</h5>
<p>GraphViz and Excel are used for authoring graph and chart which are converted
to images and inserted to blog. For futhur updates, source files
should be stored but because blog service does not provide storage, I backup
these files to the separate place, which is tiresome and easy to forget.</p>
<h2 id="why-i-choose-jekyll">Why I choose Jekyll</h2>
<h5 id="easy-to-embed-code-and-math-expression"># Easy to embed code and math expression</h5>
<p>If you are accustomed to using markdown, it is really hard to imagine a better
way than using markdown to insert a code block.
Jekyll uses <a href="http://kramdown.gettalong.org/">kramdown</a> as a default
markdown engine which is goot at dealing with code and math expression.</p>
<p>Code block with syntax highlighting is rendered like:</p>
<div class="language-javascript highlighter-rouge"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">fancyAlert</span><span class="p">(</span><span class="nx">arg</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span><span class="p">(</span><span class="nx">arg</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">.</span><span class="nx">facebox</span><span class="p">({</span><span class="na">div</span><span class="p">:</span><span class="s1">'#foo'</span><span class="p">})</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre>
</div>
<p>Math expression by LaTeX format is rendered like:</p>
<script type="math/tex; mode=display">\frac{n!}{k!(n-k)!} = {n \choose k}</script>
<h5 id="hosting-on-github"># Hosting on Github</h5>
<p>Github provides pages service for hosting a static web site.
It’s free and good to keep original source files of diagram and chart along with web site.</p>
<h5 id="simple-architecture-and-highly-customizable"># Simple architecture and highly customizable</h5>
<p>Jekyll is a simple tool to transform plain texts to htmls.
It’s easy to understand and can be customized as you want.
With greate customization comes great labor.
In my case, multi langauge plugin <a href="https://untra.github.io/polyglot/">polyglot</a> is used to support
english and korean at the same time.</p>
</description>
<pubDate>Fri, 13 May 2016 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/why-move-to-jekyll/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/why-move-to-jekyll/</guid>
<category>blog</category>
</item>
<item>
<title>Python n-grouper</title>
<description><p><em>Oops sorry! English post is not available.</em></p>
</description>
<pubDate>Thu, 28 Feb 2013 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/python-n-grouper/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/python-n-grouper/</guid>
<category>python</category>
</item>
<item>
<title>Parsing with GOLD Parser</title>
<description><p><em>Oops sorry! English post is not available.</em></p>
</description>
<pubDate>Sun, 09 Dec 2012 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/parsing-with-gold-parser/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/parsing-with-gold-parser/</guid>
<category>parser</category>
</item>
<item>
<title>Filename case sensitivity</title>
<description><p><em>Oops sorry! English post is not available.</em></p>
</description>
<pubDate>Sun, 09 Dec 2012 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/filename-case-sensitivity/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/filename-case-sensitivity/</guid>
<category>windows</category>
</item>
<item>
<title>C++11 variadic trio</title>
<description><p><em>Oops sorry! English post is not available.</em></p>
</description>
<pubDate>Sat, 10 Nov 2012 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/cpp11-variadic-trio/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/cpp11-variadic-trio/</guid>
<category>cpp</category>
</item>
<item>
<title>C++11 rvalue references and move constructors</title>
<description><p><em>Oops sorry! English post is not available.</em></p>
</description>
<pubDate>Thu, 08 Nov 2012 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/cpp11-rvalue-references-and-move-constructors/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/cpp11-rvalue-references-and-move-constructors/</guid>
<category>cpp</category>
</item>
<item>
<title>How windows installer works and free space of SSD</title>
<description><p><em>Oops sorry! English post is not available.</em></p>
</description>
<pubDate>Sat, 03 Nov 2012 00:00:00 +0900</pubDate>
<link>http://veblush.github.io/posts/how-windows-installer-works-and-ssd/</link>
<guid isPermaLink="true">http://veblush.github.io/posts/how-windows-installer-works-and-ssd/</guid>
<category>windows</category>
</item>
</channel>
</rss>