Slide 1

Slide 1 text

Sergio Gil @porras iamserg.io

Slide 2

Slide 2 text

Hello, Humans! Sergio Gil @porras iamserg.io

Slide 3

Slide 3 text

list.each do |item| do_something(item) end

Slide 4

Slide 4 text

Lukas Rieder @Overbryd PStore

Slide 5

Slide 5 text

Hidden gems* in the Ruby Standard Library *They're not actually gems, that's the joke ;) Today: Queue and SizedQueue

Slide 6

Slide 6 text

list.each do |item| do_something(item) end

Slide 7

Slide 7 text

list.each do |item| do_something_slow(item) end

Slide 8

Slide 8 text

list.each do |item| http.post(item) end

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

Parallel Map

Slide 11

Slide 11 text

list.map do |item| Thread.new do do_something(item) end end.each(&:join)

Slide 12

Slide 12 text

huge_list.map do |item| Thread.new do do_something(item) end end.each(&:join)

Slide 13

Slide 13 text

huge_list = File.open('huge.txt') # * * This works as is because File (and all IO's) include Enumerable

Slide 14

Slide 14 text

huge_list = TCPSocket.new( 'somewhere.com', 1234) # * * This works as is because TCPSocket (and all IO's) include Enumerable

Slide 15

Slide 15 text

Amdahl's Law

Slide 16

Slide 16 text

No content

Slide 17

Slide 17 text

No content

Slide 18

Slide 18 text

Thread Pools

Slide 19

Slide 19 text

Queue

Slide 20

Slide 20 text

require 'thread' num_workers = 20 queue = Queue.new threads = num_workers.times.map do Thread.new do until (item = queue.pop) == :END do_something(item) end end end list.each { |item| queue << item } num_workers.times { queue << :END } threads.each(&:join)

Slide 21

Slide 21 text

SizedQueue

Slide 22

Slide 22 text

require 'thread' num_workers = 20 queue = SizedQueue.new(num_workers * 2) threads = num_workers.times.map do Thread.new do until (item = queue.pop) == :END do_something(item) end end end list.each { |item| queue << item } num_workers.times { queue << :END } threads.each(&:join)

Slide 23

Slide 23 text

Bonus Track: Refactoring

Slide 24

Slide 24 text

require 'thread' num_workers = 20 queue = SizedQueue.new(num_workers * 2) threads = num_workers.times.map do Thread.new do until (item = queue.pop) == :END do_something(item) end end end list.each { |item| queue << item } num_workers.times { queue << :END } threads.each(&:join)

Slide 25

Slide 25 text

require 'thread' num_workers = 20 queue = SizedQueue.new(num_workers * 2) threads = num_workers.times.map do Thread.new do until (item = queue.pop) == :END do_something(item) end end end list.each { |item| queue << item } num_workers.times { queue << :END } threads.each(&:join) U GLY

Slide 26

Slide 26 text

class WorkersPool def initialize(num_workers) ... end def process(enumerable, &block) ... end end

Slide 27

Slide 27 text

workers = WorkersPool.new(20) workers.process(huge_list) do |item| do_something(item) end

Slide 28

Slide 28 text

Dankeschön! Sergio Gil @porras iamserg.io