rabbit-slide-kou-tokyork-11 2016.5.28.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e4f161dc20b7401d3e4f570a81fe852aceda684d
4
+ data.tar.gz: 5f167c805fc70ae5daac9f28661e729d6b4bfd79
5
+ SHA512:
6
+ metadata.gz: 4a89069e1a4bada1eec0de1dd3f5561d677d05f5926646a614ef5a49ca1cda6a7626bfb5288d557e6f88caf85a06200781959688d20909188f0145fb33b0a812
7
+ data.tar.gz: 7beec6c56399fe0973f70cbe8fd3615b68b98e5eaa60cde752415c565576d931f28c52eb7e88854e67e5220319df66207e5a5e1ff0788be125a70ee12c436288
data/.rabbit ADDED
@@ -0,0 +1 @@
1
+ embed-ruby.rab
@@ -0,0 +1,44 @@
1
+ = アプリケーションへのRubyインタープリターの組み込み
2
+
3
+ milter managerとGroongaを例にして、アプリケーションへのCRubyの組み込み・mrubyの組み込みの実装について説明します。
4
+
5
+ == ライセンス
6
+
7
+ === スライド
8
+
9
+ CC BY-SA 4.0
10
+
11
+ 原著作者名は以下の通りです。
12
+
13
+ * 須藤功平(またはKouhei Sutou)
14
+
15
+ === 画像
16
+
17
+ ==== Groongaのロゴ
18
+
19
+ CC BY 3.0
20
+
21
+ 原著作者名は以下の通りです。
22
+
23
+ * Groongaプロジェクト
24
+
25
+ == 作者向け
26
+
27
+ === 表示
28
+
29
+ rake
30
+
31
+ === 公開
32
+
33
+ rake publish
34
+
35
+ == 閲覧者向け
36
+
37
+ === インストール
38
+
39
+ gem install rabbit-slide-kou-tokyork-11
40
+
41
+ === 表示
42
+
43
+ rabbit rabbit-slide-kou-tokyork-11.gem
44
+
@@ -0,0 +1,17 @@
1
+ require "rabbit/task/slide"
2
+
3
+ # Edit ./config.yaml to customize meta data
4
+
5
+ spec = nil
6
+ Rabbit::Task::Slide.new do |task|
7
+ spec = task.spec
8
+ # spec.files += Dir.glob("doc/**/*.*")
9
+ # spec.files -= Dir.glob("private/**/*.*")
10
+ spec.add_runtime_dependency("rabbit-theme-clear-code")
11
+ end
12
+
13
+ desc "Tag #{spec.version}"
14
+ task :tag do
15
+ sh("git", "tag", "-a", spec.version.to_s, "-m", "Publish #{spec.version}")
16
+ sh("git", "push", "--tags")
17
+ end
@@ -0,0 +1,26 @@
1
+ ---
2
+ id: tokyork-11
3
+ base_name: embed-ruby
4
+ tags:
5
+ - rabbit
6
+ - ruby
7
+ - embed
8
+ - milter-manager
9
+ - groonga
10
+ presentation_date: 2016-05-28
11
+ version: 2016.5.28.0
12
+ licenses:
13
+ - CC BY 3.0
14
+ - CC BY-SA 4.0
15
+ slideshare_id: tokyork-11
16
+ speaker_deck_id:
17
+ ustream_id:
18
+ vimeo_id:
19
+ youtube_id:
20
+ author:
21
+ markup_language: :rd
22
+ name: Kouhei Sutou
23
+ email: kou@clear-code.com
24
+ rubygems_user: kou
25
+ slideshare_user: kou
26
+ speaker_deck_user: kou
@@ -0,0 +1,610 @@
1
+ = Embed Ruby
2
+
3
+ : subtitle
4
+ アプリケーションへの\n
5
+ Rubyインタープリターの組み込み
6
+ : author
7
+ 須藤功平
8
+ : institution
9
+ 株式会社クリアコード
10
+ : content-source
11
+ 東京Ruby会議11
12
+ : date
13
+ 2016-05-28
14
+ : allotted-time
15
+ 25m
16
+ : theme
17
+ clear-code
18
+
19
+ = Speaker's award
20
+
21
+ Continuous development award
22
+
23
+ = 受賞者
24
+
25
+ (('tag:center'))
26
+ (('tag:x-large'))
27
+ cedlemo
28
+
29
+ (('tag:center'))
30
+ (('note:Continuous development award'))
31
+
32
+ = 受賞理由
33
+
34
+ (('tag:center'))
35
+ (('tag:large'))
36
+ 2015年1月から継続的に\n
37
+ Ruby-GNOME2の開発に\n
38
+ 参加しているから
39
+
40
+ (('tag:center'))
41
+ (('note:一発すごい改善をした人よりも'))\n
42
+ (('note:地味でも継続的に改善している人を評価したい'))
43
+
44
+ (('tag:center'))
45
+ (('note:Continuous development award'))\n
46
+ (('note:cedlemo'))
47
+
48
+ = 宣伝
49
+
50
+ OSS Gate
51
+
52
+ = OSS Gate
53
+
54
+ OSS開発に\n
55
+ 参加する人を\n
56
+ 増やす取り組み
57
+
58
+ = 背景
59
+
60
+ * OSS利用は当たり前になった
61
+ * →OSS利用者増加
62
+ * (('wait'))開発参加者も増えるといいな
63
+ * →OSS増加
64
+
65
+ (('tag:center'))
66
+ (('note:OSS Gate'))
67
+
68
+ = OSS開発参加
69
+
70
+ * すごい改善じゃなくていい
71
+ * (('wait'))バグレポートとかでいい
72
+ * typo見つけました!とかでもいい
73
+ * サンプルを更新とかでもいい
74
+
75
+ (('tag:center'))
76
+ (('note:OSS Gate'))
77
+
78
+ = OSS Gate参加の動機
79
+
80
+ (('tag:center'))
81
+ (('tag:large'))
82
+ 人それぞれでいい
83
+
84
+ (('tag:center'))
85
+ (('note:OSS Gate'))
86
+
87
+ = 私の動機
88
+
89
+ * ユーザーが自由に使える\n
90
+ ソフトウェアが増えるといいな
91
+ * 自由に使える例:
92
+ * (('wait'))コードを読んで学習できる
93
+ * (('wait'))今日聞いた話の実装を確認できる!
94
+
95
+ (('tag:center'))
96
+ (('note:OSS Gate'))
97
+
98
+ = 興味ある?
99
+
100
+ * 興味?(重要:動機不問)
101
+ * OSS開発に参加したい!
102
+ * OSS開発参加者を増やしたい!
103
+ * (('wait'))5階でワークショップ開催中
104
+ * 説明や見学は私に一声かけて
105
+
106
+ (('tag:center'))
107
+ (('note:OSS Gate'))
108
+
109
+ = 本題
110
+
111
+ Rubyの組み込み\n
112
+ (('note:(CアプリケーションへのRubyインタープリターの組み込み)'))
113
+
114
+ = 動機
115
+
116
+ * 柔軟な記述力が欲しい
117
+ * (('wait'))Cの速さが欲しい
118
+ * (('wait'))Ruby以外の言語とも連携したい
119
+ * Pythonも組み込む
120
+ * (('wait'))なんかカッコいい
121
+
122
+ (('tag:center'))
123
+ (('note:Rubyの組み込み'))
124
+
125
+ = 別の実現方法
126
+
127
+ (('tag:center'))
128
+ (('tag:large'))
129
+ 拡張ライブラリー
130
+
131
+ (('tag:center'))
132
+ (('note:Rubyの組み込み'))
133
+
134
+ = 組み込み(('note:と'))拡張ライブラリー
135
+
136
+ # image
137
+ # src = images/embed-and-extension.svg
138
+ # relative_width = 90
139
+
140
+ (('tag:center'))
141
+ (('note:Rubyの組み込み'))
142
+
143
+ = 拡張ライブラリー
144
+
145
+ * 実現可能:
146
+ * (('wait'))柔軟な記述力が欲しい
147
+ * (('wait'))Cの速さが欲しい
148
+ * 実現不可能:
149
+ * (('wait'))Ruby以外の言語とも連携したい
150
+ * (('wait'))なんかカッコいい感
151
+
152
+ (('tag:center'))
153
+ (('note:Rubyの組み込み'))
154
+
155
+ = 実現方法の選び方
156
+
157
+ * (('wait'))基本は拡張ライブラリー
158
+ * (('wait'))すでにあるアプリなら組み込み
159
+ * (('wait'))選びたい方があるならそっち
160
+
161
+ (('tag:center'))
162
+ (('note:Rubyの組み込み'))
163
+
164
+ = 組み込みを選ぶ時の注意
165
+
166
+ (('tag:center'))
167
+ (('wait'))それなりの覚悟が必要
168
+
169
+ * (('wait'))利用例があまりない
170
+ * 問題遭遇確率が高い
171
+ * (('wait'))問題遭遇時:
172
+ * 自分でソースを読んで調べる
173
+ * 詳しい人に相談\n
174
+ (('note:ささださん<できればサポートを強化したい'))
175
+
176
+ (('tag:center'))
177
+ (('note:Rubyの組み込み'))
178
+
179
+ = 組み込み方を紹介
180
+
181
+ 実例\n
182
+ milter manager\n
183
+ (('note:Since 2008'))
184
+
185
+ = milter manager
186
+
187
+ # image
188
+ # src = images/milter-manager-overview.svg
189
+ # relative_width = 85
190
+
191
+ (('wait'))
192
+ (('tag:center'))
193
+ milterを管理するmilter\n
194
+ (('note:サーバープロセス'))
195
+
196
+ = Ruby組み込みの実装
197
+
198
+ * 初期化
199
+ * fork対応
200
+ * イベントループとシグナル
201
+
202
+ (('tag:center'))
203
+ (('note:milter managerへのRubyの組み込み'))
204
+
205
+ = 初期化:GC関連
206
+
207
+ # coderay c
208
+ {
209
+ /* スタックの底を設定 */
210
+ /* GC時にCのローカル変数に代入されている
211
+ Rubyのオブジェクトをマークするため */
212
+ RUBY_INIT_STACK;
213
+ /* ... */
214
+ }
215
+
216
+ (('tag:center'))
217
+ (('note:milter managerへのRubyの組み込み'))
218
+
219
+ = スタックとマーク対象
220
+
221
+ # coderay c
222
+ {
223
+ RUBY_INIT_STACK;
224
+ /* ... */
225
+ {
226
+ VALUE object = rb_ary_new(); /* マーク対象 */
227
+ }
228
+ }
229
+ {
230
+ VALUE object = rb_ary_new(); /* マーク対象外 */
231
+ }
232
+
233
+ (('tag:center'))
234
+ (('note:milter managerへのRubyの組み込み'))
235
+
236
+ = 確認例
237
+
238
+ # coderay c
239
+ #define MARKED_P(object) rb_objspace_marked_object_p(object)
240
+ {
241
+ RUBY_INIT_STACK;
242
+ {
243
+ VALUE object = rb_ary_new();
244
+ /* GC.start(immediate_sweep: false) */
245
+ printf("%d\n", MARKED_P(object)); /* => 1 */
246
+ }
247
+ }
248
+ {
249
+ VALUE object = rb_ary_new();
250
+ /* GC.start(immediate_sweep: false) */
251
+ printf("%d\n", MARKED_P(object)); /* => 0 */
252
+ }
253
+
254
+ (('tag:center'))
255
+ (('note:スライドのリポジトリー:examples/gc.c'))
256
+
257
+ = GC関連の注意
258
+
259
+ # coderay c
260
+ {
261
+ RUBY_INIT_STACK;
262
+ /* Rubyのオブジェクトを触る
263
+ Cのコードはこのブロック内でだけ使うこと */
264
+ /* Cからのコールバックで
265
+ Rubyのコードを呼び出すときは注意 */
266
+ }
267
+
268
+ (('tag:center'))
269
+ (('note:milter managerへのRubyの組み込み'))
270
+
271
+ = 初期化:シグナル関連
272
+
273
+ # coderay c
274
+ {
275
+ RUBY_INIT_STACK;
276
+ /* シグナルハンドラーを保存 */
277
+ ruby_init(); /* Rubyがシグナルハンドラーを登録 */
278
+ /* シグナルハンドラーを復帰 */
279
+ /* シグナルはアプリで処理したいから */
280
+ }
281
+
282
+ (('tag:center'))
283
+ (('note:milter managerへのRubyの組み込み'))
284
+
285
+ = シグナル復帰例
286
+
287
+ # coderay c
288
+ {
289
+ /* 他のシグナルも同様に復帰 */
290
+ void (*sigint_handler)(int);
291
+ sigint_handler = signal(SIGINT, SIG_DFL);
292
+ ruby_init();
293
+ signal(SIGINT, sigint_handler);
294
+ }
295
+
296
+ (('tag:center'))
297
+ (('note:milter managerへのRubyの組み込み'))
298
+
299
+ = 初期化:引数の処理
300
+
301
+ # coderay c
302
+ {
303
+ /* ...ruby_init()... */
304
+ static char *argv_raw[] = {"milter-manager", "-e;"};
305
+ int argc;
306
+ char **argv;
307
+ argc = sizeof(argv_raw) / sizeof(char *);
308
+ argv = argv_raw;
309
+ ruby_incpush(/* ... */); /* $LOAD_PATHの設定 */
310
+ /* 中でいろいろ初期化するのでダミーの引数で呼ぶ */
311
+ ruby_process_options(argc, argv);
312
+ }
313
+
314
+ (('tag:center'))
315
+ (('note:milter managerへのRubyの組み込み'))
316
+
317
+ = 初期化:アプリの初期化
318
+
319
+ # coderay c
320
+ {
321
+ /* ...ruby_process_options()... */
322
+ /* require中に例外が発生してもここで止める */
323
+ /* ここで止めないと例外を受け取る人がいなくて
324
+ クラッシュ */
325
+ rb_protect(/* rb_require("milter/manager") */);
326
+ }
327
+
328
+ (('tag:center'))
329
+ (('note:milter managerへのRubyの組み込み'))
330
+
331
+ = milter managerとRuby
332
+
333
+ * 組み込み処理系の1つ
334
+ * Pythonも使えるようにしたかった\n
335
+ (('note:結局Ruby必須でPython対応はしなかった'))
336
+ * (('wait'))起動後に(({dlopen()}))で動的にsoを読み込んで組み込み
337
+
338
+ (('tag:center'))
339
+ (('note:milter managerへのRubyの組み込み'))
340
+
341
+ = 起動時に動的に組み込み
342
+
343
+ # image
344
+ # src = images/milter-manager-and-ruby.svg
345
+ # relative_width = 90
346
+
347
+ (('tag:center'))
348
+ (('note:milter managerへのRubyの組み込み'))
349
+
350
+ = 起動時にso読んで組み込み
351
+
352
+ # coderay c
353
+ {
354
+ /* ↓GC用 */
355
+ RUBY_INIT_STACK;
356
+ /* 動的にsoを読んで初期化関数を呼ぶ */
357
+ /* dlopen();
358
+ init = dlsym();
359
+ init(); ←の中でruby_init();とか */
360
+ /* アプリの処理 */
361
+ }
362
+
363
+ (('tag:center'))
364
+ (('note:milter managerへのRubyの組み込み'))
365
+
366
+ = RUBY_INIT_STACK!?
367
+
368
+ # coderay c
369
+ {
370
+ /* ↓アプリ側で呼ぶの!? */
371
+ RUBY_INIT_STACK;
372
+ /* 動的にsoを読んで初期化関数を呼ぶ */
373
+ /* dlopen();
374
+ init = dlsym();
375
+ init(); ←の中でruby_init();とか */
376
+ /* アプリの処理 */
377
+ }
378
+
379
+ (('tag:center'))
380
+ (('note:milter managerへのRubyの組み込み'))
381
+
382
+ = アプリにーlruby…
383
+
384
+ # image
385
+ # src = images/milter-manager-and-ruby-real.svg
386
+ # relative_width = 90
387
+
388
+ (('tag:center'))
389
+ (('note:カッコわるい。。。'))\n
390
+ (('note:milter managerへのRubyの組み込み'))
391
+
392
+ = Ruby組み込み時の意気込み
393
+
394
+ * 本体に組み込む
395
+ * 動的に組み込もうとしない
396
+
397
+ = Ruby組み込みの実装
398
+
399
+ * (('del:初期化'))
400
+ * fork対応
401
+ * イベントループとシグナル
402
+
403
+ (('tag:center'))
404
+ (('note:milter managerへのRubyの組み込み'))
405
+
406
+ = milter manager利用例
407
+
408
+ * (('wait'))大学・企業
409
+ * ユーザー数:数百〜数万人
410
+ * (('wait'))プロバイダー
411
+ * ユーザー数:数千〜数十万人
412
+
413
+ (('wait'))
414
+ (('tag:center'))
415
+ それなりの性能が必要
416
+
417
+ (('tag:center'))
418
+ (('note:milter managerへのRubyの組み込み'))
419
+
420
+ = 性能向上方法
421
+
422
+ * CPU
423
+ * マルチプロセス1択
424
+ * 通信・多同時接続
425
+ * いろいろ
426
+
427
+ (('tag:center'))
428
+ (('note:milter managerへのRubyの組み込み'))
429
+
430
+ = マルチプロセス
431
+
432
+ * (('wait'))マスタープロセス
433
+ (1) (({listen()}))
434
+ (2) (({fork()}))
435
+ * (('wait'))ワーカープロセス
436
+ (1) (({accept()}))
437
+ (2) ↑したクライアントの処理
438
+
439
+ (('tag:center'))
440
+ (('note:milter managerへのRubyの組み込み'))
441
+
442
+ = Ruby組み込みと(({fork()}))
443
+
444
+ * (({fork()}))すると\n
445
+ ワーカープロセスがクラッシュ
446
+ * プロセス終了時とか
447
+ * (('wait'))ヒント:(({fork()}))とスレッド
448
+
449
+ (('tag:center'))
450
+ (('note:milter managerへのRubyの組み込み'))
451
+
452
+ = (({fork()}))とスレッド
453
+
454
+ * 混ぜるな危険
455
+ * (('wait'))Rubyはスレッドを動かしている
456
+ * 例:タイマースレッド
457
+ * (('wait'))(({fork}))時にスレッドのケアが必要
458
+
459
+ (('tag:center'))
460
+ (('note:milter managerへのRubyの組み込み'))
461
+
462
+ = スレッドのケア
463
+
464
+ # coderay c
465
+ VALUE rb_pid;
466
+ /* タイマースレッドの後始末とか
467
+ した上でfork */
468
+ rb_pid = rb_funcall(rb_mKernel,
469
+ rb_intern("fork"),
470
+ 0);
471
+ return NUM2INT(rb_pid);
472
+
473
+ (('tag:center'))
474
+ (('note:milter managerへのRubyの組み込み'))
475
+
476
+ = Ruby組み込みの実装
477
+
478
+ * (('del:初期化'))
479
+ * (('del:fork対応'))
480
+ * イベントループとシグナル
481
+
482
+ (('tag:center'))
483
+ (('note:milter managerへのRubyの組み込み'))
484
+
485
+ = イベントループとシグナル
486
+
487
+ * 気にしなくてよい
488
+ * (('wait'))アプリがシグナルを処理するから
489
+ * (('wait'))拡張ライブラリーなら対応必要
490
+ * イベントループ中にシグナル発生
491
+ * →すぐにイベントループを抜ける
492
+
493
+ (('tag:center'))
494
+ (('note:milter managerへのRubyの組み込み'))
495
+
496
+ = Rubyの組み込みのまとめ
497
+
498
+ * Rubyを組み込む実装方法を紹介
499
+ * (('wait'))動的組み込みは諦めろ
500
+ * (('wait'))(({fork}))時はRubyの(({fork}))を使う
501
+
502
+ (('tag:center'))
503
+ (('note:Rubyの組み込み'))
504
+
505
+ = mrubyの組み込み
506
+
507
+ 実例\n
508
+ Groonga\n
509
+ (('note:Since 2013'))
510
+
511
+ = Groongaとmruby
512
+
513
+ * Groonga
514
+ * 全文検索エンジン(mruby組み込み)
515
+ * (('wait'))高速に検索結果を返し続けたい
516
+ * (('wait'))リソース消費は波がない方がよい\n
517
+ (('note:例:いらなくなったメモリーはすぐに解放'))
518
+
519
+ (('tag:center'))
520
+ (('note:mrubyの組み込み'))
521
+
522
+ = リソース消費
523
+
524
+ # image
525
+ # src = images/groonga-memory-usage.svg
526
+ # relative_height = 90
527
+
528
+ (('tag:center'))
529
+ (('note:mrubyの組み込み'))
530
+
531
+ = メモリー管理
532
+
533
+ * Groonga
534
+ * (('wait'))必要なときに確保
535
+ * (('wait'))いらなくなったら解放
536
+ * mruby
537
+ * (('wait'))GC
538
+ * (('wait'))メモリーが足りなくなったら解放
539
+
540
+ (('tag:center'))
541
+ (('note:mrubyの組み込み'))
542
+
543
+ = GroongaとmrubyのGC
544
+
545
+ * mrubyのGCにGroongaのリソース管理を任せない
546
+ * リソース管理:\n
547
+ mrubyのオブジェクトのsweep時にGroongaのリソースを解放
548
+
549
+ (('tag:center'))
550
+ (('note:mrubyの組み込み'))
551
+
552
+ = mrubyのGCとリソース
553
+
554
+ * mrubyのGC
555
+ * Groongaリソースのサイズを知らない
556
+ * 適切なタイミングでsweepできない
557
+ * (('wait'))(('note:RubyのGCも同じ'))
558
+
559
+ (('tag:center'))
560
+ (('note:mrubyの組み込み'))
561
+
562
+ = 実例1: 明示的な解放
563
+
564
+ # coderay ruby
565
+
566
+ # 検索
567
+ result = table.search(condition)
568
+ begin
569
+ output_result(result) # 出力
570
+ ensure
571
+ result.close # 明示的な解放
572
+ end
573
+
574
+ (('tag:center'))
575
+ (('note:mrubyの組み込み'))
576
+
577
+ = 実例2: 所有権を渡さない
578
+
579
+ # coderay c
580
+
581
+ /* Groonga側でリソース確保 */
582
+ expr = grn_expr_create(/* ... */);
583
+ /* mrubyのオブジェクトとしてラップ */
584
+ mrb_expr = grn_mrb_value_from_grn_obj(mrb, expr);
585
+ /* mruby側は参照して処理する */
586
+ mrb_size = mrb_funcall(mrb, mrb_expr,
587
+ "estimate_size", 1, mrb_table);
588
+ /* Groonga側でリソース解放 */
589
+ grn_expr_close(expr);
590
+
591
+ (('tag:center'))
592
+ (('note:mrubyの組み込み'))
593
+
594
+ = mruby組み込みのまとめ
595
+
596
+ * GCに任せないという選択
597
+ * 使用メモリー量を安定させるため
598
+ * 安定した性能を出すため
599
+
600
+ (('tag:center'))
601
+ (('note:mrubyの組み込み'))
602
+
603
+ = まとめ
604
+
605
+ * Rubyの組み込み
606
+ * (('wait'))ガッツリ連携するつもりで設計\n
607
+ (('note:拡張ライブラリーで十分じゃないかよく検討すること'))
608
+ * mrubyの組み込み
609
+ * (('wait'))アプリの大事な事を忘れないで設計
610
+ * (('wait'))OSS Gateもよろしく