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

1.9K Views

October 11, 14

スライド概要

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

profile-image

2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

PHPにおける I/O多重化と yield PHP Conference 2014 ヤフー株式会社 中野 拓 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 1

2.

自己紹介 中野 拓 http://developer.yahoo.co.jp/ のフロントエンドなど担当 PHP歴7年目 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 2

3.

目次 1. マイクロサービスとI/O遅い問題 2. 真のI/O多重化 3. PHPはnode.jsになれるか 4. yieldのススメ 5. まとめと今後の展望 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 3

4.

第1部 マイクロサービスとI/O遅い問題 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 4

5.

出典: http://martinfowler.com/articles/microservices.html Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 5

6.

*aaS/WebAPIと組み合わせて アプリケーションを作る MBaaS DBaaS Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 6

7.

でも… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 7

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.

ネットワーク I/O遅い マ ン レ ジ サービス 分割で I/O増加 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 9

10.

I/Oが遅いのは仕方ないとして、 もっと効率化できないか? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 10

11.

通信1回分 前準備 待ち 後処理 待ってるだけ= 暇 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 11

12.

前準備 待ち 後処理 今のうちに他の仕事 をしておこう… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 12

13.

I/O多重化! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 13

14.

I/O多重化を実現するには? • 非同期APIを使う (Reactorパターン) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 14

15.

マルチスレッドとか マルチプロセスは? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 15

16.

• スレッド … PHPではExperimental • プロセス … pcntlが使えるが、 Apacheモジュール版PHPは非対応 • 非同期APIは問題なく使える Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 16

17.

PHPで使える非同期API • curl̲multi • mysqlnd • postgresql • stream̲select, libevent, libev, libuv などなど Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 17

18.

第1部まとめ • ネットワークI/Oは遅いので、多重化する とよい • PHPなら非同期APIを使うのがお手軽 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 18

19.

第2部 真のI/O多重化 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 19

20.

curl̲multiのサンプル • 検索するといくつかヒットする Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 20

21.

Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 21

22.

通信1回分 前準備 待ち 後処理 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 22

23.

curl̲multiのサンプルだと こんな感じ 準備 準備 準備 待ち 後処理理 後処理理 後処理理 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 23

24.

ん? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 24

25.

1スレッドI/O多重化のルール • 一度に出来る仕事は常に1つだけ • 待ち時間は別の仕事ができる ⿊黒は重ねられ ない Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 25

26.

どうせなら 真の並行 にしたい…よね? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 26

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.

お、おう… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 28

29.

第2部のまとめ • curl̲multiで真の多重化を行うのは、 可能だけど、書くのが面倒 • 多重ループの山!! • 書きやすく抽象化したいところ →どうやって? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 29

30.

ところで、 真のI/O多重化を いとも簡潔に 実現している言語があります。 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 30

31.

http://nodejs.org Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 31

32.

第3部 PHPはnode.jsになれるか Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 32

33.

node.js • 1スレッド1プロセスだが、同時に複数の リクエストをさばける • あらゆるI/Oが徹底的に非同期化・多重化 されている Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 33

34.

node.jsの非同期API抽象化方針 • 多重化するところ(イベントループ)は コアで処理 – 開発者は素直に処理を書くだけ • Callbackスタイル – クロージャ多用 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 34

35.

echoサーバー var  net  =  require('net');     var  server  =  net.createServer(function(socket){          socket.write('Echo  server\r\n');          socket.pipe(socket);   });     server.listen(1337,  '127.0.0.1'); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 35

36.

あとは、node.js自身が うまいこと重ねてくれる • たったこれだけのコードで 複数リクエストを同時にさばける Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 36

37.

これはすごい! PHPでもnode.jsを パクればいいのでは? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 37

38.

PHP版node.js あります Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 38

39.

http://reactphp.org/ Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 39

40.

https://github.com/amphp Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 40

41.
[beta]
reactphpの例
<?php
require	
  'vendor/autoload.php';	
  
	
  
$app	
  =	
  function	
  ($request,	
  $response)	
  {	
  
	
  	
  	
  	
  $response-­‐>writeHead(200,	
  ['Content-­‐Type'	
  =>	
  'text/plain']);	
  
	
  	
  	
  	
  $response-­‐>end("Hello	
  World\n");	
  
};	
  
	
  
$loop	
  =	
  React\EventLoop\Factory::create();	
  
$socket	
  =	
  new	
  React\Socket\Server($loop);	
  
$http	
  =	
  new	
  React\Http\Server($socket,	
  $loop);	
  
	
  
$http-­‐>on('request',	
  $app);	
  
echo	
  "Server	
  running	
  at	
  http://127.0.0.1:1337\n";	
  
	
  
$socket-­‐>listen(1337);	
  
$loop-­‐>run();
Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止

41

42.

実用になる? • いくつか課題がある • 個人的には、PHPにnode.js風の抽象化 は向いてないと思っています Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 42

43.

しばらくdisが続きますが あくまで個人の見解です Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 43

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.

課題2 循環参照への耐性 • PHPのGCは参照カウンタ方式 +補助的に循環参照コレクタ • クロージャは本質的に循環参照を作りや すく、参照カウンタが機能しにくくなる Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 45

46.

課題3 既存の資産が使えない • Callbackスタイルは独特の書き方 – 例外禁止 – コールバック地獄はPromiseなどで整理 • 既存のライブラリは全て使えないと思っ たほうがよい。書き直し! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 46

47.

reactphpは全部 1から作ろうとしている みたいですが… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 47

48.

皆さん、 そこまでして PHPを使いたいですか? 1から書き直せって言われたら別言語 使う人多そう。。 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 48

49.

第3部のまとめ • node.js風の非同期APIの抽象化は前例が ある • ただ、Callbackスタイルは個人的な意見 として微妙。。 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 49

50.

第4部 yieldのススメ Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 50

51.

Callback以外の抽象化方法 • 継続(Continuation)に類する機能を使う – C#/VisualBasic/Hackのasync/await – node.jsのco、task.js Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 51

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.
[beta]
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.

ここに同期コードがあるじゃろ? ( ^ω^) 同期コード Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 54

55.

これにasync/awaitキーワードを 合わせて… ( ^ω^) Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 55

56.

( ^ω^) 非同期コード 出来上がりじゃ。 よしなにI/O多重化するぞい Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 56

57.

まじで!? それPHPにも欲しい… Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 57

58.

async/awaitはないけど、 yieldがあるよ! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 58

59.

yield(ジェネレータ) • PHP5.5から導入された構文 • 関数を一時停止・再開できる機能 • 言語によって呼び名が違う – ジェネレータ、軽量スレッド、ファイバー、 コルーチン Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 59

60.

yieldで async/awaitみたいなやつ 実装してみました Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 60

61.

hirak/co-httpclient $  composer  require  'hirak/co-­‐httpclient:dev-­‐master' Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 61

62.

通常の関数 function  getWebapi($url)  {          $req  =  new  HttpClient\Request($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.

非同期版の関数 function  getWebapiAsync($url)  {          $req  =  new  HttpClient\Request($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.

起動 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.

I/O多重化への修正 1. 待つところにyieldを挟んでおく。 2. returnをyieldに置き換える。 3. co関数で起動 これだけ!! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 65

66.

真の並行 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 66

67.

この一本を ジェネレータ 関数にしてお く Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 67

68.

co( ) co関数に渡すと、なるべく重ねな がら実行してくれる Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 68

69.

yield方式のメリット • 既存のPHPコードをあまり書き換えなく て良い – パラダイムを変えなくて良い • interfaceを全て通過する Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 69

70.

yieldならば… • 既存WAFも非同期化できるかも? Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 70

71.

第4部 ‒ 補遺 どうやって実現しているのか Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 71

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.

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.

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.

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.

function  gen()  {   yieldが見つかったので…    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. 無断引用・転載禁止 76

77.

function  gen()  {      echo  (yield  1);  (一時停止中)    echo  (yield  2);      echo  (yield  3);   }     $g = gen(); echo 1; echo $g->send(4); echo $g->send(5); 1 $g->send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 77

78.

function  gen()  {      echo  (yield  1);  (一時停止中)    echo  (yield  2);      echo  (yield  3);   }     $g = gen(); echo 1; echo $g->send(4); echo $g->send(5); 1 $g->send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 78

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.

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.

function  gen()  {      echo  (4);      echo  (yield  2);  (一時停止中)    echo  (yield  3);   }     $g = gen(); echo 1; echo 2; echo $g->send(5); 142 $g->send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 81

82.

function  gen()  {      echo  (4);      echo  (yield  2);  (一時停止中)    echo  (yield  3);   }     $g = gen(); echo 1; echo 2; echo $g->send(5); 142 $g->send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 82

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.

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.

function  gen()  {      echo  (4);      echo  (5);      echo  (yield  3);  (一時停止中) }     $g = gen(); echo 1; echo 2; echo 3; 14253 $g->send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 85

86.

function  gen()  {      echo  (4);      echo  (5);      echo  (yield  3);  (一時停止中) }     $g = gen(); echo 1; echo 2; echo 3; 14253 $g->send(6); Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 86

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.

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.

co-httpclientの場合 gen gen co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 89

90.

1. 与えられたジェネレータを 順番に実行していく gen gen 実行 co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 90

91.

1. 与えられたジェネレータを 順番に実行していく gen 実行 gen co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 91

92.

2. yieldされたら… gen yield gen Request co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 92

93.

3. 非同期実行し始めて… gen yield gen ⾮非同期実⾏行行中 Request co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 93

94.

4. 待っている間に次の ジェネレータを実行 gen yield gen ⾮非同期実⾏行行中 Request co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 94

95.

5. やることがなくなったら 非同期実行を待って… gen yield gen ⾮非同期実⾏行行中(終わ るまで待つ) Request co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 95

96.

6. ジェネレータを再開! gen yield gen Request co関数 gen Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 96

97.

つまり • yield = コンテキストスイッチ • co関数はyieldされる度に次に行う処理を 探して実行する • スレッドっぽい – 軽量スレッドと呼ばれる所以 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 97

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.

関数内で別の関数を呼ぶ //通常の関数 function a() { return b() . c(); } //非同期の関数 function aAsync() { yield (yield bAsync()) . (yield cAsync()); }   Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 99

100.

こんな書き方もできる //非同期関数の配列 function aAsync() { $arr = (yield [bAsync(), cAsync()]); yield implode('', $arr); }   Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 100

101.

第5部 まとめと今後の展望 Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 10 1

102.

まとめ • I/O多重化してマイクロサービスに備えよう • PHPにcallbackスタイルはつらい… • yieldでも抽象化できる – こっちの方が既存のPHPコードと互換性が高い • curl̲multiに関して実装を書いてみた Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 102

103.

今後の展望 • curl̲multi以外にmysqlndや postgresqlも重ねたい • 例外のスタックトレースサポート • コードのブラッシュアップ Pull Request歓迎! Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 103

104.

再掲 hirak/co-httpclient $  composer  require  'hirak/co-­‐httpclient:dev-­‐master' Copyright (C) 2014 Yahoo Japan Corporation. All Rights Reserved. 無断引用・転載禁止 104