Clean & fast code with Enumerators
DENIS DEFREYNE RUG::B DECEMBER 7TH, 2017
Slide 2
Slide 2 text
No content
Slide 3
Slide 3 text
No content
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
No content
Slide 6
Slide 6 text
1. Simple HTTP client
Slide 7
Slide 7 text
{
"books": [
{
"id": "B98312",
"title": "The Monkey's Raincoat",
"author": "Oswaldo Berge"
},
{
"id": "B98318",
"title": "The World, the Flesh and the Devil",
"author": "Haleigh Thompson"
}
]
}
Slide 8
Slide 8 text
def fetch_books(base_url)
url = base_url + '/books'
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
body.fetch('books')
else
raise "Unexpected response code: #{response.code}"
end
end
Slide 9
Slide 9 text
books = fetch_books('http://localhost:4567')
books.each do |book|
p book
end
Slide 10
Slide 10 text
2. Paginating HTTP client
Slide 11
Slide 11 text
{
"books": [
{
"id": "B98312",
"title": "The Monkey's Raincoat",
"author": "Oswaldo Berge"
},
{
"id": "B98318",
"title": "The World, the Flesh and the Devil",
"author": "Haleigh Thompson"
}
],
"cursor": "B98318"
}
Slide 12
Slide 12 text
def fetch_books(base_url)
url = base_url + '/books'
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
body.fetch('books')
else
raise "Unexpected response code: #{response.code}"
end
end
Slide 13
Slide 13 text
def fetch_books(base_url)
books = []
loop do
url = base_url + '/books'
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
books.concat(body.fetch('books'))
break
else
raise "Unexpected response code: #{response.code}"
end
end
books
end
Slide 14
Slide 14 text
def fetch_books(base_url)
books = []
cursor = nil
loop do
url = base_url + '/books'
url += "?cursor=#{cursor}" if cursor
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
books.concat(body.fetch('books'))
cursor = body.fetch('cursor')
break if cursor.nil?
else
raise "Unexpected response code: #{response.code}"
end
end
books
end
Slide 15
Slide 15 text
def fetch_books(base_url)
books = []
cursor = nil
loop do
url = base_url + '/books'
url += "?cursor=#{cursor}" if cursor
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
books.concat(body.fetch('books'))
cursor = body.fetch('cursor')
break if cursor.nil?
else
raise "Unexpected response code: #{response.code}"
end
end
books
end
Slide 16
Slide 16 text
books = fetch_books('http://localhost:4567')
books.each do |book|
p book
end
Slide 17
Slide 17 text
3. Refactoring
Slide 18
Slide 18 text
def fetch_books(base_url)
books = []
cursor = nil
loop do
url = base_url + '/books'
url += "?cursor=#{cursor}" if cursor
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
books.concat(body.fetch('books'))
cursor = body.fetch('cursor')
break if cursor.nil?
else
raise "Unexpected response code: #{response.code}"
end
end
books
end
Slide 19
Slide 19 text
def fetch_books(base_url)
cursor = nil
loop do
url = base_url + '/books'
url += "?cursor=#{cursor}" if cursor
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
body.fetch('books').each { |b| yield(b) }
cursor = body.fetch('cursor')
break if cursor.nil?
else
raise "Unexpected response code: #{response.code}"
end
end
end
Slide 20
Slide 20 text
fetch_books('http://localhost:4567') do |book|
p book
end
Slide 21
Slide 21 text
4. More refactoring
Slide 22
Slide 22 text
def fetch_books(base_url)
cursor = nil
loop do
url = base_url + '/books'
url += "?cursor=#{cursor}" if cursor
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
body.fetch('books').each { |b| yield(b) }
cursor = body.fetch('cursor')
break if cursor.nil?
else
raise "Unexpected response code: #{response.code}"
end
end
end
Slide 23
Slide 23 text
def fetch(base_url)
cursor = nil
loop do
url = base_url
url += "?cursor=#{cursor}" if cursor
response = NetUVHTTP.get_response(URI.parse(url))
case response.code
when '200'
body = JSON.parse(response.body)
yield(body)
cursor = body.fetch('cursor')
break if cursor.nil?
else
raise "Unexpected response code: #{response.code}"
end
end
end
Slide 24
Slide 24 text
fetch('http://localhost:4567/books') do |response|
response.fetch('books').each do |book|
p book
end
end
Slide 25
Slide 25 text
responses = []
fetch('http://localhost:4567/books') do |response|
responses << response
end
books = responses.map { |r| r.fetch('books') }.flatten
books.each do |book|
p book
end
Slide 26
Slide 26 text
responses = []
fetch('http://localhost:4567/books') do |response|
responses << response
end
Given
‣ 200 books
‣ HTTP response contains 50 books
‣ it takes 1s to fetch a batch of books
‣ it takes 1s to store a batch of books
Slide 40
Slide 40 text
Given
‣ 200 books
‣ HTTP response contains 50 books
‣ it takes 1s to fetch a batch of books
‣ it takes 1s to store a batch of books
Question
How long does this code take to execute?
3s 4s 5s 8s 16s
Slide 41
Slide 41 text
Given
‣ 200 books
‣ HTTP response contains 50 books
‣ it takes 1s to fetch a batch of books
‣ it takes 1s to store a batch of books
Question
How long does this code take to execute?
3s 4s 5s 8s 16s
Given
‣ 200 books
‣ HTTP response contains 50 books
‣ it takes 1s to fetch a batch of books
‣ it takes 1s to store a batch of books
Slide 50
Slide 50 text
Given
‣ 200 books
‣ HTTP response contains 50 books
‣ it takes 1s to fetch a batch of books
‣ it takes 1s to store a batch of books
Question
How long does this code take to execute?
3s 4s 5s 8s 16s
Slide 51
Slide 51 text
Given
‣ 200 books
‣ HTTP response contains 50 books
‣ it takes 1s to fetch a batch of books
‣ it takes 1s to store a batch of books
Question
How long does this code take to execute?
3s 4s 5s 8s 16s