Lock in $30 Savings on PRO—Offer Ends Soon! ⏳
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ハチャメチャに叩く
Search
uzulla
July 13, 2018
Programming
1
1.6k
ハチャメチャに叩く
【非公式】PHPカンファレンス 2018 関西 前夜祭
https://dbstudychugoku.connpass.com/event/92337/
uzulla
July 13, 2018
Tweet
Share
More Decks by uzulla
See All by uzulla
似たもの同士のPerlとPHP
uzulla
1
110
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
110
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
170
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
120
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
2k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
4
910
PHPerが ISUCONでやるべき事
uzulla
1
980
開発生産性は上がらない - N Ways to Reduce Development Productivity
uzulla
1
240
test is not a job
uzulla
1
500
Other Decks in Programming
See All in Programming
SymfonyCon Vienna 2025: Twig, still relevant in 2025?
fabpot
2
580
あれやってみてー駆動から成長を加速させる / areyattemite-driven
nashiusagi
1
140
TypeScript でバックもやるって実際どう? 実運用で困ったこと3選
yuichiro_serita
17
7.5k
.NET Conf 2024の振り返り
tomokusaba
0
190
我々のデザインシステムは Chakra v3 にアップデートします
shunya078
2
2.8k
カンファレンスの「アレ」Webでなんとかしませんか? / Conference “thing” Why don't you do something about it on the Web?
dero1to
2
160
Welcome JSConf.jp 2024
yosuke_furukawa
PRO
0
3k
Cognitoが大型アップデート!Managed Loginとパスワードレスログインを実際に使ってみた@しむそくRadio Special Day1
tmhirai
3
230
Vue.js_好きに捧ぐ Nuxt Hub で簡単に始めるCloudflare
xiombatsg
1
120
PaaSとSaaSの境目で信頼性と開発速度を両立する 〜TROCCO®︎のこれまでとこれから〜
gtnao
6
6.7k
HTTP compression in PHP and Symfony apps
dunglas
2
1.3k
今からはじめるAndroidアプリ開発 2024 / DevFest 2024
star_zero
0
730
Featured
See All Featured
GraphQLの誤解/rethinking-graphql
sonatard
67
10k
Thoughts on Productivity
jonyablonski
67
4.3k
Code Reviewing Like a Champion
maltzj
520
39k
Building Your Own Lightsaber
phodgson
103
6.1k
Art, The Web, and Tiny UX
lynnandtonic
297
20k
A Tale of Four Properties
chriscoyier
157
23k
Rails Girls Zürich Keynote
gr2m
94
13k
Automating Front-end Workflow
addyosmani
1366
200k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
232
17k
The Illustrated Children's Guide to Kubernetes
chrisshort
48
48k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
29
2k
Optimising Largest Contentful Paint
csswizardry
33
3k
Transcript
ϋνϟϝνϟʹhttp(s) ͰԥΓ͍ͨ
@uzulla
ઌSwooleͷΛ͠·͕ͨ͠ • https:/ /speakerdeck.com/uzulla/zui-jin- meruhuomukaitenaimeruhuomaniyoru-tiyotutodakebian-watuta- ying-phpfalsemeruhuomu-falseohua-fu-ti-zui-jin- swoolegatafalsesiidesu • ʢ͍…ʣ •
ʢuzulla swoole speakerdeckͰݕࡧʣ • ඇಉظɺcoroutineͷ͕͋·ΓͰ͖ͳ͔ͬͨͷͰ • ͦͷؔ࿈
ਓϋνϟϝνϟʹʢAPIͱ͔Λʣୟ͖͍ͨ • PHPͰͲΜͲΜୟ͖͍ͨ • Ϋϩʔϧ͍ͨͨ͠Ί • ྲྀߦͷϚΠΫϩφϯτΧͰࢁAPIΛୟ͘ඞཁ • շײΛಘΔͨΊ
• ͔͠͠PHPʮ͍ʯ(Β͍͠) !
• Կ͕͍͔ʁ! • httpʮऔಘ͢Δͪ࣌ؒʯ͕ࢧత • ྻͷಉظॲཧͰͦͷؒͳʹͰ͖ͳ͍ʂ " • ଞͷݴޠͰ؆୯ʹʢʁʣϚϧνεϨουʹͨ͠Γ͢Δʢཁ ग़య#ʣ
• ͔͠͠PHPϚϧνεϨουɺϚϧνϓϩηεΉ͔͍ͣ͠ ʢཁग़య#ʣ
Ͳ͏͢Δ͔ʁ • ඇಉظͩʂ • PHPͷඇಉظ݁ߏྺ࢙͕͋Δ(ओ؍) • ʢඇಉظI/OɺϊϯϒϩοΩϯάI/OɺଟॏԽI/Oͱ͔৭ʑ͋Δ ͕ɺ͜͜ͰҰॹͨ͘ʹඇಉظͱ͓͖ͯ͠·͢ʣ
ʮඇಉظʯͱʁ • I/OॲཧதʹϘʔͬͱͤͣɺଞͷ͜ͱΛΕΔ • ฒྻॲཧͰͳ͍ɺʢਅͷʣϚϧνεϨουͰͳ͍ • ͳΜΒ͔c֦ுΛೖΕͳ͍ͱCPUෛՙ͕ߴ͍ • ex: ev,uv,event,swoole
• ૉखͰ৮ΔͷେมͳͷͰϑϨʔϜϫʔΫ͕ॏཁ • ex: reactPHP,swoole,amp
None
None
None
None
None
༨ஊ curl_multi Ͱ͍͍ͷͰʁ • ࠷ॳʹʮNݸऔಘʯΈ͍ͨʹͳΔͷͰɺ̍ͭऴΘΓ࣍ୈҰͭى ಈͱ͔Ͱ͖ͳ͍ • ༻్ʹΑΔ͕ɺྫ͑ΫϩʔϥͰඞཁ • selectͷѻ͍͍͠…
• ʢͦͦcurl_* ࣗମ͕͍͠ʣ • ʢͲ͜ʹͰೖ͍ͬͯΔʢʁʣͷ࠷ߴʣ
ʮͱ͍͏͜ͱͰswooleͰඇಉظͩʂʯ • ຺བྷলུ͠·͢ɻ • ʮͳͥPHPͳͷ͔ɺదࡐదॴ͕ඞཁͰʁʁʯ • ʮࠓPHPҎ֎ͷ͔ͯͨ͠͠ͳ͍Ͱ͠ΐ…ʯ
swooleʹ͓͚Δهड़ํࣜ • callbackํࣜ • coroutineํࣜ
• callbackํࣜ • ΠϕϯτۦಈΒ͍͠ॻ͖ํ • JSͬΆ͍ • ຊདྷ͕ͪ͜ΒͳͷͰɺݫີʹௐ͍͢͠ • ωετஅ͕૿͑ΔͷͰগʑಡΈͮΒ͍
• coroutineํࣜ • ී௨ͷίʔυͬΆ͍ɺಡΈ͍͢ɺָ • (PHPͷ) δΣωϨʔλͬΆ͍ • ͪΐͬͱͨ͠ແବ͕Ͱ͖͍͢ •
৭ʑӅṭ͞Ε͍ͯΔͷͰɺٯʹ࣮ߦͮ͠Β͍͜ͱ • ࠓճͪ͜Β
• swoole࠷ۙcoroutineํࣜਪ͠ • swoolego()Λ͔ͭ͏ͱɺઐ༻ڥʢΠϕϯτϧʔϓͳͲʣ֎Ͱ ίϧʔνϯΛಈ͔ͤΔ • ʢͷͰָɻׂ͕͜͜ͱॏཁͳͷ͕ͩɺൺֱʹͳΔ͠આ໌͕ ͘ͳΔͷͰলུʣ
coroutineͷྑ͍ͱ͜Ζ • ;ͭʔͷίʔυͰɺAPIDBΞΫηεΛ͍͔ͭ͘ॱ൪ʹߦ͏ • coroutineී௨(ྻ)ʹॻ͚Δ • callbackํࣜωετ(ؔͰׂ)͠ͳ͚ΕͳΒͳ͍ • PromiseΛ͔ͭ͑ฏୱʹͰ͖Δ͕ɺείʔϓͷׂ͞Ε Δ
ͱ͍͏͜ͱͰαϯϓϧίʔυ • coroutineํࣜ • ʮwhileͰΔͷɺͲ͏ͳͷʁʯ ʮsleepΛௐ͢Ε࣮༻Ͱ͠ΐ…ʢͲ͏͔ͳʁʣʯ
• ͓ࢼ͢͠Δਓͪ͜Β͔ΒͲ͏ͧ • https:/ /github.com/uzulla/sample-co-get
<?php // Ұൠతͳྻऔಘίʔυ const MAX_REQ = 10; // نఆॲཧ $req_num
= 0; while (1) { echo "."; // نఆॲཧΛ͑ͨͷͰऴྃ if ($req_num >= MAX_REQ) { break; } // औಘ $req_num++; $_ = file_get_contents("http://example.jp"); }
• 1req2ඵ͔͔ΔAPIΛ10ճऔಘͩͱ… real 0m20.199s user 0m0.089s sys 0m0.067s
<?php // coroutineͰ͔͍ͯΈΔ go(function () { $now_worker_num = 0; $req_num
= 0; while (1) { echo "."; co::sleep(0.001); // εέδϡʔϥͷͨΊʹ // نఆॲཧूΛ͑ͨͷͰऴྃ if ($req_num >= MAX_REQ) { break; } // ىಈதͷίϧʔνϯ͕نఆʹୡ͍ͯ͠ͳ͚ΕՃىಈɺ // ʢنఆϫʔΧʔͳΒىಈͤͣɺϧʔϓઌ಄ʣ if ($now_worker_num >= MAX_WORKER_NUM) { continue; }
// while (1) { // ... // go()ͷΫϩʔδϟ͕ίϧʔνϯͱͯ͠εέδϡʔϥʹొ go(function ()
use (&$now_worker_num, &$req_num) { $req_num++; $now_worker_num++; $http = new \Swoole\Coroutine\Http\Client( "http://example.jp", 80); $http->get('/'); $_ = $http->body; $now_worker_num--; }); // ্هྃΛͨͣʹൈ͚Δ } });
real 0m4.187s user 0m0.267s sys 0m0.523s
• 1req2ඵ͔͔ΔAPIΛ10ճऔಘ͢Δͷʹ • ʢಉظʣ20ඵ->ʢඇಉظʣ4ඵ • ಉ࣌5ଓͩͱ̎ճ • ಉ࣌10ʹͳΒҰׅͰऴΘΔͷͰ̎ඵʹ • ʢ…ͳΔ͜ͱ͋Δʣ
coroutineཧղצॴ • go()ͰίϧʔνϯΛ࡞ͯ͠ʮޙͰ࣮ߦϦετʯʹՃ͠ʢεέ δϡʔϧ͞ΕΔʣɺޙͰ࣮ߦ͢Δ • ઐ༻ʹ࡞ΒΕͨؔҎ֎ඇಉظʹͳΒͳ͍
εέδϡʔϧ…ʁ • ֓೦ਤͰͬ͘͟Γઆ໌͍ͨ͠
None
None
None
None
None
None
None
• ʮεέδϡʔϧͬͯΫϩʔδϟΛฒସ͍͑ͯΔ͚ͩͳͷͰ ʁʯʮ͜͜Ͱ͋Δҙຯਖ਼ղͰ͢ʯ • (ࠓճset/getDeferͷ͠·ͤΜ) • ʢͪΌΜͱཧղ͢ΔͨΊʹίʔυΛಡΉͳΒɺreactPHPͳͲͷ ίʔυൺֱతಡΈ͍͢ʢSwooleCͳͷͰ…ʣʣ
• Ͳ͔͜ΒͰࣗ༝ʹεΠον͞ΕΔ༁Ͱͳ͍ • ओʹIOsleepͳͲɺͯ͠ҙຯ͕͋ΔॴͰ͞ΕΔ • ͦ͏͍͏;͏ʹSwoole͕औΓ͍ͬͯΔ
• JSΈ͍ͨʹؔ୯ҐͰࣗಈతʹΓସ͑͞Εͳ͍ͷͰҙ • ʮͳΜ͔ίϧʔνϯ͕ಈ͔ΜʂແݶϧʔϓʂϩοΫʂʯͱ͍ ͏࣌େମ͜Ε • ׳ΕΔ·Ͱࢥͬͨ௨Γͷ࣮ߦλΠϛϯάʢεέδϡʔϦϯ άʣʹͳΒͳ͍͜ͱ͋Δ • ඞཁͳΒɺखಈͰco::sleepͳͲΛೖΕͨΓ͢Δ
• ׳ΕΔ·ͰʮͳΜͰಈ͔ͳ͍Μͩ…ʯͱࢥ͏͜ͱ ->׳ΕΑ͏ʂ
·ͱΊ • ʮඇಉظ͋Μ·Γා͘ͳ͍ʯ • γϯϓϧʹॻ͖͘͢ಡΈ͍͢ͷ͕ʢSwooleͷʣ Coroutineʢओ؍ʣ • ͲΜͲΜAPIͳͲΛୟ͍ͯճΓ·͠ΐ͏ʂ
ຊͷ(?)·ͱΊ • file_get_contentsͰेͳΒɺͦ͏͠·͠ΐ͏ • ʮfile_get_contentsͰ͕ͨΓͳ͍༻్ͱ…͏͝͝…ʯ • ʮඇಉظͰ͏·͘ΕඵؒXXXXճୟ͘͜ͱເͰͳ ͍ʂʯ • →
ࣄ݅ʹͳΔ • ʮඇಉظͱ͔ɺ୭͕ϝϯς͢ΔΜͩ…ʯ • ʢ ચ ҭ͍ͯ͜͠͏ʣ
ࠓ͞ͳ͔࣮ͬͨࡍʹϋνϟϝνϟʹୟͨ͘ Ίʹॏཁͳॴ • DNSΩϟογϡɺkeep-aliveɺλΠϜΞτ&ϦτϥΠɺಈతε ϩοτϦϯάɺchanͳͲͰͷσʔλड͚͠ɺDefer • ʮຊʹඇಉظ͕ඞཁͳॴͱͲ͔͜ʁʯ • ॏ͍݁Ռॲཧ͕ඞཁͳΒϚϧνίΞ͕׆͔ͤΔͷͰϚϧνϓ ϩηεͷ΄͏͕ྑ͍
• ʮϚϧνϓϩηεʴඇಉظͩʂʯʮγϯϓϧͱ…ʯ
go()͝ਗ਼ௌ͍͖ͨͩ͋Γ͕ͱ͏͍͟͝ ·ͨ͠ɻ
• ͕࣌ؒ༨ΕҎԼ
coroutine͕ಡΈ͍͢ɺͱʁ • ʢҎԼ࣮ࡍʹಈ͔͍ͯ͠ΔίʔυͰͳ͍Ͱ͕͢ʣ
go(function () { $http = new Co\Http\Client("http://example.jp", 80); $http->get('/api.json'); $data
= json_decode($http->body); $id = $data[0]['id']; $http->get('/api.json?id='.$id); $data = json_decode($http->body); $child_id = $data[0]['child_id']; $http->get('/api.json?child_id='.$child_id); $data = json_decode($http->body); echo $data['title']; //-> });
$client = new Swoole\Http2\Client("example.jp", 80); $client->get("/", function ($o) use($client) {
$data = json_decode($o->body); $id = $data[0]['id']; $client->get("/api.json?id=".$id, function ($o) use($client) { $data = json_decode($o->body); $child_id = $data[0]['child_id']; $client->get("/api.json?child_id=".$id, function ($o) use($client) { $data = json_decode($o->body); echo $data['title']; //---------> } } });
3ճϦΫΤετΛͳ͛Δͱ… # coro //-> (1Πϯσϯτ # cb //---------> (3Πϯσϯτ
• ී௨ɺ͍͔ͭ͘ͷAPIDBΞΫηεΛॱ൪ʹߦ͏ • coroutineී௨(ྻ)ʹॻ͚Δ • ίʔϧόοΫํࣜωετ(ؔͰׂ)͠ͳ͚ΕͳΒͳ͍ • PromiseΛ͔ͭ͑ฏୱʹͰ͖Δ͕ɺείʔϓͷׂ͞Ε Δ
see also • https:/ /wiki.swoole.com/wiki/page/p-coroutinehttpclient.html • https:/ /github.com/swoole/swoole-src/tree/master/examples/ coroutine •
https:/ /wiki.swoole.com/wiki/page/752.html • https:/ /wiki.swoole.com/wiki/page/784.html • https:/ /github.com/eaglewu/swoole-ide-helper • https:/ /www.swoole.com/ • https:/ /www.swoole.co.uk/docs/modules/swoole-async-http-client