concurrent php in the etsy api

86
Concurrent PHP in the Etsy API Matthew Graham @lapsu @EtsyAPI Lead #phpday 2014 April

Upload: matt-graham

Post on 27-May-2015

917 views

Category:

Software


0 download

DESCRIPTION

How we at Etsy are adding concurrent data access to our PHP API. From PHP Day 2014

TRANSCRIPT

Page 1: Concurrent PHP in the Etsy API

Concurrent PHPin the Etsy API

Matthew Graham@lapsu

@EtsyAPI Lead#phpday2014 April

Page 2: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

Page 3: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

$1.3 BillionThings That Matter

Page 4: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

Page 5: Concurrent PHP in the Etsy API

@lapsu

Etsy's PHP

www api adminqueues cron

@EtsyAPI

Page 6: Concurrent PHP in the Etsy API

@lapsu

~200 engineers

30+ deploys / day

@EtsyAPI

Page 7: Concurrent PHP in the Etsy API

Also, Rasmus

@lapsu@EtsyAPI

Page 8: Concurrent PHP in the Etsy API

Spoilers

@lapsu

Mobile Clients Are Special

1 Thread != No Concurrency

@EtsyAPI

Page 9: Concurrent PHP in the Etsy API

@lapsu

<motivation>

@EtsyAPI

Page 10: Concurrent PHP in the Etsy API

Premise:

@lapsu

The Future is Mobile

@EtsyAPI

Page 11: Concurrent PHP in the Etsy API

@lapsu

Past The Future is Mobile

November 2013

@EtsyAPI

Page 12: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

Page 13: Concurrent PHP in the Etsy API

@EtsyAPI

Mobile Networks Suck

@lapsu

<

Page 14: Concurrent PHP in the Etsy API

@EtsyAPI

Not Mobile

@lapsu

www.etsy.com/shop/AVintageWanderer

Page 15: Concurrent PHP in the Etsy API

@EtsyAPI

Network Performance

@lapsu

3G < 4G

Page 16: Concurrent PHP in the Etsy API

@EtsyAPI

Network Coverage

@lapsu

3G > 4G

Page 17: Concurrent PHP in the Etsy API

@EtsyAPI

Mobile Requests

@lapsu

More != Better

Page 18: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

Page 19: Concurrent PHP in the Etsy API

@lapsu

1000ms Time To Glass

@EtsyAPI

Page 20: Concurrent PHP in the Etsy API

@lapsu

1000ms- 900ms

-------------100ms

Network/Client------------------------ Server

@EtsyAPI

Page 21: Concurrent PHP in the Etsy API

@lapsu

100ms = Bespoke + Concurrent

@EtsyAPI

Page 22: Concurrent PHP in the Etsy API

@lapsu

Single Threads

@EtsyAPI

Page 23: Concurrent PHP in the Etsy API

Concurrency

@lapsu@EtsyAPI

Main “Thread”

Child “Thread” Child “Thread”

Page 24: Concurrent PHP in the Etsy API

@lapsu

</motivation><interface>

@EtsyAPI

Page 25: Concurrent PHP in the Etsy API

Paul goes to Netflix

@lapsu@EtsyAPI

Page 26: Concurrent PHP in the Etsy API

1 View : 1 Bespoke

@lapsu@EtsyAPI

ClientView

Bespoke

View View

Bespoke BespokeAPI

Page 27: Concurrent PHP in the Etsy API

Multiple Clients

@lapsu@EtsyAPI

ClientsView

Bespoke

View View

Bespoke BespokeAPI

Page 28: Concurrent PHP in the Etsy API

Bespoke : Components

@lapsu@EtsyAPI

Bespoke Bespoke BespokeAPI

Item User Shop Favs Tx

Page 29: Concurrent PHP in the Etsy API

Components as REST

@lapsu@EtsyAPI

Bespoke BespokeAPI

Item User Shop Favs Tx

Page 30: Concurrent PHP in the Etsy API

@lapsu

?includes=User

@EtsyAPI

Page 31: Concurrent PHP in the Etsy API

Android User View

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id);

Curl_Orchestrator::run( [$shop,$favs,$items]); return [$favs,$items];}

@EtsyAPI

Page 32: Concurrent PHP in the Etsy API

Concurrent Client

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id);

Curl_Orchestrator::run( [$shop,$favs,$items]); return [$favs,$items];}

@EtsyAPI

Page 33: Concurrent PHP in the Etsy API

Making Requests

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id);

Curl_Orchestrator::run( [$shop,$favs,$items]); return [$favs,$items];}

@EtsyAPI

Page 34: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

shop

favs

t0 t1

Page 35: Concurrent PHP in the Etsy API

Inputs

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id);

Curl_Orchestrator::run( [$shop,$favs,$items]); return [$favs,$items];}

@EtsyAPI

Page 36: Concurrent PHP in the Etsy API

Future Parameters

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id);

Curl_Orchestrator::run( [$shop,$favs,$items]); return [$favs,$items];}

@EtsyAPI

Page 37: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

shop

favs

items

t0 t1 t2 t3 t4

Page 38: Concurrent PHP in the Etsy API

~6 Lines

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id);

Curl_Orchestrator::run( [$shop,$favs,$items]); return [$favs,$items];}

@EtsyAPI

Page 39: Concurrent PHP in the Etsy API

@lapsu

</interface><performance>

@EtsyAPI

Page 40: Concurrent PHP in the Etsy API

@lapsu

Web Pages Are Clients Too

@EtsyAPI

Page 41: Concurrent PHP in the Etsy API

Web First

@lapsu@EtsyAPI

Page 42: Concurrent PHP in the Etsy API

API First

@lapsu@EtsyAPI

Page 43: Concurrent PHP in the Etsy API

Android User View

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id);

Curl_Orchestrator::run( [$shop,$favs,$items]); return [$favs,$items];}

@EtsyAPI

Page 44: Concurrent PHP in the Etsy API

Desktop Web User View

@lapsu

function handle($cli, $inp) { $shop = $cli->shop($inp->user_id); $favs = $cli->favs($inp->user_id); $items = $cli->items($shop->shop_id); $teams = $cli->teams($inp->user_id);

Curl_Orchestrator::run( [$shop,$favs,$items,$teams]); return [$favs,$items,$teams];}

@EtsyAPI

Page 45: Concurrent PHP in the Etsy API

@lapsu

Activity Feed

@EtsyAPI

Page 46: Concurrent PHP in the Etsy API

@lapsu

Activity FeedPage

@EtsyAPI

HomePage

Page 47: Concurrent PHP in the Etsy API

30s of HTTP Time

@lapsu@EtsyAPI

Page 48: Concurrent PHP in the Etsy API

30s of HTTP Time

@lapsu

880ms Real Time

@EtsyAPI

Page 49: Concurrent PHP in the Etsy API

Components

@lapsu@EtsyAPI

Bespoke Bespoke Bespoke

API

Item User Shop Favs Tx

Page 50: Concurrent PHP in the Etsy API

Components Cache

@lapsu@EtsyAPI

Bespoke Bespoke Bespoke

CacheAPI

Item User Shop Favs Tx

Page 51: Concurrent PHP in the Etsy API

Local Call

@lapsu@EtsyAPI

Me

Page 52: Concurrent PHP in the Etsy API

Long Distance Call

@lapsu@EtsyAPI

AtlanticOcean User

Page 53: Concurrent PHP in the Etsy API

Long Distance Call

@lapsu@EtsyAPI

AtlanticOcean

API

Templates

User

Page 54: Concurrent PHP in the Etsy API

@lapsu

</performance><internals>

@EtsyAPI

Page 55: Concurrent PHP in the Etsy API

@lapsu

curl_multi_*

@EtsyAPI

Page 56: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

curl?

Page 57: Concurrent PHP in the Etsy API

General Sequence

@lapsu@EtsyAPI

curl_multi_init();curl_multi_add();curl_multi_exec();

while (!$done) { curl_multi_select(); curl_multi_exec(); curl_multi_info_read();}

Page 58: Concurrent PHP in the Etsy API

curl_multi_init

@lapsu@EtsyAPI

$mh = curl_multi_init();

Page 59: Concurrent PHP in the Etsy API

curl_multi_add_handle

@lapsu@EtsyAPI

$mh = curl_multi_init();$ch = curl_init($url);curl_setopt_array($ch, $options);curl_multi_add_handle($mh, $ch);

Page 60: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

multi handle

handle handle handle

Page 61: Concurrent PHP in the Etsy API

curl_multi_exec

@lapsu@EtsyAPI

do { $code = curl_multi_exec($mh, $r);} while ($code == CURLM_CALL_MULTI_PERFORM);

Page 62: Concurrent PHP in the Etsy API

curl_multi_select

@lapsu@EtsyAPI

$cnt = curl_multi_select($mh, $tmout);

Page 63: Concurrent PHP in the Etsy API

curl_multi_info_read

@lapsu@EtsyAPI

$info = curl_multi_info_read($mh);$ch = $info['handle'];$content = curl_multi_getcontent($ch);

Page 64: Concurrent PHP in the Etsy API

@lapsu@EtsyAPI

Page 65: Concurrent PHP in the Etsy API

localhost: Expected

@lapsu@EtsyAPI

R1

R2

R3

t0

Page 66: Concurrent PHP in the Etsy API

Network: Actual

@lapsu@EtsyAPI

R2

R3

t0 t1

R1

Page 67: Concurrent PHP in the Etsy API

curl Protocols

@lapsu@EtsyAPI

HTTP LDAP

Gopher POP3 IMAP

TELNET TFTP

Page 68: Concurrent PHP in the Etsy API

curl_get_multi_handle_state

@lapsu@EtsyAPI

$state = CURLM_STATE_FIRST;curl_multi_get_handle_state( $mh, $ch, $state);$sent = $state > CURLM_STATE_FIRST && $state < CURLM_STATE_PERFORM;

Page 69: Concurrent PHP in the Etsy API

Expected, Actual

@lapsu@EtsyAPI

R1

R2

R3

t0

Page 70: Concurrent PHP in the Etsy API

Revised Sequence

@lapsu@EtsyAPI

curl_multi_init();curl_multi_add();while (!$sent) { curl_multi_exec(); curl_multi_get_handle_state();}

while (!$done) { curl_multi_select(); curl_multi_exec(); curl_multi_info_read();}

Page 71: Concurrent PHP in the Etsy API

Still Headed Upstream

@lapsu@EtsyAPI

Page 72: Concurrent PHP in the Etsy API

Patch URL

@lapsu

bit.ly/etsy_curl_multi_patch

@EtsyAPI

Page 73: Concurrent PHP in the Etsy API

Recursion?

@lapsu@EtsyAPI

Page 74: Concurrent PHP in the Etsy API

Recursion?

@lapsu

No.

@EtsyAPI

Page 75: Concurrent PHP in the Etsy API

Recursion?

@lapsu

No?Not yet.

@EtsyAPI

Page 76: Concurrent PHP in the Etsy API

Visibility

@lapsu@EtsyAPI

Page 77: Concurrent PHP in the Etsy API

@lapsu

PHP Coroutines

@EtsyAPI

Page 78: Concurrent PHP in the Etsy API

More Code

@lapsu

Available Upon Request

@EtsyAPI

Page 79: Concurrent PHP in the Etsy API

@lapsu

codeascraft.etsy.com

@EtsyAPI

Page 80: Concurrent PHP in the Etsy API

@lapsu

</internals><wrap/>

@EtsyAPI

Page 81: Concurrent PHP in the Etsy API

@lapsu

Address Mobile Challenges

@EtsyAPI

Page 82: Concurrent PHP in the Etsy API

@lapsu

PHP Does Concurrency

@EtsyAPI

Page 83: Concurrent PHP in the Etsy API

PHP Abides

@lapsu@EtsyAPI

Page 84: Concurrent PHP in the Etsy API

Concurrent PHP

in the Etsy APIMatthew Graham

@lapsu@EtsyAPI Lead

#phpday2014 April

Thank You

Page 85: Concurrent PHP in the Etsy API

Reminder:

@lapsu

Repeat the questions

@EtsyAPI

Page 86: Concurrent PHP in the Etsy API

@lapsu

SPDY / HTTP 2.0

@EtsyAPI