PHPにおけるI/O多重化とyield

15,976 views

Published on

PHPカンファレンス2014にて発表した内容です。
https://joind.in/talk/view/12038

Published in: Software
0 Comments
47 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
15,976
On SlideShare
0
From Embeds
0
Number of Embeds
4,962
Actions
Shares
0
Downloads
45
Comments
0
Likes
47
Embeds 0
No embeds

No notes for slide

PHPにおけるI/O多重化とyield

  1. 1. PHPにおける I/O多重化と yield PHP Conference 2014 ヤフー株式会社 中野 拓 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 1
  2. 2. 自己紹介 中野 拓 http://developer.yahoo.co.jp/ のフロントエンドなど担当 PHP歴7年目 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 2
  3. 3. 目次 3 1. マイクロサービスとI/O遅い問題 2. 真のI/O多重化 3. PHPはnode.jsになれるか 4. yieldのススメ 5. まとめと今後の展望 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
  4. 4. 第1部 マイクロサービスとI/O遅い問題 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 4
  5. 5. 出典: http://martinfowler.com/articles/microservices.html Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 5
  6. 6. *aaS/WebAPIと組み合わせて アプリケーションを作る 6 MBaaS DBaaS Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
  7. 7. でも… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 7
  8. 8. 一般的にI/Oは遅い L1 cache reference 0.5 ns L2 cache reference 5 ns Main Memory reference 100 ns Send 1K bytes over 1Gbps network 10,000 ns 0.01 ms Read 4K randomly from SSD 150,000 ns 0.15 ms Round trip within same datacenter 500,000 ns 0.5 ms Read 1 MB sequentially from SSD 1,000,000 ns 1 ms Disk seek 10,000,000 ns 10 ms Read 1 MB sequentially from disk 20,000,000 ns 20 ms Send Packet CA-­‐Netherlands-­‐CA 150,000,000 ns 150 ms 出典:Latency Numbers Every Programmer Should Know (抜粋) https://gist.github.com/jboner/2841832 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 8
  9. 9. ネットワーク I/O遅い サービス 分割で I/O増加 ジレンマ Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 9
  10. 10. I/Oが遅いのは仕方ないとして、 もっと効率化できないか? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 10
  11. 11. 通信1回分 前準備 待ち 後処理 待ってるだけ= 暇 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 11
  12. 12. 前準備 待ち 後処理 今のうちに他の仕事 をしておこう… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 12
  13. 13. I/O多重化! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 13
  14. 14. I/O多重化を実現するには? • 非同期APIを使う (Reactorパターン) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 14
  15. 15. マルチスレッドとか マルチプロセスは? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 15
  16. 16. • スレッド … PHPではExperimental • プロセス … pcntlが使えるが、 Apacheモジュール版PHPは非対応 • 非同期APIは問題なく使える Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 16
  17. 17. PHPで使える非同期API • curl_multi • mysqlnd • postgresql • stream_select, libevent, libev, libuv などなど Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 17
  18. 18. 第1部まとめ • ネットワークI/Oは遅いので、多重化する とよい • PHPなら非同期APIを使うのがお手軽 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 18
  19. 19. 第2部 真のI/O多重化 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 19
  20. 20. curl_multiのサンプル • 検索するといくつかヒットする Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 20
  21. 21. Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 21
  22. 22. 通信1回分 前準備 待ち 後処理 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 22
  23. 23. curl_multiのサンプルだと こんな感じ 23 準備準備準備待ち後処理理後処理理後処理理 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止
  24. 24. ん? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 24
  25. 25. 1スレッドI/O多重化のルール • 一度に出来る仕事は常に1つだけ • 待ち時間は別の仕事ができる ⿊黒は重ねられ ない Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 25
  26. 26. どうせなら 真の並行 にしたい…よね? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 26
  27. 27. ここで curl_multiの 例を ごらん ください PHP - curl_multiでHTTP並行リクエストを行うサンプル - Qiita http://qiita.com/Hiraku/items/1c67b51040246efb4254 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 27
  28. 28. お、おう… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 28
  29. 29. 第2部のまとめ • curl_multiで真の多重化を行うのは、 可能だけど、書くのが面倒 • 多重ループの山!! • 書きやすく抽象化したいところ →どうやって? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 29
  30. 30. ところで、 真のI/O多重化を いとも簡潔に 実現している言語があります。 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 30
  31. 31. http://nodejs.org Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 31
  32. 32. 第3部 PHPはnode.jsになれるか Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 32
  33. 33. node.js • 1スレッド1プロセスだが、同時に複数の リクエストをさばける • あらゆるI/Oが徹底的に非同期化・多重化 されている Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 33
  34. 34. node.jsの非同期API抽象化方針 • 多重化するところ(イベントループ)は コアで処理 – 開発者は素直に処理を書くだけ • Callbackスタイル – クロージャ多用 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 34
  35. 35. echoサーバー var net = require('net'); var server = net.createServer(function(socket){ socket.write('Echo serverrn'); socket.pipe(socket); }); server.listen(1337, '127.0.0.1'); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 35
  36. 36. あとは、node.js自身が うまいこと重ねてくれる • たったこれだけのコードで 複数リクエストを同時にさばける Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 36
  37. 37. これはすごい! PHPでもnode.jsを パクればいいのでは? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 37
  38. 38. PHP版node.js あります Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 38
  39. 39. http://reactphp.org/ Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 39
  40. 40. https://github.com/amphp Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 40
  41. 41. reactphpの例 ?php require 'vendor/autoload.php'; $app = function ($request, $response) { $response-­‐writeHead(200, ['Content-­‐Type' = 'text/plain']); $response-­‐end(Hello Worldn); }; $loop = ReactEventLoopFactory::create(); $socket = new ReactSocketServer($loop); $http = new ReactHttpServer($socket, $loop); $http-­‐on('request', $app); echo Server running at http://127.0.0.1:1337n; $socket-­‐listen(1337); $loop-­‐run(); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 41
  42. 42. 実用になる? • いくつか課題がある • 個人的には、PHPにnode.js風の抽象化 は向いてないと思っています Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 42
  43. 43. しばらくdisが続きますが あくまで個人の見解です Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 43
  44. 44. 課題1 クロージャの構文 • PHPのクロージャ構文はかなり冗長 – function ~ use ~ return ~ – これを毎回書くのか… CoffeeScript x - x + offset JavaScript function(x) { return x + offset; } PHP function($x) use($offset){ return $x + $offset; } Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 44
  45. 45. 課題2 循環参照への耐性 • PHPのGCは参照カウンタ方式 +補助的に循環参照コレクタ • クロージャは本質的に循環参照を作りや すく、参照カウンタが機能しにくくなる Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 45
  46. 46. 課題3 既存の資産が使えない • Callbackスタイルは独特の書き方 – 例外禁止 – コールバック地獄はPromiseなどで整理 • 既存のライブラリは全て使えないと思っ たほうがよい。書き直し! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 46
  47. 47. reactphpは全部 1から作ろうとしている みたいですが… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 47
  48. 48. 皆さん、 そこまでして PHPを使いたいですか? 1から書き直せって言われたら別言語 使う人多そう。。 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 48
  49. 49. 第3部のまとめ • node.js風の非同期APIの抽象化は前例が ある • ただ、Callbackスタイルは個人的な意見 として微妙。。 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 49
  50. 50. 第4部 yieldのススメ Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 50
  51. 51. Callback以外の抽象化方法 • 継続(Continuation)に類する機能を使う – C#/VisualBasic/Hackのasync/await – node.jsのco、task.js Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 51
  52. 52. C#の同期メソッド private void Button_Click(object sender, RoutedEventArgs e) { this.button.IsEnabled = false; Thread.Sleep(3000); this.button.IsEnabled = true; } (出典) .NET開発における⾮非同期処理理の基礎と歴史 - @IT http://www.atmarkit.co.jp/fdotnet/chushin/masterasync_01/masterasync_01_01.html Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 52
  53. 53. C#の非同期メソッド private async void Button_Click(object sender, RoutedEventArgs e) { this.button.IsEnabled = false; await Task.Run(() = Thread.Sleep(3000)); this.button.IsEnabled = true; } (出典) .NET開発における⾮非同期処理理の基礎と歴史 - @IT http://www.atmarkit.co.jp/fdotnet/chushin/masterasync_01/masterasync_01_01.html Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 53
  54. 54. ここに同期コードがあるじゃろ? ( ^ω^) ⊃同期コード⊂ Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 54
  55. 55. これにasync/awaitキーワードを 合わせて… ( ^ω^) ≡⊃⊂≡ Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 55
  56. 56. ( ^ω^) ⊃非同期コード⊂ 出来上がりじゃ。 よしなにI/O多重化するぞい Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 56
  57. 57. まじで!? それPHPにも欲しい… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 57
  58. 58. async/awaitはないけど、 yieldがあるよ! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 58
  59. 59. yield(ジェネレータ) • PHP5.5から導入された構文 • 関数を一時停止・再開できる機能 • 言語によって呼び名が違う – ジェネレータ、軽量スレッド、ファイバー、 コルーチン Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 59
  60. 60. yieldで async/awaitみたいなやつ 実装してみました Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 60
  61. 61. hirak/co-httpclient $ composer require 'hirak/co-­‐httpclient:dev-­‐master' Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 61
  62. 62. 通常の関数 function getWebapi($url) { $req = new HttpClientRequest($url); $res = $req-­‐send(); if ($res-­‐getStatusCode() = 400) { throw new RuntimeException($url); } return json_decode($res-­‐getBody()); } Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 62
  63. 63. 非同期版の関数 function getWebapiAsync($url) { $req = new HttpClientRequest($url); $res = (yield $req); if ($res-­‐getStatusCode() = 400) { throw new RuntimeException($url); } yield json_decode($res-­‐getBody()); } Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 63
  64. 64. 起動 list($res1, $res2) = co( getWebapiAsync('http://example.com/a.json'), getWebapiAsync('http://example.com/b.json') ); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 64
  65. 65. I/O多重化への修正 1. 待つところにyieldを挟んでおく。 2. returnをyieldに置き換える。 3. co関数で起動 これだけ!! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 65
  66. 66. 真の並行 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 66
  67. 67. この一本を ジェネレータ 関数にしてお く Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 67
  68. 68. co( ) co関数に渡すと、なるべく重ねな がら実行してくれる Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 68
  69. 69. yield方式のメリット • 既存のPHPコードをあまり書き換えなく て良い – パラダイムを変えなくて良い • interfaceを全て通過する Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 69
  70. 70. yieldならば… • 既存WAFも非同期化できるかも? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 70
  71. 71. 第4部 ‒ 補遺 どうやって実現しているのか Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 71
  72. 72. yieldのおさらい • 関数の処理を一時停止・再開できる機能 ジェネレータの例例ジェネレータを実⾏行行するコード例例 function gen() { echo (yield 1); echo (yield 2); echo (yield 3); } $g = gen(); echo $g-current(); echo $g-send(4); echo $g-send(5); $g-send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 72
  73. 73. function gen() { echo (yield 1); echo (yield 2); echo (yield 3); } $g = gen(); echo $g-current(); echo $g-send(4); echo $g-send(5); $g-send(6); ← ここから起動 (ジェネレータの準備) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 73
  74. 74. function gen() { echo (yield 1); echo (yield 2); echo (yield 3); } $g = gen(); echo $g-current(); echo $g-send(4); echo $g-send(5); $g-send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 74
  75. 75. function gen() { echo (yield 1); echo (yield 2); echo (yield 3); } $g = gen(); echo $g-current(); echo $g-send(4); echo $g-send(5); $g-send(6); 実行開始! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 75
  76. 76. function gen() { echo (yield 1); echo (yield 2); echo (yield 3); } $g = gen(); echo $g-current(); echo $g-send(4); echo $g-send(5); $g-send(6); yieldが見つかったので… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 76
  77. 77. function gen() { echo (yield 1); echo (yield 2); echo (yield 3); } $g = gen(); echo 1; echo $g-send(4); echo $g-send(5); $g-send(6); (一時停止中) 1 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 77
  78. 78. function gen() { echo (yield 1); echo (yield 2); echo (yield 3); } $g = gen(); echo 1; echo $g-send(4); echo $g-send(5); $g-send(6); (一時停止中) 1 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 78
  79. 79. function gen() { echo (4); echo (yield 2); echo (yield 3); } $g = gen(); echo 1; echo $g-send(4); echo $g-send(5); $g-send(6); 14 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 79
  80. 80. function gen() { echo (4); echo (yield 2); echo (yield 3); } $g = gen(); echo 1; echo $g-send(4); echo $g-send(5); $g-send(6); 14 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 80
  81. 81. function gen() { echo (4); echo (yield 2); echo (yield 3); } $g = gen(); echo 1; echo 2; echo $g-send(5); $g-send(6); 142 (一時停止中) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 81
  82. 82. function gen() { echo (4); echo (yield 2); echo (yield 3); } $g = gen(); echo 1; echo 2; echo $g-send(5); $g-send(6); 142 (一時停止中) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 82
  83. 83. function gen() { echo (4); echo (5); echo (yield 3); } $g = gen(); echo 1; echo 2; echo $g-send(5); $g-send(6); 1425 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 83
  84. 84. function gen() { echo (4); echo (5); echo (yield 3); } $g = gen(); echo 1; echo 2; echo $g-send(5); $g-send(6); 1425 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 84
  85. 85. function gen() { echo (4); echo (5); echo (yield 3); } $g = gen(); echo 1; echo 2; echo 3; $g-send(6); 14253 (一時停止中) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 85
  86. 86. function gen() { echo (4); echo (5); echo (yield 3); } $g = gen(); echo 1; echo 2; echo 3; $g-send(6); 14253 (一時停止中) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 86
  87. 87. function gen() { echo (4); echo (5); echo (6); } $g = gen(); echo 1; echo 2; echo 3; $g-send(6); 142536 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 87
  88. 88. function gen() { echo (4); echo (5); echo (6); } $g = gen(); echo 1; echo 2; echo 3; null; 142536 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 88
  89. 89. co-httpclientの場合 co関数 gen gen gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 89
  90. 90. 1. 与えられたジェネレータを 順番に実行していく co関数 gen gen gen 実行 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 90
  91. 91. 1. 与えられたジェネレータを 順番に実行していく co関数 gen gen gen 実行 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 91
  92. 92. 2. yieldされたら… co関数 gen yieldRequest gen gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 92
  93. 93. 3. 非同期実行し始めて… co関数 gen yield gen gen ⾮非同期実⾏行行中 Request Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 93
  94. 94. 4. 待っている間に次の ジェネレータを実行 co関数 gen yield gen gen ⾮非同期実⾏行行中 Request Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 94
  95. 95. 5. やることがなくなったら 非同期実行を待って… co関数 gen yield gen gen ⾮非同期実⾏行行中(終わ るまで待つ) Request Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 95
  96. 96. 6. ジェネレータを再開! co関数 gen yieldRequest gen gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 96
  97. 97. つまり • yield = コンテキストスイッチ • co関数はyieldされる度に次に行う処理を 探して実行する • スレッドっぽい – 軽量スレッドと呼ばれる所以 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 97
  98. 98. その他の工夫 • 非同期関数内で別の非同期関数を呼ぶ – SplStackを使って対処 • 例外の伝搬 – Generator::throw()を使用する 非常に参考にしました↓ Cooperative multitasking using coroutines (in PHP!) http://nikic.github.io/2012/12/22/Cooperative-multitasking-using-coroutines-in-PHP.html Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 98
  99. 99. 関数内で別の関数を呼ぶ //通常の関数 function a() { return b() . c(); } //非同期の関数 function aAsync() { yield (yield bAsync()) . (yield cAsync()); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 99 }
  100. 100. こんな書き方もできる //非同期関数の配列 function aAsync() { $arr = (yield [bAsync(), cAsync()]); yield implode('', $arr); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 100 }
  101. 101. 第5部 まとめと今後の展望 10 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 1
  102. 102. まとめ • I/O多重化してマイクロサービスに備えよう • PHPにcallbackスタイルはつらい… • yieldでも抽象化できる – こっちの方が既存のPHPコードと互換性が高い • curl_multiに関して実装を書いてみた Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 102
  103. 103. 今後の展望 • curl_multi以外にmysqlndや postgresqlも重ねたい • 例外のスタックトレースサポート • コードのブラッシュアップ Pull Request歓迎! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 103
  104. 104. hirak/co-httpclient $ composer require 'hirak/co-­‐httpclient:dev-­‐master' 104 再掲 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

×