SlideShare a Scribd company logo
Dexador Rises
Lisp Meet Up #31
August 26, 2015
Eitaro Fukamachi
Somewrite Co., Ltd.
I’m Eitaro Fukamachi
@nitro_idiot fukamachi
My Products
• Clack
• Caveman2
• Woo
• quickdocs.org
• Qlot
Contributing
• Roswell
We Work Remotely
We Work Remotely
We’re hiring!
Today,
let me talk about HTTP client.
HTTP client
Client Server
HTTP client
Client Server
HTTP Request
GET / HTTP/1.1
Host: quickdocs.org
User-Agent: curl/7.43.0
Accept: */*
HTTP client
Client Server
HTTP Request
HTTP Response
GET / HTTP/1.1
Host: quickdocs.org
User-Agent: curl/7.43.0
Accept: */*
HTTP/1.1 200 OK
Date: Mon, 24 Aug 2015 00:41:36 GMT
Content-Type: text/html
Content-Length: 3771
Connection: keep-alive
HTTP client
Client Server
HTTP Request
HTTP Response
GET / HTTP/1.1
Host: quickdocs.org
User-Agent: curl/7.43.0
Accept: */*
HTTP/1.1 200 OK
Date: Mon, 24 Aug 2015 00:41:36 GMT
Content-Type: text/html
Content-Length: 3771
Connection: keep-alive
ex) Google Chrome, curl, Drakma ex) Apache, nginx, Woo
HTTP client libraries
• Drakma
• trivial-http
• Carrier
HTTP client libraries
• Drakma
• De facto. Full-featured.
• trivial-http
• Simple. A few features. No SSL.
• Carrier
• Asynchronous.
HTTP client libraries
• Drakma (usocket)
• De facto. Full-featured.
• trivial-http (usocket)
• Simple. A few features. No SSL.
• Carrier (cl-async/libuv)
• Asynchronous.
HTTP client libraries
• Drakma (usocket)
• De facto. Full-featured.
• trivial-http (usocket)
• Simple. A few features. No SSL.
• Carrier (cl-async/libuv)
• Asynchronous.
75
LIBRARIES
Required by
3
LIBRARIES
None
Drakma
• Ediware
• Since 2006
• Still maintained at GitHub
Mature??? Easy to use??? Fast???
No.
Pitfall 1:
Force URL encoding
• Force URL encoding with PURI
Pitfall (1/3) of Drakma
(drakma:http-request
(format nil “http://b.hatena.ne.jp/search/tag?q=~A”
tag))
tag = “lisp” => OK
tag = “scheme” => OK
tag = “clojure” => OK
tag = “common lisp” => PURI:URI-PARSE-ERROR
• Force URL encoding with PURI
Pitfall (1/3) of Drakma
(drakma:http-request
(format nil “http://b.hatena.ne.jp/search/tag?q=~A”
(drakma:url-encode tag :utf-8)))
tag = “lisp” => OK
tag = “scheme” => OK
tag = “clojure” => OK
tag = “common lisp” => “common+lisp”
• Force URL encoding with PURI
Pitfall (1/3) of Drakma
(drakma:http-request
(format nil “http://b.hatena.ne.jp/search/tag?q=~A”
(drakma:url-encode tag :utf-8)))
tag = “lisp” => OK
tag = “scheme” => OK
tag = “clojure” => OK
tag = “common lisp” => “common+lisp”
tag = “AKB48” => OK
tag = “乃木坂46” => "%E4%B9%83%E6%9C%A8%E5%9D%8246"
• Force URL encoding with PURI
Pitfall (1/3) of Drakma
(drakma:http-request
(format nil “http://b.hatena.ne.jp/search/tag?q=~A”
(drakma:url-encode tag :utf-8))
:preserve-uri t)
tag = “lisp” => OK
tag = “scheme” => OK
tag = “clojure” => OK
tag = “common lisp” => OK
tag = “AKB48” => OK
tag = “乃木坂46” => OK
Pitfall 2:
Poor language support
• Poor language support with flexi-streams
Pitfall (2/3) of Drakma
(drakma:http-request “http://www.hatena.ne.jp/”)
(drakma:http-request “http://www.google.co.jp/”)
• Poor language support with flexi-streams
Pitfall (2/3) of Drakma
(drakma:http-request “http://www.hatena.ne.jp/”)
;; => body as UTF-8 string
(drakma:http-request “http://www.google.co.jp/”)
;; => body as byte vector
WARNING: Problems determining charset (falling back to binary):
:SHIFT_JIS is not known to be a name for an external format.
Pitfall 3:
Error handling
• Tend to forget error handling
Pitfall (3/3) of Drakma
(let* ((body (drakma:http-request “http://cliki.net”))
(parsed-html (plump:parse body)))
…)
• Tend to forget error handling
Pitfall (3/3) of Drakma
(let* ((body (drakma:http-request “http://cliki.net”))
(parsed-html (plump:parse body)))
…)
It fails if the HTTP response code is 4xx or 5xx.
• Tend to forget error handling
Pitfall (3/3) of Drakma
(multiple-value-bind (body status)
(drakma:http-request “http://cliki.net”)
(unless (= status 200)
(error “An HTTP request failed (Code=~D)”
status))
(let ((parsed-html (plump:parse body)))
…))
Raise an error unless the status is not 200
• Tend to forget error handling
Pitfall (3/3) of Drakma
(multiple-value-bind (body status)
(drakma:http-request “http://cliki.net”)
(unless (= status 200)
(error “An HTTP request failed (Code=~D)”
status))
(let ((parsed-html (plump:parse body)))
…))
Raise an error unless the status is not 200
Want to retry???
• Tend to forget error handling
Pitfall (3/3) of Drakma
(block nil
(tagbody
retry
(multiple-value-bind (body status)
(drakma:http-request "http://cliki.net/")
(unless (= status 200)
(go retry))
(return body))))
With Auto-Retrying
• Tend to forget error handling
Pitfall (3/3) of Drakma
(block nil
(let ((times 5))
(tagbody
retry
(multiple-value-bind (body status)
(drakma:http-request "http://cliki.net/")
(unless (= status 200)
(when (= times 0)
(error "An HTTP request failed. (Code=~D)”
status))
(decf times)
(go retry))
(return body)))))
Retry only 5 times
Many pitfalls.
Ridiculous.
We just wanted to
send an HTTP request.
Dexador changes it.
• Full-featured. usocket based.
• Use fast-http, QURI, Babel, cl-cookie
Dexador: Another choice
Dexador: APIs
(dex:get “http://lisp.org/“)
(dex:post “http://lisp.org/“)
(dex:head “http://lisp.org/“)
(dex:put “http://lisp.org/“)
(dex:delete “http://lisp.org/“)
Dexador: Language support
;; Shift_JIS
(dex:get “http://www.google.co.jp/“)
;; EUC-JP
(dex:get “https://mixi.jp/“)
Dexador: Error handling
(handler-case (dex:get “http://cliki.net/“)
(dex:http-request-failed (e)
(warn “An HTTP request failed (Code=~D)”
(dex:response-status e))))
Dexador: Error handling
(handler-case (dex:get “http://cliki.net/“)
(dex:http-request-forbidden ()
;; for 403 forbidden
)
(dex:http-request-service-unavailable ()
;; for 503 service unavailable
)
(dex:http-request-failed (e)
(warn “An HTTP request failed (Code=~D)”
(dex:response-status e))))
Dexador: Error handling
;; Ignore errors and continue
(handler-bind ((dex:http-request-failed
#'dex:ignore-and-continue))
(dex:get "http://lisp.org"))
Dexador: Auto-Retrying
;; Auto-retry on 503 error
(handler-bind ((dex:http-request-service-unavailable
#’dex:retry-request))
(dex:get "http://lisp.org"))
Dexador: Auto-Retrying
;; Retry only 5 times
(handler-bind ((dex:http-request-service-unavailable
(dex:retry-request 5)))
(dex:get "http://lisp.org"))
Dexador: Auto-Retrying
;; Retry only 5 times at 3-second intervals
(handler-bind ((dex:http-request-service-unavailable
(dex:retry-request 5 :interval 3)))
(dex:get "http://lisp.org"))
Dexador: Auto-Retrying
;; Retry only 5 times at 3-second intervals
(handler-bind ((dex:http-request-service-unavailable
(dex:retry-request 5 :interval 3)))
(dex:get "http://lisp.org"))
(block nil
(let ((times 5))
(tagbody
retry
(multiple-value-bind (body status)
(drakma:http-request "http://cliki.net/")
(unless (= status 200)
(when (= times 0)
(error "An HTTP request failed. (Code=~D)”
status))
(decf times)
(sleep 3)
(go retry))
(return body)))))
Dexador
Drakma
You may ask…
You may ask…
…is it fast?
Benchmark
Sending GET request 30 times to Local Server

(lower is better)
0
0.009
0.018
0.026
0.035
Drakma Dexador

w/out conneciton-pool
0.024s
Benchmark
Sending GET request 30 times to Local Server

(lower is better)
0
0.009
0.018
0.026
0.035
Drakma Dexador

w/out conneciton-pool
0.013s
0.024s
Sending GET request 30 times to Local Server

(lower is better)
0
0.009
0.018
0.026
0.035
Drakma Dexador

w/out conneciton-pool
0.013s
0.024s
Benchmark
x1.8 faster!
Sending GET request 30 times to Local Server

(lower is better)
0
0.009
0.018
0.026
0.035
Drakma Dexador

w/out conneciton-pool
0.013s
0.024s
Benchmark
x1.8 faster!????
How about requesting
over network?
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.505s
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.396s
0.505s
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.396s
0.505s x1.2 faster
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.396s
0.505s 0.0036 sec/req
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.396s
0.505s 0.0036 sec/req
Too trivial improvement…
How come?
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.396s
0.505s
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.396s
0.505s
Network Latency
+
Connection
establishment
Network Latency
+
Connection
establishment
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
0.396s
0.505s
Network Latency
+
Connection
establishment
Network Latency
+
Connection
establishment
The largest bottleneck
Differences of Servers/Clients
HTTP Server HTTP Client
C
S
C C
C
S
Can’t help
Network Latency and
bandwidth.
Can skip
connection establishment…?
• Reuse connections once established
(Implicit) Connection-pooling
• Reuse connections once established
(Implicit) Connection-pooling
;; Establish a new connection
(dex:get “http://lisp.org/index.html“)
;; Reuse the above connection
(dex:get “http://lisp.org/index.html“)
• Reuse connections once established
(Implicit) Connection-pooling
;; Establish a new connection
(dex:get “http://lisp.org/index.html“)
;; Reuse the above connection
(dex:get “http://lisp.org/index.html“)
0.727 sec
0.380 sec
Benchmark (again)
Benchmark
Sending GET request 30 times to Local Server

(lower is better)
0
0.006
0.012
0.018
0.024
Drakma Dexador

w/out conneciton-pool
Dexador

w/ connection-pool
0.013s
0.024s
Benchmark
Sending GET request 30 times to Local Server

(lower is better)
0
0.006
0.012
0.018
0.024
Drakma Dexador

w/out conneciton-pool
Dexador

w/ connection-pool
0.005s
0.013s
0.024s
Benchmark
Sending GET request 30 times to Local Server

(lower is better)
0
0.006
0.012
0.018
0.024
Drakma Dexador

w/out conneciton-pool
Dexador

w/ connection-pool
0.005s
0.013s
0.024s
x4.8 faster!
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
Dexador

w/ connection-pool
0.396s
0.505s
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
Dexador

w/ connection-pool
0.219s
0.396s
0.505s
Benchmark
Sending GET request 30 times to Remote Server

(lower is better)
0
0.15
0.3
0.45
0.6
Drakma Dexador

w/out conneciton-pool
Dexador

w/ connection-pool
0.219s
0.396s
0.505s Still x2.3 faster!
• It’s pretty common to request to the same
host multiple times
• Can expect some performance
improvements in real applications
In real applications
Status
• Still BETA (v0.9.7)
• Stabilizing. More performance
improvements are secondary importance.
• Bug reports are welcome
• Tested with SBCL, CCL, ABCL and ECL

on Travis CI
Status
Try the new player
and send me a feedback.
Thanks.
EITARO FUKAMACHI
8arrow.org
@nitro_idiot fukamachi
See Also
• Dexador: github.com/fukamachi/dexador

More Related Content

What's hot

Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
Seungmo Koo
 
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
Heungsub Lee
 
Next-generation MMORPG service architecture
Next-generation MMORPG service architectureNext-generation MMORPG service architecture
Next-generation MMORPG service architecture
Jongwon Kim
 
이재훈 개발 포트폴리오.pdf
이재훈 개발 포트폴리오.pdf이재훈 개발 포트폴리오.pdf
이재훈 개발 포트폴리오.pdf
jaehoon lee
 
Git Introduction
Git IntroductionGit Introduction
Git Introduction
Gareth Hall
 
Cloud Native Java GraalVM 이상과 현실
Cloud Native Java GraalVM 이상과 현실Cloud Native Java GraalVM 이상과 현실
Cloud Native Java GraalVM 이상과 현실
Taewan Kim
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
Nam Hyeonuk
 
게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hosting게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hosting
iFunFactory Inc.
 
GA로 게임 로그 분석하기
GA로 게임 로그 분석하기GA로 게임 로그 분석하기
GA로 게임 로그 분석하기
Alan Kang
 
Design for succcess with react and storybook.js
Design for succcess with react and storybook.jsDesign for succcess with react and storybook.js
Design for succcess with react and storybook.js
Chris Saylor
 
Bitbucket and Git
Bitbucket and GitBitbucket and Git
Bitbucket and Git
Mohit Shukla
 
JavaScript Fetch API
JavaScript Fetch APIJavaScript Fetch API
JavaScript Fetch API
Xcat Liu
 
Lets make a better react form
Lets make a better react formLets make a better react form
Lets make a better react form
Yao Nien Chung
 
Git basics
Git basicsGit basics
Git basics
Amit Sawhney
 
도메인 주도 설계의 본질
도메인 주도 설계의 본질도메인 주도 설계의 본질
도메인 주도 설계의 본질
Young-Ho Cho
 
Git and GitHub for Documentation
Git and GitHub for DocumentationGit and GitHub for Documentation
Git and GitHub for Documentation
Anne Gentle
 
Writing Reusable Web Components with jQuery and jQuery UI
Writing Reusable Web Components with jQuery and jQuery UIWriting Reusable Web Components with jQuery and jQuery UI
Writing Reusable Web Components with jQuery and jQuery UI
Ynon Perek
 
Successful DB migrations with Liquibase
 Successful DB migrations with Liquibase Successful DB migrations with Liquibase
Successful DB migrations with Liquibase
Illia Seleznov
 
프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요Chris Ohk
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)
Tracy Lee
 

What's hot (20)

Windows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCPWindows Registered I/O (RIO) vs IOCP
Windows Registered I/O (RIO) vs IOCP
 
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
[야생의 땅: 듀랑고] 서버 아키텍처 - SPOF 없는 분산 MMORPG 서버
 
Next-generation MMORPG service architecture
Next-generation MMORPG service architectureNext-generation MMORPG service architecture
Next-generation MMORPG service architecture
 
이재훈 개발 포트폴리오.pdf
이재훈 개발 포트폴리오.pdf이재훈 개발 포트폴리오.pdf
이재훈 개발 포트폴리오.pdf
 
Git Introduction
Git IntroductionGit Introduction
Git Introduction
 
Cloud Native Java GraalVM 이상과 현실
Cloud Native Java GraalVM 이상과 현실Cloud Native Java GraalVM 이상과 현실
Cloud Native Java GraalVM 이상과 현실
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hosting게임서버 구축 방법비교 : GBaaS vs. Self-hosting
게임서버 구축 방법비교 : GBaaS vs. Self-hosting
 
GA로 게임 로그 분석하기
GA로 게임 로그 분석하기GA로 게임 로그 분석하기
GA로 게임 로그 분석하기
 
Design for succcess with react and storybook.js
Design for succcess with react and storybook.jsDesign for succcess with react and storybook.js
Design for succcess with react and storybook.js
 
Bitbucket and Git
Bitbucket and GitBitbucket and Git
Bitbucket and Git
 
JavaScript Fetch API
JavaScript Fetch APIJavaScript Fetch API
JavaScript Fetch API
 
Lets make a better react form
Lets make a better react formLets make a better react form
Lets make a better react form
 
Git basics
Git basicsGit basics
Git basics
 
도메인 주도 설계의 본질
도메인 주도 설계의 본질도메인 주도 설계의 본질
도메인 주도 설계의 본질
 
Git and GitHub for Documentation
Git and GitHub for DocumentationGit and GitHub for Documentation
Git and GitHub for Documentation
 
Writing Reusable Web Components with jQuery and jQuery UI
Writing Reusable Web Components with jQuery and jQuery UIWriting Reusable Web Components with jQuery and jQuery UI
Writing Reusable Web Components with jQuery and jQuery UI
 
Successful DB migrations with Liquibase
 Successful DB migrations with Liquibase Successful DB migrations with Liquibase
Successful DB migrations with Liquibase
 
프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요프로그래머가 되고 싶으세요
프로그래머가 되고 싶으세요
 
RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)RxJS Operators - Real World Use Cases (FULL VERSION)
RxJS Operators - Real World Use Cases (FULL VERSION)
 

Similar to Dexador Rises

tdc2012
tdc2012tdc2012
tdc2012
Juan Lopes
 
Http capturing
Http capturingHttp capturing
Http capturing
Eric Ahn
 
Haproxy - zastosowania
Haproxy - zastosowaniaHaproxy - zastosowania
Haproxy - zastosowania
Łukasz Jagiełło
 
Web前端性能优化 2014
Web前端性能优化 2014Web前端性能优化 2014
Web前端性能优化 2014
Yubei Li
 
Http2 in practice
Http2 in practiceHttp2 in practice
Http2 in practice
Patrick Meenan
 
6 app-tcp
6 app-tcp6 app-tcp
Atlassian meets Kerberos
Atlassian meets KerberosAtlassian meets Kerberos
Atlassian meets Kerberos
Nils Hofmeister
 
Inside Of Mbga Open Platform
Inside Of Mbga Open PlatformInside Of Mbga Open Platform
Inside Of Mbga Open PlatformHideo Kimura
 
HTTP Caching and PHP
HTTP Caching and PHPHTTP Caching and PHP
HTTP Caching and PHP
David de Boer
 
Apache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestApache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestMyles Braithwaite
 
Apache mod authまわりとか
Apache mod authまわりとかApache mod authまわりとか
Apache mod authまわりとか
Toshiyuki Terashita
 
SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28
SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28
SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28
Jxck Jxck
 
Into The Box 2018 Ortus Keynote
Into The Box 2018 Ortus KeynoteInto The Box 2018 Ortus Keynote
Into The Box 2018 Ortus Keynote
Ortus Solutions, Corp
 
Varnish Cache and Django (Falcon, Flask etc)
Varnish Cache and Django (Falcon, Flask etc)Varnish Cache and Django (Falcon, Flask etc)
Varnish Cache and Django (Falcon, Flask etc)
Данил Иванов
 
VUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareVUG5: Varnish at Opera Software
VUG5: Varnish at Opera Software
Cosimo Streppone
 
Logstash for SEO: come monitorare i Log del Web Server in realtime
Logstash for SEO: come monitorare i Log del Web Server in realtimeLogstash for SEO: come monitorare i Log del Web Server in realtime
Logstash for SEO: come monitorare i Log del Web Server in realtime
Andrea Cardinale
 
Load testing with Blitz
Load testing with BlitzLoad testing with Blitz
Load testing with Blitz
Lindsay Holmwood
 
Devoxx Maroc 2015 HTTP 1, HTTP 2 and folks
Devoxx Maroc  2015 HTTP 1, HTTP 2 and folksDevoxx Maroc  2015 HTTP 1, HTTP 2 and folks
Devoxx Maroc 2015 HTTP 1, HTTP 2 and folks
Nicolas Martignole
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
Metosin Oy
 
An Introduction to Twisted
An Introduction to TwistedAn Introduction to Twisted
An Introduction to Twisted
sdsern
 

Similar to Dexador Rises (20)

tdc2012
tdc2012tdc2012
tdc2012
 
Http capturing
Http capturingHttp capturing
Http capturing
 
Haproxy - zastosowania
Haproxy - zastosowaniaHaproxy - zastosowania
Haproxy - zastosowania
 
Web前端性能优化 2014
Web前端性能优化 2014Web前端性能优化 2014
Web前端性能优化 2014
 
Http2 in practice
Http2 in practiceHttp2 in practice
Http2 in practice
 
6 app-tcp
6 app-tcp6 app-tcp
6 app-tcp
 
Atlassian meets Kerberos
Atlassian meets KerberosAtlassian meets Kerberos
Atlassian meets Kerberos
 
Inside Of Mbga Open Platform
Inside Of Mbga Open PlatformInside Of Mbga Open Platform
Inside Of Mbga Open Platform
 
HTTP Caching and PHP
HTTP Caching and PHPHTTP Caching and PHP
HTTP Caching and PHP
 
Apache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux FestApache CouchDB talk at Ontario GNU Linux Fest
Apache CouchDB talk at Ontario GNU Linux Fest
 
Apache mod authまわりとか
Apache mod authまわりとかApache mod authまわりとか
Apache mod authまわりとか
 
SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28
SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28
SPDY & HTTP2.0 & QUIC - #bpstudy 2013-08-28
 
Into The Box 2018 Ortus Keynote
Into The Box 2018 Ortus KeynoteInto The Box 2018 Ortus Keynote
Into The Box 2018 Ortus Keynote
 
Varnish Cache and Django (Falcon, Flask etc)
Varnish Cache and Django (Falcon, Flask etc)Varnish Cache and Django (Falcon, Flask etc)
Varnish Cache and Django (Falcon, Flask etc)
 
VUG5: Varnish at Opera Software
VUG5: Varnish at Opera SoftwareVUG5: Varnish at Opera Software
VUG5: Varnish at Opera Software
 
Logstash for SEO: come monitorare i Log del Web Server in realtime
Logstash for SEO: come monitorare i Log del Web Server in realtimeLogstash for SEO: come monitorare i Log del Web Server in realtime
Logstash for SEO: come monitorare i Log del Web Server in realtime
 
Load testing with Blitz
Load testing with BlitzLoad testing with Blitz
Load testing with Blitz
 
Devoxx Maroc 2015 HTTP 1, HTTP 2 and folks
Devoxx Maroc  2015 HTTP 1, HTTP 2 and folksDevoxx Maroc  2015 HTTP 1, HTTP 2 and folks
Devoxx Maroc 2015 HTTP 1, HTTP 2 and folks
 
Naked Performance With Clojure
Naked Performance With ClojureNaked Performance With Clojure
Naked Performance With Clojure
 
An Introduction to Twisted
An Introduction to TwistedAn Introduction to Twisted
An Introduction to Twisted
 

More from fukamachi

競プロの話
競プロの話競プロの話
競プロの話
fukamachi
 
Rove / Testing is a pity in Common Lisp
Rove / Testing is a pity in Common LispRove / Testing is a pity in Common Lisp
Rove / Testing is a pity in Common Lisp
fukamachi
 
SBLint
SBLintSBLint
SBLint
fukamachi
 
Mito, a successor of Integral
Mito, a successor of IntegralMito, a successor of Integral
Mito, a successor of Integral
fukamachi
 
Woo: Writing a fast web server @ ELS2015
Woo: Writing a fast web server @ ELS2015Woo: Writing a fast web server @ ELS2015
Woo: Writing a fast web server @ ELS2015
fukamachi
 
Clack: glue for web apps
Clack: glue for web appsClack: glue for web apps
Clack: glue for web apps
fukamachi
 
Woo: Writing a fast web server
Woo: Writing a fast web serverWoo: Writing a fast web server
Woo: Writing a fast web server
fukamachi
 
Redesigning Common Lisp
Redesigning Common LispRedesigning Common Lisp
Redesigning Common Lisp
fukamachi
 
Integral - New O/R Mapper for Common Lisp
Integral - New O/R Mapper for Common LispIntegral - New O/R Mapper for Common Lisp
Integral - New O/R Mapper for Common Lisp
fukamachi
 
About Clack
About ClackAbout Clack
About Clack
fukamachi
 
Shelly
ShellyShelly
Shelly
fukamachi
 
第四回関西Emacs「ari.el」
第四回関西Emacs「ari.el」第四回関西Emacs「ari.el」
第四回関西Emacs「ari.el」
fukamachi
 
Clack & Caveman
Clack & CavemanClack & Caveman
Clack & Cavemanfukamachi
 
Lispで仕事をするために
Lispで仕事をするためにLispで仕事をするために
Lispで仕事をするために
fukamachi
 
Lisperの見る世界
Lisperの見る世界Lisperの見る世界
Lisperの見る世界
fukamachi
 
JavaからClojure、そして夢の世界へ
JavaからClojure、そして夢の世界へJavaからClojure、そして夢の世界へ
JavaからClojure、そして夢の世界へ
fukamachi
 
自分をClojure化する方法
自分をClojure化する方法自分をClojure化する方法
自分をClojure化する方法fukamachi
 
Google App Engine for Java (手嶋屋勉強会)
Google App Engine for Java (手嶋屋勉強会)Google App Engine for Java (手嶋屋勉強会)
Google App Engine for Java (手嶋屋勉強会)
fukamachi
 

More from fukamachi (19)

競プロの話
競プロの話競プロの話
競プロの話
 
Rove / Testing is a pity in Common Lisp
Rove / Testing is a pity in Common LispRove / Testing is a pity in Common Lisp
Rove / Testing is a pity in Common Lisp
 
SBLint
SBLintSBLint
SBLint
 
Mito, a successor of Integral
Mito, a successor of IntegralMito, a successor of Integral
Mito, a successor of Integral
 
Woo: Writing a fast web server @ ELS2015
Woo: Writing a fast web server @ ELS2015Woo: Writing a fast web server @ ELS2015
Woo: Writing a fast web server @ ELS2015
 
Clack: glue for web apps
Clack: glue for web appsClack: glue for web apps
Clack: glue for web apps
 
Woo: Writing a fast web server
Woo: Writing a fast web serverWoo: Writing a fast web server
Woo: Writing a fast web server
 
Redesigning Common Lisp
Redesigning Common LispRedesigning Common Lisp
Redesigning Common Lisp
 
Integral - New O/R Mapper for Common Lisp
Integral - New O/R Mapper for Common LispIntegral - New O/R Mapper for Common Lisp
Integral - New O/R Mapper for Common Lisp
 
About Clack
About ClackAbout Clack
About Clack
 
Shelly
ShellyShelly
Shelly
 
第四回関西Emacs「ari.el」
第四回関西Emacs「ari.el」第四回関西Emacs「ari.el」
第四回関西Emacs「ari.el」
 
Clack & Caveman
Clack & CavemanClack & Caveman
Clack & Caveman
 
Lispで仕事をするために
Lispで仕事をするためにLispで仕事をするために
Lispで仕事をするために
 
Lisperの見る世界
Lisperの見る世界Lisperの見る世界
Lisperの見る世界
 
Lisp Poetry
Lisp PoetryLisp Poetry
Lisp Poetry
 
JavaからClojure、そして夢の世界へ
JavaからClojure、そして夢の世界へJavaからClojure、そして夢の世界へ
JavaからClojure、そして夢の世界へ
 
自分をClojure化する方法
自分をClojure化する方法自分をClojure化する方法
自分をClojure化する方法
 
Google App Engine for Java (手嶋屋勉強会)
Google App Engine for Java (手嶋屋勉強会)Google App Engine for Java (手嶋屋勉強会)
Google App Engine for Java (手嶋屋勉強会)
 

Recently uploaded

The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Product School
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
DianaGray10
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
Laura Byrne
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
BookNet Canada
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Tobias Schneck
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
Product School
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 

Recently uploaded (20)

The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...Mission to Decommission: Importance of Decommissioning Products to Increase E...
Mission to Decommission: Importance of Decommissioning Products to Increase E...
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
Connector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a buttonConnector Corner: Automate dynamic content and events by pushing a button
Connector Corner: Automate dynamic content and events by pushing a button
 
The Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and SalesThe Art of the Pitch: WordPress Relationships and Sales
The Art of the Pitch: WordPress Relationships and Sales
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...Transcript: Selling digital books in 2024: Insights from industry leaders - T...
Transcript: Selling digital books in 2024: Insights from industry leaders - T...
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024
 
How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...How world-class product teams are winning in the AI era by CEO and Founder, P...
How world-class product teams are winning in the AI era by CEO and Founder, P...
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 

Dexador Rises

  • 1. Dexador Rises Lisp Meet Up #31 August 26, 2015 Eitaro Fukamachi Somewrite Co., Ltd.
  • 3. My Products • Clack • Caveman2 • Woo • quickdocs.org • Qlot
  • 5.
  • 8. Today, let me talk about HTTP client.
  • 10. HTTP client Client Server HTTP Request GET / HTTP/1.1 Host: quickdocs.org User-Agent: curl/7.43.0 Accept: */*
  • 11. HTTP client Client Server HTTP Request HTTP Response GET / HTTP/1.1 Host: quickdocs.org User-Agent: curl/7.43.0 Accept: */* HTTP/1.1 200 OK Date: Mon, 24 Aug 2015 00:41:36 GMT Content-Type: text/html Content-Length: 3771 Connection: keep-alive
  • 12. HTTP client Client Server HTTP Request HTTP Response GET / HTTP/1.1 Host: quickdocs.org User-Agent: curl/7.43.0 Accept: */* HTTP/1.1 200 OK Date: Mon, 24 Aug 2015 00:41:36 GMT Content-Type: text/html Content-Length: 3771 Connection: keep-alive ex) Google Chrome, curl, Drakma ex) Apache, nginx, Woo
  • 13. HTTP client libraries • Drakma • trivial-http • Carrier
  • 14. HTTP client libraries • Drakma • De facto. Full-featured. • trivial-http • Simple. A few features. No SSL. • Carrier • Asynchronous.
  • 15. HTTP client libraries • Drakma (usocket) • De facto. Full-featured. • trivial-http (usocket) • Simple. A few features. No SSL. • Carrier (cl-async/libuv) • Asynchronous.
  • 16. HTTP client libraries • Drakma (usocket) • De facto. Full-featured. • trivial-http (usocket) • Simple. A few features. No SSL. • Carrier (cl-async/libuv) • Asynchronous. 75 LIBRARIES Required by 3 LIBRARIES None
  • 17. Drakma • Ediware • Since 2006 • Still maintained at GitHub Mature??? Easy to use??? Fast???
  • 18. No.
  • 20. • Force URL encoding with PURI Pitfall (1/3) of Drakma (drakma:http-request (format nil “http://b.hatena.ne.jp/search/tag?q=~A” tag)) tag = “lisp” => OK tag = “scheme” => OK tag = “clojure” => OK tag = “common lisp” => PURI:URI-PARSE-ERROR
  • 21. • Force URL encoding with PURI Pitfall (1/3) of Drakma (drakma:http-request (format nil “http://b.hatena.ne.jp/search/tag?q=~A” (drakma:url-encode tag :utf-8))) tag = “lisp” => OK tag = “scheme” => OK tag = “clojure” => OK tag = “common lisp” => “common+lisp”
  • 22. • Force URL encoding with PURI Pitfall (1/3) of Drakma (drakma:http-request (format nil “http://b.hatena.ne.jp/search/tag?q=~A” (drakma:url-encode tag :utf-8))) tag = “lisp” => OK tag = “scheme” => OK tag = “clojure” => OK tag = “common lisp” => “common+lisp” tag = “AKB48” => OK tag = “乃木坂46” => "%E4%B9%83%E6%9C%A8%E5%9D%8246"
  • 23. • Force URL encoding with PURI Pitfall (1/3) of Drakma (drakma:http-request (format nil “http://b.hatena.ne.jp/search/tag?q=~A” (drakma:url-encode tag :utf-8)) :preserve-uri t) tag = “lisp” => OK tag = “scheme” => OK tag = “clojure” => OK tag = “common lisp” => OK tag = “AKB48” => OK tag = “乃木坂46” => OK
  • 25. • Poor language support with flexi-streams Pitfall (2/3) of Drakma (drakma:http-request “http://www.hatena.ne.jp/”) (drakma:http-request “http://www.google.co.jp/”)
  • 26. • Poor language support with flexi-streams Pitfall (2/3) of Drakma (drakma:http-request “http://www.hatena.ne.jp/”) ;; => body as UTF-8 string (drakma:http-request “http://www.google.co.jp/”) ;; => body as byte vector WARNING: Problems determining charset (falling back to binary): :SHIFT_JIS is not known to be a name for an external format.
  • 28. • Tend to forget error handling Pitfall (3/3) of Drakma (let* ((body (drakma:http-request “http://cliki.net”)) (parsed-html (plump:parse body))) …)
  • 29. • Tend to forget error handling Pitfall (3/3) of Drakma (let* ((body (drakma:http-request “http://cliki.net”)) (parsed-html (plump:parse body))) …) It fails if the HTTP response code is 4xx or 5xx.
  • 30. • Tend to forget error handling Pitfall (3/3) of Drakma (multiple-value-bind (body status) (drakma:http-request “http://cliki.net”) (unless (= status 200) (error “An HTTP request failed (Code=~D)” status)) (let ((parsed-html (plump:parse body))) …)) Raise an error unless the status is not 200
  • 31. • Tend to forget error handling Pitfall (3/3) of Drakma (multiple-value-bind (body status) (drakma:http-request “http://cliki.net”) (unless (= status 200) (error “An HTTP request failed (Code=~D)” status)) (let ((parsed-html (plump:parse body))) …)) Raise an error unless the status is not 200 Want to retry???
  • 32. • Tend to forget error handling Pitfall (3/3) of Drakma (block nil (tagbody retry (multiple-value-bind (body status) (drakma:http-request "http://cliki.net/") (unless (= status 200) (go retry)) (return body)))) With Auto-Retrying
  • 33. • Tend to forget error handling Pitfall (3/3) of Drakma (block nil (let ((times 5)) (tagbody retry (multiple-value-bind (body status) (drakma:http-request "http://cliki.net/") (unless (= status 200) (when (= times 0) (error "An HTTP request failed. (Code=~D)” status)) (decf times) (go retry)) (return body))))) Retry only 5 times
  • 36. We just wanted to send an HTTP request.
  • 38. • Full-featured. usocket based. • Use fast-http, QURI, Babel, cl-cookie Dexador: Another choice
  • 39. Dexador: APIs (dex:get “http://lisp.org/“) (dex:post “http://lisp.org/“) (dex:head “http://lisp.org/“) (dex:put “http://lisp.org/“) (dex:delete “http://lisp.org/“)
  • 40. Dexador: Language support ;; Shift_JIS (dex:get “http://www.google.co.jp/“) ;; EUC-JP (dex:get “https://mixi.jp/“)
  • 41. Dexador: Error handling (handler-case (dex:get “http://cliki.net/“) (dex:http-request-failed (e) (warn “An HTTP request failed (Code=~D)” (dex:response-status e))))
  • 42. Dexador: Error handling (handler-case (dex:get “http://cliki.net/“) (dex:http-request-forbidden () ;; for 403 forbidden ) (dex:http-request-service-unavailable () ;; for 503 service unavailable ) (dex:http-request-failed (e) (warn “An HTTP request failed (Code=~D)” (dex:response-status e))))
  • 43. Dexador: Error handling ;; Ignore errors and continue (handler-bind ((dex:http-request-failed #'dex:ignore-and-continue)) (dex:get "http://lisp.org"))
  • 44. Dexador: Auto-Retrying ;; Auto-retry on 503 error (handler-bind ((dex:http-request-service-unavailable #’dex:retry-request)) (dex:get "http://lisp.org"))
  • 45. Dexador: Auto-Retrying ;; Retry only 5 times (handler-bind ((dex:http-request-service-unavailable (dex:retry-request 5))) (dex:get "http://lisp.org"))
  • 46. Dexador: Auto-Retrying ;; Retry only 5 times at 3-second intervals (handler-bind ((dex:http-request-service-unavailable (dex:retry-request 5 :interval 3))) (dex:get "http://lisp.org"))
  • 47. Dexador: Auto-Retrying ;; Retry only 5 times at 3-second intervals (handler-bind ((dex:http-request-service-unavailable (dex:retry-request 5 :interval 3))) (dex:get "http://lisp.org")) (block nil (let ((times 5)) (tagbody retry (multiple-value-bind (body status) (drakma:http-request "http://cliki.net/") (unless (= status 200) (when (= times 0) (error "An HTTP request failed. (Code=~D)” status)) (decf times) (sleep 3) (go retry)) (return body))))) Dexador Drakma
  • 50. Benchmark Sending GET request 30 times to Local Server
 (lower is better) 0 0.009 0.018 0.026 0.035 Drakma Dexador
 w/out conneciton-pool 0.024s
  • 51. Benchmark Sending GET request 30 times to Local Server
 (lower is better) 0 0.009 0.018 0.026 0.035 Drakma Dexador
 w/out conneciton-pool 0.013s 0.024s
  • 52. Sending GET request 30 times to Local Server
 (lower is better) 0 0.009 0.018 0.026 0.035 Drakma Dexador
 w/out conneciton-pool 0.013s 0.024s Benchmark x1.8 faster!
  • 53. Sending GET request 30 times to Local Server
 (lower is better) 0 0.009 0.018 0.026 0.035 Drakma Dexador
 w/out conneciton-pool 0.013s 0.024s Benchmark x1.8 faster!????
  • 55. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.505s
  • 56. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.396s 0.505s
  • 57. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.396s 0.505s x1.2 faster
  • 58. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.396s 0.505s 0.0036 sec/req
  • 59. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.396s 0.505s 0.0036 sec/req Too trivial improvement…
  • 61. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.396s 0.505s
  • 62. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.396s 0.505s Network Latency + Connection establishment Network Latency + Connection establishment
  • 63. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool 0.396s 0.505s Network Latency + Connection establishment Network Latency + Connection establishment The largest bottleneck
  • 64. Differences of Servers/Clients HTTP Server HTTP Client C S C C C S
  • 67. • Reuse connections once established (Implicit) Connection-pooling
  • 68. • Reuse connections once established (Implicit) Connection-pooling ;; Establish a new connection (dex:get “http://lisp.org/index.html“) ;; Reuse the above connection (dex:get “http://lisp.org/index.html“)
  • 69. • Reuse connections once established (Implicit) Connection-pooling ;; Establish a new connection (dex:get “http://lisp.org/index.html“) ;; Reuse the above connection (dex:get “http://lisp.org/index.html“) 0.727 sec 0.380 sec
  • 71. Benchmark Sending GET request 30 times to Local Server
 (lower is better) 0 0.006 0.012 0.018 0.024 Drakma Dexador
 w/out conneciton-pool Dexador
 w/ connection-pool 0.013s 0.024s
  • 72. Benchmark Sending GET request 30 times to Local Server
 (lower is better) 0 0.006 0.012 0.018 0.024 Drakma Dexador
 w/out conneciton-pool Dexador
 w/ connection-pool 0.005s 0.013s 0.024s
  • 73. Benchmark Sending GET request 30 times to Local Server
 (lower is better) 0 0.006 0.012 0.018 0.024 Drakma Dexador
 w/out conneciton-pool Dexador
 w/ connection-pool 0.005s 0.013s 0.024s x4.8 faster!
  • 74. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool Dexador
 w/ connection-pool 0.396s 0.505s
  • 75. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool Dexador
 w/ connection-pool 0.219s 0.396s 0.505s
  • 76. Benchmark Sending GET request 30 times to Remote Server
 (lower is better) 0 0.15 0.3 0.45 0.6 Drakma Dexador
 w/out conneciton-pool Dexador
 w/ connection-pool 0.219s 0.396s 0.505s Still x2.3 faster!
  • 77. • It’s pretty common to request to the same host multiple times • Can expect some performance improvements in real applications In real applications
  • 79. • Still BETA (v0.9.7) • Stabilizing. More performance improvements are secondary importance. • Bug reports are welcome • Tested with SBCL, CCL, ABCL and ECL
 on Travis CI Status
  • 80. Try the new player and send me a feedback.
  • 83. See Also • Dexador: github.com/fukamachi/dexador