Your SlideShare is downloading. ×
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
RubyConf Brazil 2010
Upcoming SlideShare
Loading in...5
×

Thanks for flagging this SlideShare!

Oops! An error has occurred.

×
Saving this for later? Get the SlideShare app to save on your phone or tablet. Read anywhere, anytime – even offline.
Text the download link to your phone
Standard text messaging rates apply

RubyConf Brazil 2010

1,268

Published on

The slides for the talk I gave at RubyConf Brazil 2010!

The slides for the talk I gave at RubyConf Brazil 2010!

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
1,268
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
8
Comments
0
Likes
0
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. OMG HELLO! Friday, November 5, 2010
  • 2. THANK YOU Friday, November 5, 2010
  • 3. Aaron Patterson Friday, November 5, 2010
  • 4. AT&T, AT&T logo and all AT&T related marks are trademarks of AT&T Intellectual Property and/or AT&T affiliated companies. Friday, November 5, 2010
  • 5. @tenderlove Friday, November 5, 2010
  • 6. nokogiri Friday, November 5, 2010
  • 7. ruby core committer Friday, November 5, 2010
  • 8. YAML Friday, November 5, 2010
  • 9. Psych Friday, November 5, 2010
  • 10. DL Friday, November 5, 2010
  • 11. rails core committer Friday, November 5, 2010
  • 12. rails core committer Friday, November 5, 2010
  • 13. ActiveRecord Friday, November 5, 2010
  • 14. ARel Friday, November 5, 2010
  • 15. anywhere... Friday, November 5, 2010
  • 16. aaron.patterson@gmail.com Friday, November 5, 2010
  • 17. Friday, November 5, 2010
  • 18. WWFMD? Friday, November 5, 2010
  • 19. Preparations the @tenderlove way Friday, November 5, 2010
  • 20. What should I talk about? Friday, November 5, 2010
  • 21. Yehuda? Friday, November 5, 2010
  • 22. Evan? Friday, November 5, 2010
  • 23. DHH? Friday, November 5, 2010
  • 24. I will talk about Concurrency! Friday, November 5, 2010
  • 25. Threads! Friday, November 5, 2010
  • 26. Iterators! Friday, November 5, 2010
  • 27. Generators! Friday, November 5, 2010
  • 28. Fibers! Friday, November 5, 2010
  • 29. Coroutines! Friday, November 5, 2010
  • 30. Friday, November 5, 2010
  • 31. the @tenderlove process for producing slides Friday, November 5, 2010
  • 32. BOOKS ARE IN STORES NOW! Friday, November 5, 2010
  • 33. ONLY $24.99!!! Friday, November 5, 2010
  • 34. BUY TODAY! Friday, November 5, 2010
  • 35. Fun with Fibers! Friday, November 5, 2010
  • 36. Concurrency Friday, November 5, 2010
  • 37. WARNING! Friday, November 5, 2010
  • 38. fork() Friday, November 5, 2010
  • 39. fork() foo = "hello" fork do foo << " world" puts foo end fork do foo << " everyone!" puts foo end puts foo Process.wait Friday, November 5, 2010
  • 40. Copy on Write Friday, November 5, 2010
  • 41. Threads Friday, November 5, 2010
  • 42. Why Use Threads? Friday, November 5, 2010
  • 43. Friday, November 5, 2010
  • 44. Thread API Friday, November 5, 2010
  • 45. thread = Thread.new { ... do some work ... } thread.join new and join Friday, November 5, 2010
  • 46. 100.times { Thread.new { ... } } (Thread.list - [Thread.main]).each { |t| t.join } list / main Friday, November 5, 2010
  • 47. Return Value thread = Thread.new do 10 end thread.join thread.value # => 10 Friday, November 5, 2010
  • 48. Shared Data Friday, November 5, 2010
  • 49. n = 0 def increment(v) v + 1 end threads = 2.times.map { Thread.new { 1_000_000.times { n = increment(n) } } } threads.each { |x| x.join } puts n Friday, November 5, 2010
  • 50. 2,000,000? Friday, November 5, 2010
  • 51. Friday, November 5, 2010
  • 52. Friday, November 5, 2010
  • 53. Read Increment Update v = n v += 1 n = v n = 2 n = 2 n = 3 Friday, November 5, 2010
  • 54. Thread 1 Thread 2 Friday, November 5, 2010
  • 55. Read Read Thread 1 Thread 2 Increment Increment Update Update Friday, November 5, 2010
  • 56. Read Read Thread 1 Thread 2 Increment Increment Update Update n = 2 n = 3 Friday, November 5, 2010
  • 57. Solutions Friday, November 5, 2010
  • 58. Locking Friday, November 5, 2010
  • 59. Mutex n = 0 mutex = Mutex.new def increment(v) v + 1 end 2.times do Thread.new { 1_000_000.times { mutex.synchronize { n = increment(n) } } } end Friday, November 5, 2010
  • 60. Mutex n = 0 mutex = Mutex.new def increment(v) v + 1 end 2.times do Thread.new { 1_000_000.times { mutex.synchronize { n = increment(n) } } } end Friday, November 5, 2010
  • 61. Friday, November 5, 2010
  • 62. Mutex_m require 'mutex_m' class Tenderlove include Mutex_m end n = 0 mutex = Tenderlove.new mutex.synchronize { ... } Friday, November 5, 2010
  • 63. Conditional Variable Friday, November 5, 2010
  • 64. mutex = Mutex.new resource = ConditionVariable.new a = Thread.new { mutex.synchronize { puts "hello" resource.wait(mutex) puts "world" } } b = Thread.new { mutex.synchronize { puts "hello1" sleep 1 resource.signal } } a.join b.join Friday, November 5, 2010
  • 65. mutex = Mutex.new resource = ConditionVariable.new a = Thread.new { mutex.synchronize { puts "hello" resource.wait(mutex) puts "world" } } b = Thread.new { mutex.synchronize { puts "hello1" sleep 1 resource.signal } } a.join b.join Friday, November 5, 2010
  • 66. mutex = Mutex.new resource = ConditionVariable.new a = Thread.new { mutex.synchronize { puts "hello" resource.wait(mutex) puts "world" } } b = Thread.new { mutex.synchronize { puts "hello1" sleep 1 resource.signal } } a.join b.join Friday, November 5, 2010
  • 67. Friday, November 5, 2010
  • 68. Thread Safe Objects Friday, November 5, 2010
  • 69. Queue queue = Queue.new [ Thread.new { 100.times { queue << "omg!" } }, Thread.new { 100.times { queue << "omgagain!" } }, ].each { |t| t.join } Friday, November 5, 2010
  • 70. SizedQueue Friday, November 5, 2010
  • 71. Iterators Friday, November 5, 2010
  • 72. Internal Friday, November 5, 2010
  • 73. %w{ a b c d e }.each do ... ... end Friday, November 5, 2010
  • 74. %w{ a b c d e }.each do ... ... end Friday, November 5, 2010
  • 75. External Friday, November 5, 2010
  • 76. list = %w{ a b } iter = Enumerator.new(list) iter.next # => a iter.next # => b iter.next # raises StopIteration Friday, November 5, 2010
  • 77. list = %w{ a b } iter = Enumerator.new(list) begin 3.times do iter.next end rescue StopIteration => e p e.result end Friday, November 5, 2010
  • 78. list = %w{ a b } iter = Enumerator.new(list) begin 3.times do iter.next end rescue StopIteration => e p e.result # => ["a", "b"] end Friday, November 5, 2010
  • 79. External => Internal Friday, November 5, 2010
  • 80. list = %w{ a b } iter = Enumerator.new(list) iter.each do |thing| p thing end Friday, November 5, 2010
  • 81. list = %w{ a b } iter = Enumerator.new(list) iter.each do |thing| p thing end Friday, November 5, 2010
  • 82. Specify a Method Friday, November 5, 2010
  • 83. list = %w{ a b } iter = Enumerator.new(list, :map) x = iter.each do |thing| thing + " hello!" end p x Friday, November 5, 2010
  • 84. list = %w{ a b } iter = Enumerator.new(list, :map) x = iter.each do |thing| thing + " hello!" end p x # => ["a hello!", "b hello!"] Friday, November 5, 2010
  • 85. list = %w{ a b } iter = Enumerator.new(list, :map) x = iter.each_with_index do |thing, i| thing + ":#{i}" end p x Friday, November 5, 2010
  • 86. list = %w{ a b } iter = Enumerator.new(list, :map) x = iter.each_with_index do |thing, i| thing + ":#{i}" end p x # => ["a:0", "b:1"] Friday, November 5, 2010
  • 87. DRY it up Friday, November 5, 2010
  • 88. list = %w{ a b } iter = list.enum_for(:each) 3.times do p iter.next end Friday, November 5, 2010
  • 89. list = %w{ a b } iter = list.each 3.times do p itr.next end Friday, November 5, 2010
  • 90. list = %w{ a b } list.map.each_with_index { |obj, i| "#{obj} => #{i}" } Friday, November 5, 2010
  • 91. list = %w{ a b } list.map.each_with_index { |obj, i| "#{obj} => #{i}" } # => ["a => 0", "b => 1"] Friday, November 5, 2010
  • 92. Fun with Iterators! Friday, November 5, 2010
  • 93. Parallel Iteration Friday, November 5, 2010
  • 94. a = %w{ a b c d } b = %w{ a b c d } iter = a.each b.all? { |v| iter.next == v } Friday, November 5, 2010
  • 95. Iteration Strategy Friday, November 5, 2010
  • 96. Tree Node NodeNode NodeNode Friday, November 5, 2010
  • 97. Node class Node < Struct.new(:children) def initialize(children = []) super end end Friday, November 5, 2010
  • 98. Bottom Up class DepthFirst < Struct.new(:tree) def each(&block) iterate(tree, block) end private def iterate(node, block) node.children.each { |n| iterate(n, block) } block.call node end end Friday, November 5, 2010
  • 99. Node NodeNode NodeNode Bottom Up Node NodeNode NodeNode Friday, November 5, 2010
  • 100. Node NodeNode NodeNode Bottom Up Node NodeNode NodeNode Friday, November 5, 2010
  • 101. Top Down class TopDown < Struct.new(:tree) def each(&block) iterate(tree, block) end private def iterate(node, block) block.call node node.children.each { |n| iterate(n, block) } end end Friday, November 5, 2010
  • 102. Node NodeNode NodeNode Top Down Node NodeNode NodeNode Friday, November 5, 2010
  • 103. Node NodeNode NodeNode Top Down Node NodeNode NodeNode Friday, November 5, 2010
  • 104. Node class Node < Struct.new(:children) def initialize(children = []) super end def each(&block) return enum_for(:each) unless block_given? DepthFirst.new(self).each(&block) end end Friday, November 5, 2010
  • 105. Parallel Iteration iter = tree1.each tree2.all? { |node| node == iter.next } Friday, November 5, 2010
  • 106. To Infinity, and Beyond! Friday, November 5, 2010
  • 107. Infinite Series n → ∞ Friday, November 5, 2010
  • 108. class Infinity include Enumerable def each return enum_for(:each) unless block_given? i = 0 loop do yield i i += 1 end end end Friday, November 5, 2010
  • 109. Friday, November 5, 2010
  • 110. infinity = Enumerator.new do |yielder| i = 0 loop do yielder << i i += 1 end end Friday, November 5, 2010
  • 111. infinity = Enumerator.new do |yielder| i = 0 loop do yielder << i i += 1 end end Friday, November 5, 2010
  • 112. Friday, November 5, 2010
  • 113. π Pi Friday, November 5, 2010
  • 114. Mādhavan of Sangamagrāmam Friday, November 5, 2010
  • 115. Friday, November 5, 2010
  • 116. pi = Enumerator.new do |yielder| root_12 = Math.sqrt(12) pi = 0 infinity.each do |k| pi += (-1 / 3.0) ** k / (2 * k + 1).to_f yielder << (root_12 * pi) end end Friday, November 5, 2010
  • 117. pi = Enumerator.new do |yielder| root_12 = Math.sqrt(12) pi = 0 infinity.each do |k| pi += (-1 / 3.0) ** k / (2 * k + 1).to_f yielder << (root_12 * pi) end end Friday, November 5, 2010
  • 118. Friday, November 5, 2010
  • 119. Generators Friday, November 5, 2010
  • 120. Iterator.is_a? Generator Friday, November 5, 2010
  • 121. Generator Client Friday, November 5, 2010
  • 122. Generator Client Value Friday, November 5, 2010
  • 123. Fibers Friday, November 5, 2010
  • 124. Abstract Methods Friday, November 5, 2010
  • 125. method = Proc.new { ... } method.call # => "hello" method.call # => "world" method.call # => "how are you?" Friday, November 5, 2010
  • 126. method = Proc.new { ... } method.call('1') # => "1: hello" method.call('2') # => "2: world" method.call('3') # => "3: how are you?" Friday, November 5, 2010
  • 127. Proc => Fiber Friday, November 5, 2010
  • 128. call => resume Friday, November 5, 2010
  • 129. method = Proc.new { ... } method.call('1') # => "1: hello" method.call('2') # => "2: world" method.call('3') # => "3: how are you?" Friday, November 5, 2010
  • 130. method = Fiber.new { ... } method.resume('1') # => "1: hello" method.resume('2') # => "2: world" method.resume('3') # => "3: how are you?" Friday, November 5, 2010
  • 131. Arbitrary Exits Friday, November 5, 2010
  • 132. method = Fiber.new do Fiber.yield "hello" Fiber.yield "world" end method.resume # => "hello" method.resume # => "world" method.resume # => nil method.resume # => (FiberError) Friday, November 5, 2010
  • 133. Accept Parameters Friday, November 5, 2010
  • 134. method = Fiber.new do |val| val = Fiber.yield "#{val}: hello" val = Fiber.yield "#{val}: world" val end method.resume(1) # => "1: hello" method.resume(2) # => "2: world" method.resume(3) # => 3 method.resume(4) # => (FiberError) Friday, November 5, 2010
  • 135. method = Fiber.new do |val| val = Fiber.yield "#{val}: hello" val = Fiber.yield "#{val}: world" val end method.resume(1) # => "1: hello" method.resume(2) # => "2: world" method.resume(3) # => 3 method.resume(4) # => (FiberError) Friday, November 5, 2010
  • 136. method = Fiber.new do |val| val = Fiber.yield "#{val}: hello" val = Fiber.yield "#{val}: world" val end method.resume(1) # => "1: hello" method.resume(2) # => "2: world" method.resume(3) # => 3 method.resume(4) # => (FiberError) Friday, November 5, 2010
  • 137. First "resume" is the block argument Friday, November 5, 2010
  • 138. method = Fiber.new do |val| val = Fiber.yield "#{val}: hello" val = Fiber.yield "#{val}: world" val end method.resume(1) # => "1: hello" method.resume(2) # => "2: world" method.resume(3) # => 3 method.resume(4) # => (FiberError) Friday, November 5, 2010
  • 139. The rest are returned by Fiber.yield Friday, November 5, 2010
  • 140. method = Fiber.new do |val| val = Fiber.yield "#{val}: hello" val = Fiber.yield "#{val}: world" val end method.resume(1) # => "1: hello" method.resume(2) # => "2: world" method.resume(3) # => 3 method.resume(4) # => (FiberError) Friday, November 5, 2010
  • 141. Cool story bro Friday, November 5, 2010
  • 142. Friday, November 5, 2010
  • 143. Callbacks -> FSM Friday, November 5, 2010
  • 144. YAML because XML is boring Friday, November 5, 2010
  • 145. YAML yes, I wrote nokogiri. :-P Friday, November 5, 2010
  • 146. Psych Ruby 1.9.2 Only Friday, November 5, 2010
  • 147. class Foo < Psych::Handler def start_document(...) ... end def end_document(...) ... end end SAX Style Handler Friday, November 5, 2010
  • 148. Event Handler class EventHandler def initialize(fiber) @fiber = fiber end def method_missing(name, *args) @fiber.resume(name, args) end end Friday, November 5, 2010
  • 149. fiber = Fiber.new do |method, args| stack = [] loop do case method when :start_mapping stack << [] when :end_mapping h = Hash[*stack.pop] if stack.empty? p h else stack.last << h end when :scalar stack.last << args.first end method, args = Fiber.yield end end Friday, November 5, 2010
  • 150. case method when :start_mapping stack << [] when :end_mapping h = Hash[*stack.pop] if stack.empty? stdout.resume h else stack.last << h end when :scalar stack.last << args.first end method, args = Fiber.yield Friday, November 5, 2010
  • 151. StdOut Fiber stdout = Fiber.new do |obj| loop do p obj obj = Fiber.yield end end Friday, November 5, 2010
  • 152. Tied Together parser = Psych::Parser.new EventHandler.new fiber parser.parse(<<-eoyaml) --- - foo: { fiz: buzz } - bar: { fiz: buzz } - baz: { fiz: buzz } eoyaml Friday, November 5, 2010
  • 153. Friday, November 5, 2010
  • 154. Filtering Results Friday, November 5, 2010
  • 155. Foo Filter foo_filter = Fiber.new do |hash| loop do stdout.resume hash if hash.key? 'foo' hash = Fiber.yield end end Friday, November 5, 2010
  • 156. Output {"foo"=>{"fiz"=>"buzz"}} Friday, November 5, 2010
  • 157. Scheduling Threads Without Threads Friday, November 5, 2010
  • 158. P1 P2 Processes Friday, November 5, 2010
  • 159. P1 P2 Processes fopen() fread() fseek() fopen() fopen() Friday, November 5, 2010
  • 160. Simple Example Friday, November 5, 2010
  • 161. Producer producer = Fiber.new do loop do 5.times do |i| queue << "hello :#{i}" end Fiber.yield end end Friday, November 5, 2010
  • 162. Consumer hungry = Fiber.new do loop do while !queue.empty? puts queue.pop end Fiber.yield end end Friday, November 5, 2010
  • 163. Scheduler fibers = [producer, hungry] loop do fibers.each do |fiber| fiber.resume end end Friday, November 5, 2010
  • 164. Slow Consumer slow = Fiber.new do loop do while !queue.empty? sleep 1 puts "########### slow: " + queue.pop Fiber.yield end Fiber.yield end end Friday, November 5, 2010
  • 165. Random Scheduler fibers = [producer, hungry, slow] loop do fibers.sort_by { rand }.each do |fiber| fiber.resume end end Friday, November 5, 2010
  • 166. Friday, November 5, 2010
  • 167. "Processes" •Anonymous •We control when to "give up" Friday, November 5, 2010
  • 168. Homework •Favor fast processes •Favor queue fillers •Favor queue drainers •Deal with multiple queues Friday, November 5, 2010
  • 169. Generators The Fiber Edition Friday, November 5, 2010
  • 170. infinity = Fiber.new do i = 0 loop do Fiber.yield i i += 1 end end Friday, November 5, 2010
  • 171. infinity = Enumerator.new do |yielder| i = 0 loop do yielder << i i += 1 end end Friday, November 5, 2010
  • 172. Our Own Enumerator Friday, November 5, 2010
  • 173. class SimpleEnum def initialize &block @fiber = Fiber.new do block.call(self) end end def << value Fiber.yield value end def next @fiber.resume end end Friday, November 5, 2010
  • 174. infinity = SimpleEnum.new do |yielder| i = 0 loop do yielder << i i += 1 end end Friday, November 5, 2010
  • 175. •Capture return value •Add StopIteration Exception Homework Friday, November 5, 2010
  • 176. Coroutines Friday, November 5, 2010
  • 177. Fiber implements Coroutine Friday, November 5, 2010
  • 178. Coroutine Client Value Friday, November 5, 2010
  • 179. Coroutine Client Value Friday, November 5, 2010
  • 180. Pipelines Friday, November 5, 2010
  • 181. Coroutine CoroutineGenerator Friday, November 5, 2010
  • 182. Coroutine CoroutineGenerator Friday, November 5, 2010
  • 183. Our Friend, Infinity infinity = Fiber.new do i = 0 loop do Fiber.yield i i += 1 end end Friday, November 5, 2010
  • 184. Even Numbers evens = Fiber.new do loop do value = infinity.resume Fiber.yield value if value % 2 == 0 end end Friday, November 5, 2010
  • 185. Friday, November 5, 2010
  • 186. Three's threes = Fiber.new do loop do value = evens.resume Fiber.yield value if value % 3 == 0 end end Friday, November 5, 2010
  • 187. Three's threes = Fiber.new do loop do value = evens.resume Fiber.yield value if value % 3 == 0 end end Friday, November 5, 2010
  • 188. Friday, November 5, 2010
  • 189. Abstraction Friday, November 5, 2010
  • 190. Common Elements •Source •Sink •Runloop •Work Friday, November 5, 2010
  • 191. class Pipe < Struct.new(:source) def initialize(source = nil) super @fiber = Fiber.new { self.loop } end def loop while value = read process value end end def read; source.resume end def write(value); Fiber.yield(value) end def process(value); write(value) end def resume; @fiber.resume end end Friday, November 5, 2010
  • 192. class Infinity < Pipe def loop i = 0 while true write i i += 1 end end end Infinity (again) Friday, November 5, 2010
  • 193. Evens class Evens < Pipe def process(value) super if value % 2 == 0 end end Friday, November 5, 2010
  • 194. StdOut class StdOut < Pipe def write value puts value end end Friday, November 5, 2010
  • 195. Connection infinity = Infinity.new even = Evens.new infinity stdout = StdOut.new even stdout.resume Friday, November 5, 2010
  • 196. Pretty Syntax class Pipe def |(other) other.source = self other end end Friday, November 5, 2010
  • 197. Connection (Infinity.new | Evens.new | StdOut.new).resume Friday, November 5, 2010
  • 198. Producer / Consumer Friday, November 5, 2010
  • 199. ERb Friday, November 5, 2010
  • 200. Compiled Template template = ERB.new('<%= "hello" %>') puts template.src Friday, November 5, 2010
  • 201. Compiled Template #coding:US-ASCII _erbout = ''; _erbout.concat(( "hello" ).to_s); _erbout.force_encoding(__ENCODING__) Friday, November 5, 2010
  • 202. Redirect Output Friday, November 5, 2010
  • 203. Compiled Template erb = ERB.new('<%= "hello" %>', nil, nil, 'self') puts erb.src Friday, November 5, 2010
  • 204. Compiled Template #coding:US-ASCII self = ''; self.concat(( "hello" ).to_s); self.force_encoding(__ENCODING__) Friday, November 5, 2010
  • 205. Compiled Template #coding:US-ASCII self = ''; self.concat(( "hello" ).to_s); self.force_encoding(__ENCODING__) Friday, November 5, 2010
  • 206. Monkey Patch! class ERB::Compiler def pre_cmd= x; end end erb = ERB.new('<%= "hello" %>', nil, nil, 'self') puts erb.src Friday, November 5, 2010
  • 207. Compiled Source #coding:US-ASCII self.concat(( "hello" ).to_s); self.force_encoding(__ENCODING__) Friday, November 5, 2010
  • 208. ERb Pipe Friday, November 5, 2010
  • 209. ERb Pipe class PipERB < Pipe def initialize data super() @erb = ERB.new(data, nil, nil, 'self') end alias :concat :process def read; @erb.result(binding) end def force_encoding encoding; end end Friday, November 5, 2010
  • 210. Pipe to StdOut (PipERB.new("<%= 'hello' %>") | StdOut.new).resume Friday, November 5, 2010
  • 211. ERb Pipe + Rack Friday, November 5, 2010
  • 212. Slow Template <ul> <% a = b = 1 %> <% 10.times do %> <li><%= a %></li> <% sleep(1) # simulate work %> <% a, b = b, a + b %> <% end %> </ul> Friday, November 5, 2010
  • 213. Normal Handler class ERBHandler def initialize @fib_template = DATA.read end def call env result = [ ERB.new(@fib_template).result(binding) ] [ 200, {'X-Hello' => 'World'}, result ] end end Friday, November 5, 2010
  • 214. Friday, November 5, 2010
  • 215. Rack API Demands "each" Friday, November 5, 2010
  • 216. Each Pipe class Each < Pipe def each(&block) @block = block resume end def process(value) @block.call(value) end end Friday, November 5, 2010
  • 217. Each Pipe (PipERB.new(DATA.read) | Each.new).each do |chunk| print chunk end __END__ <ul> <% a = b = 1 %> <% 10.times do %> <li><%= a %></li> <% sleep 1; a, b = b, a + b %> <% end %> </ul> Friday, November 5, 2010
  • 218. Each Pipe (PipERB.new(DATA.read) | Each.new).each do |chunk| print chunk end __END__ <ul> <% a = b = 1 %> <% 10.times do %> <li><%= a %></li> <% sleep 1; a, b = b, a + b %> <% end %> </ul> Friday, November 5, 2010
  • 219. Fiber Handler class ERBHandler def initialize @fib_template = DATA.read end def call env [ 200, {}, (PipERB.new(@fib_template) | Each.new) ] end end Friday, November 5, 2010
  • 220. Friday, November 5, 2010
  • 221. Cooperative Scheduling Friday, November 5, 2010
  • 222. ERb Rack Friday, November 5, 2010
  • 223. Caveats? Friday, November 5, 2010
  • 224. Conclusion Friday, November 5, 2010
  • 225. Two Pipelines Friday, November 5, 2010
  • 226. Real Life? Friday, November 5, 2010
  • 227. Fibers are Interesting! Friday, November 5, 2010
  • 228. Concurrency is Interesting Friday, November 5, 2010
  • 229. But it requires a shift in thinking Friday, November 5, 2010
  • 230. Install Ruby 1.9.2 Friday, November 5, 2010
  • 231. Play with this at home! Friday, November 5, 2010
  • 232. Questions? Friday, November 5, 2010
  • 233. Friday, November 5, 2010

×