Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
ハチャメチャに叩く
Search
uzulla
July 13, 2018
Programming
1
1.8k
ハチャメチャに叩く
【非公式】PHPカンファレンス 2018 関西 前夜祭
https://dbstudychugoku.connpass.com/event/92337/
uzulla
July 13, 2018
Tweet
Share
More Decks by uzulla
See All by uzulla
ALL CODE BASE ARE BELONG TO STUDY
uzulla
30
7.4k
バイブスあるコーディングで ~PHP~ 便利ツールをつくるプラクティス
uzulla
1
500
PHPer's Guide to Daemon Crafting Taming and Summoning
uzulla
2
1.9k
似たもの同士のPerlとPHP
uzulla
1
270
More Context, Better Code. 既存コードやOAS等をコンテキストとしてLLMに与える事で、よりよいコード生成を行う話
uzulla
1
200
あなたのアプリ、ログはでてますか?あるいはログをだしてますか? (Funabashi.dev用 軽量版)
uzulla
3
300
セッションのトークセッション / Traps for PHP session features in growing web apps
uzulla
2
220
Crafting a Own PHP - ウキウキ手作りミニマリストPHP
uzulla
5
2.8k
例外を投げるのをやめてみないか? あるいは受け入れてみないか? - How to use exceptions other than throwing
uzulla
6
1.3k
Other Decks in Programming
See All in Programming
副作用をどこに置くか問題:オブジェクト指向で整理する設計判断ツリー
koxya
1
200
React 19でつくる「気持ちいいUI」- 楽観的UIのすすめ
himorishige
11
3.1k
JETLS.jl ─ A New Language Server for Julia
abap34
2
470
GISエンジニアから見たLINKSデータ
nokonoko1203
0
190
Spinner 軸ズレ現象を調べたらレンダリング深淵に飲まれた #レバテックMeetup
bengo4com
1
210
Navigating Dependency Injection with Metro
l2hyunwoo
1
200
Navigation 3: 적응형 UI를 위한 앱 탐색
fornewid
1
520
CSC307 Lecture 01
javiergs
PRO
0
650
AIの誤りが許されない業務システムにおいて“信頼されるAI” を目指す / building-trusted-ai-systems
yuya4
7
4.2k
Developing static sites with Ruby
okuramasafumi
1
340
Flutter On-device AI로 완성하는 오프라인 앱, 박제창 @DevFest INCHEON 2025
itsmedreamwalker
1
180
Basic Architectures
denyspoltorak
0
160
Featured
See All Featured
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
160
How to Think Like a Performance Engineer
csswizardry
28
2.4k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
43
Self-Hosted WebAssembly Runtime for Runtime-Neutral Checkpoint/Restore in Edge–Cloud Continuum
chikuwait
0
270
AI: The stuff that nobody shows you
jnunemaker
PRO
1
150
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
Git: the NoSQL Database
bkeepers
PRO
432
66k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
180
Music & Morning Musume
bryan
46
7k
Designing for Performance
lara
610
70k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.3k
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
7.9k
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