SlideShare a Scribd company logo
1 of 37
Integrating Asynchronous IO with
     your Synchronous stack




            Like a boss
Nolan Evans
- Software Engineer @Square
- Enjoys coding
- Fan of silly hats


    github: nolman
    twitter @nolman
    www.nolanevans.com
Outline
•   What problem are we trying to solve?
•   Consider other approaches
•   Put together the pieces of Goliath
      - EventMachine
      - Fibers
•   Example Goliath apps
•   Integrating with your existing stack
User Experience Impacting
     External Services
   •   Real time feedback required
   •   Dependency on external systems
   •   Outages should not impact other systems
Link Scraping
Credit Card Processing
Publishing
Mash Ups
Why not your normal Rails?

           •   External Services can will be slow
           •   Typical Rails stack is blocking/single threaded
           •   Passengers back up on blocking requests
           •   All Passengers blocked = 503 Service Unavailable
Why not background Workers & Polling?
                  •   Communication overhead
                  •   Polling overhead
                  •   Typical workers still blocking/single threaded
                  •   Memory footprint
Why Asynchronous IO works
           •   Continue to process incoming requests when
               external services are slow
           •   No cross processes communication (vs workers)
           •   Increased throughput
           •   Low memory footprint
           •   Fault tolerance
           •   Better resource utilization
How does Asynchronous IO work?
            Evented IO uses the Reactor Pattern
            nginx
            node.js
            varnish
            EventMachine
            Twisted
            Your Browser
How EventMachine Works
while (true) {
 _UpdateTime();
 _RunTimers();

    _AddNewDescriptors();
    _ModifyDescriptors();

    _RunOnce();
    if (bTerminateSignalReceived)
      break;
}




                            http://github.com/eventmachine/eventmachine
_RunOnce();
•   Find time until next timer event
•   Runs select, epoll(linux), or kqueue(bsd)
       select - check all file descriptors for changes
       epoll - multiplexing I/O
       Create via epoll_create
       Register interest via epoll_ctl
       Wait for input with epoll_wait get list of descriptors that changed
•   Run associated callbacks
•   epoll and kqueue are generally more performant
Downsides of Asynchronous IO
            •   Confusing control flow
            •   Error handling not obvious
            •   Need to spin up a reactor to run tests
            •   Blocking calls block the entire reactor
Callback Spaghetti
EventMachine.run do
 http = EM::HttpRequest.new('http://www.google.com').get
 begin
  puts "Before"
  http.callback {
    raise "Stuff Happens"
  }
  puts "After"
 rescue Exception => ex
  puts "Rescued!"
 end
 puts "All Done?"
end



                          code at: https://gist.github.com/
Callback Spaghetti
EventMachine.run do
 http = EM::HttpRequest.new('http://www.google.com').get
 begin
  puts "Before"
  http.callback {                                  Prints:
    raise "Stuff Happens"
    raise "Stuff Happens"                          Before
  }                                                After
  puts "After"                                     All Done?
 rescue Exception => ex                            #Stuff Happens (RuntimeError)
  puts "Rescued!"
 end
 puts "All Done?"
end



                          code at: https://gist.github.com/
Fibers
   •   Developer scheduled threads
   •   Lets you pause/resume execution of code
   •   Cooperative scheduling
   •   Only one executing at a time
   •   No semaphores needed
   •   Can make asynchronous code quack like
       synchronous code
Fibers
fiber = Fiber.new do
 puts 'inside the fiber'
 Fiber.yield 1 #Yields control back out to the root fiber
 puts 'after yield'
 2
end

puts   "before starting the fiber"
puts   fiber.resume # Initially Starts the fiber
puts   "we have control again"
puts   fiber.resume # Returns control back to the fiber
puts   "Done!"
Fibers
fiber = Fiber.new do
 puts 'inside the fiber'
 Fiber.yield 1 #Yields control back out to the root fiber
 puts 'after yield'
 2                                                         Prints:
end                                                        before starting the fiber
                                                           inside the fiber
puts   "before starting the fiber"                          1
puts   fiber.resume # Initially Starts the fiber
                                                           we have control again
puts   "we have control again"
puts   fiber.resume # Returns control back to the fiber      after yield
puts   "Done!"                                             2
                                                           Done!
Asynchronous Code with Fibers
EventMachine.run do
 def syncify(url)
   fiber = Fiber.current
   http = EM::HttpRequest.new(url).get
   http.callback { fiber.resume(http) }
   Fiber.yield
 end
 Fiber.new {
   begin
    puts "Before"
    http = syncify("http://www.google.com")
    puts "After"
    raise "Stuff Happens"
   rescue Exception => ex
    puts "Rescued!"
   end
   puts "All Done?"
 }.resume
end
                               code at: https://gist.github.com/
Asynchronous Code with Fibers
EventMachine.run do
 def syncify(url)
   fiber = Fiber.current
   http = EM::HttpRequest.new(url).get                             Prints:
   http.callback { fiber.resume(http) }
   Fiber.yield
                                                                   Before
 end                                                               After
 Fiber.new {                                                       Rescued!
   begin                                                           All Done?
    puts "Before"
    http = syncify("http://www.google.com")
    puts "After"
    raise "Stuff Happens"
   rescue Exception => ex
    puts "Rescued!"
   end
   puts "All Done?"
 }.resume
end
                               code at: https://gist.github.com/
Async IO with Fibers vs Threads
             Pros
             •   Many Ruby libraries are not Thread Safe
             •   Creating fibers is cheap & fast
             •   Getting Semaphores right isn’t easy
             •   Writing tests for semaphores is tough
             •   Cooperative scheduling is better then round robin


             Cons
             •   Blocking the reactor will stop all other processing
Goliath
                      •   An Asynchronous Web Framework
                      •   Written by PostRank
                      •   Rack compatible(ish)
                      •   Powered by EventMachine
                      •   Every request run inside a fiber
                      •   It’s fast! (3000 requests/second)




http://postrank-labs.github.com/
XML as JSON proxy

•   Same Origin Policy restricts XMLHttpRequest
•   JSONP lets us get around same origin policy
•   External Service has to implement the JSONP api
•   Many sites/services do not have a JSON nevermind JSONP api
•   Use Goliath to convert XML to JSON
XML as JSON proxy
class XmlAsJsonProxy < Goliath::API
 use Goliath::Rack::Params         # parse query & body params
 use Goliath::Rack::Formatters::JSON # JSON output formatter
 use Goliath::Rack::Render         # auto-negotiate response format

 def response(env)
  http = EM::HttpRequest.new(params['url']).get(:redirects => 1)
  converter = DocumentConverter.new(http.response, params['mapping'])
  [200, {'X-Goliath' => 'Proxy', 'Content-Type' => 'application/json'},
converter.mapping_to_json.merge(:redirected_to => http.last_effective_url)]
 end
end




                         code at: https://www.github.com/nolman/proxy_service
Link Scraping
Link Scraping
$.getJSON("/proxies/as_json?url=http://squareup.com",
       {'mapping': {
          'images[]': {'path': 'img[@src]', 'attribute': 'src'},
          'title': {'path': 'title'},
          'description': {'path': 'meta[@name='description'], :attribute:'content'}
          }
       }, function(data){
          //present data to user
       });
Link Scraping
$.getJSON("/proxies/as_json?url=http://squareup.com",
       {'mapping': {
          'images[]': {'path': 'img[@src]', 'attribute': 'src'},
          'title': {'path': 'title'},
          'description': {'path': 'meta[@name='description'], :attribute:'content'}
          }
       }, function(data){
          //present data to user
       });

//Response from Goliath
{
 'images':['/image.png', ...],
 'title':'Square',
 'description':'Accept credit card payments anywhere with your iPhone, iPad or Android phone.',
 'redirected_to':'https://squareup.com/'
}
Mashups




https://gist.github.com/1068959#file_mashup.html
http://stark-frost-922.heroku.com/
Mashups
$.getJSON("/proxies/as_json?url=http://sfbay.craigslist.org/sfc/apa/",
       {'mapping': {
         'link[]':{'path':'.//blockquote/p/a', 'attribute': 'href'}
         }
       }, function(links_response){
         $.each(links_response.link, function(index, value){
           $.getJSON("/proxies/as_json", {'url':value, 'mapping':{'address[]':{'path':'.//comment()'}}},
function(address_info){
             //display mashup
           });
         });
       });




                             https://gist.github.com/1068959#file_mashup.html
                             http://stark-frost-922.heroku.com/
Integrating Goliath with external
 services and our existing stack


       •   Have Goliath Proxy Requests
       •   Forward the response to our stack
Browser                               Goliath                                  Web   Rails

   GET http://foo.com/?
   url=http://github.com/users/fred
   forward_to=http://foo.com/render         GET http://github.com/users/fred




                                                 <xml><name>fred...




                                             POST http://foo.com/render
                                             body=<xml><name>fred...



                                                <div>Welcome fred ... </div>


    <div>Welcome fred ... </div>
Forwarding Proxy
class ForwardProxy < Goliath::API
 use Goliath::Rack::Params        # parse query & body params
 use Goliath::Rack::Render        # auto-negotiate response format

 def response(env)
   http = EM::HttpRequest.new(params['url']).get(:redirects => 1)
   http = EM::HttpRequest.new(params['forward_to']).post(:body => {:document =>
http.response})
   [http.response_header.status, http.response_header, http.response]
 end
end




                         code at: https://www.github.com/nolman/proxy_service
Rack Routes
class ProxyServer < Goliath::API
 use Goliath::Rack::Params         # parse query & body params
 use Goliath::Rack::Render         # auto-negotiate response format

 map "/forward" do
  run ForwardProxy.new
 end

 map "/as_json" do
  run XmlAsJsonProxy.new
 end

end




                          code at: https://www.github.com/nolman/proxy_service
Fin
•   Have an idea how Goliath works
      - EventMachine
      - Fibers
•   Advantages of Asynchronous IO
•   Basic Goliath App
•   You should try Goliath
Any Questions?


          github: nolman
          twitter @nolman
          www.nolanevans.com

More Related Content

Recently uploaded

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsMark Billinghurst
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Mattias Andersson
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionDilum Bandara
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsRizwan Syed
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenHervé Boutemy
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 

Recently uploaded (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Human Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR SystemsHuman Factors of XR: Using Human Factors to Design XR Systems
Human Factors of XR: Using Human Factors to Design XR Systems
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?Are Multi-Cloud and Serverless Good or Bad?
Are Multi-Cloud and Serverless Good or Bad?
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Advanced Computer Architecture – An Introduction
Advanced Computer Architecture – An IntroductionAdvanced Computer Architecture – An Introduction
Advanced Computer Architecture – An Introduction
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Scanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL CertsScanning the Internet for External Cloud Exposures via SSL Certs
Scanning the Internet for External Cloud Exposures via SSL Certs
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
DevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache MavenDevoxxFR 2024 Reproducible Builds with Apache Maven
DevoxxFR 2024 Reproducible Builds with Apache Maven
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 

Featured

Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 

Featured (20)

Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 

Ruby Meetup - Goliath - August 24th 2011

  • 1. Integrating Asynchronous IO with your Synchronous stack Like a boss
  • 2. Nolan Evans - Software Engineer @Square - Enjoys coding - Fan of silly hats github: nolman twitter @nolman www.nolanevans.com
  • 3. Outline • What problem are we trying to solve? • Consider other approaches • Put together the pieces of Goliath - EventMachine - Fibers • Example Goliath apps • Integrating with your existing stack
  • 4. User Experience Impacting External Services • Real time feedback required • Dependency on external systems • Outages should not impact other systems
  • 9. Why not your normal Rails? • External Services can will be slow • Typical Rails stack is blocking/single threaded • Passengers back up on blocking requests • All Passengers blocked = 503 Service Unavailable
  • 10. Why not background Workers & Polling? • Communication overhead • Polling overhead • Typical workers still blocking/single threaded • Memory footprint
  • 11. Why Asynchronous IO works • Continue to process incoming requests when external services are slow • No cross processes communication (vs workers) • Increased throughput • Low memory footprint • Fault tolerance • Better resource utilization
  • 12. How does Asynchronous IO work? Evented IO uses the Reactor Pattern nginx node.js varnish EventMachine Twisted Your Browser
  • 13. How EventMachine Works while (true) { _UpdateTime(); _RunTimers(); _AddNewDescriptors(); _ModifyDescriptors(); _RunOnce(); if (bTerminateSignalReceived) break; } http://github.com/eventmachine/eventmachine
  • 14. _RunOnce(); • Find time until next timer event • Runs select, epoll(linux), or kqueue(bsd) select - check all file descriptors for changes epoll - multiplexing I/O Create via epoll_create Register interest via epoll_ctl Wait for input with epoll_wait get list of descriptors that changed • Run associated callbacks • epoll and kqueue are generally more performant
  • 15. Downsides of Asynchronous IO • Confusing control flow • Error handling not obvious • Need to spin up a reactor to run tests • Blocking calls block the entire reactor
  • 16. Callback Spaghetti EventMachine.run do http = EM::HttpRequest.new('http://www.google.com').get begin puts "Before" http.callback { raise "Stuff Happens" } puts "After" rescue Exception => ex puts "Rescued!" end puts "All Done?" end code at: https://gist.github.com/
  • 17. Callback Spaghetti EventMachine.run do http = EM::HttpRequest.new('http://www.google.com').get begin puts "Before" http.callback { Prints: raise "Stuff Happens" raise "Stuff Happens" Before } After puts "After" All Done? rescue Exception => ex #Stuff Happens (RuntimeError) puts "Rescued!" end puts "All Done?" end code at: https://gist.github.com/
  • 18. Fibers • Developer scheduled threads • Lets you pause/resume execution of code • Cooperative scheduling • Only one executing at a time • No semaphores needed • Can make asynchronous code quack like synchronous code
  • 19. Fibers fiber = Fiber.new do puts 'inside the fiber' Fiber.yield 1 #Yields control back out to the root fiber puts 'after yield' 2 end puts "before starting the fiber" puts fiber.resume # Initially Starts the fiber puts "we have control again" puts fiber.resume # Returns control back to the fiber puts "Done!"
  • 20. Fibers fiber = Fiber.new do puts 'inside the fiber' Fiber.yield 1 #Yields control back out to the root fiber puts 'after yield' 2 Prints: end before starting the fiber inside the fiber puts "before starting the fiber" 1 puts fiber.resume # Initially Starts the fiber we have control again puts "we have control again" puts fiber.resume # Returns control back to the fiber after yield puts "Done!" 2 Done!
  • 21. Asynchronous Code with Fibers EventMachine.run do def syncify(url) fiber = Fiber.current http = EM::HttpRequest.new(url).get http.callback { fiber.resume(http) } Fiber.yield end Fiber.new { begin puts "Before" http = syncify("http://www.google.com") puts "After" raise "Stuff Happens" rescue Exception => ex puts "Rescued!" end puts "All Done?" }.resume end code at: https://gist.github.com/
  • 22. Asynchronous Code with Fibers EventMachine.run do def syncify(url) fiber = Fiber.current http = EM::HttpRequest.new(url).get Prints: http.callback { fiber.resume(http) } Fiber.yield Before end After Fiber.new { Rescued! begin All Done? puts "Before" http = syncify("http://www.google.com") puts "After" raise "Stuff Happens" rescue Exception => ex puts "Rescued!" end puts "All Done?" }.resume end code at: https://gist.github.com/
  • 23. Async IO with Fibers vs Threads Pros • Many Ruby libraries are not Thread Safe • Creating fibers is cheap & fast • Getting Semaphores right isn’t easy • Writing tests for semaphores is tough • Cooperative scheduling is better then round robin Cons • Blocking the reactor will stop all other processing
  • 24. Goliath • An Asynchronous Web Framework • Written by PostRank • Rack compatible(ish) • Powered by EventMachine • Every request run inside a fiber • It’s fast! (3000 requests/second) http://postrank-labs.github.com/
  • 25. XML as JSON proxy • Same Origin Policy restricts XMLHttpRequest • JSONP lets us get around same origin policy • External Service has to implement the JSONP api • Many sites/services do not have a JSON nevermind JSONP api • Use Goliath to convert XML to JSON
  • 26. XML as JSON proxy class XmlAsJsonProxy < Goliath::API use Goliath::Rack::Params # parse query & body params use Goliath::Rack::Formatters::JSON # JSON output formatter use Goliath::Rack::Render # auto-negotiate response format def response(env) http = EM::HttpRequest.new(params['url']).get(:redirects => 1) converter = DocumentConverter.new(http.response, params['mapping']) [200, {'X-Goliath' => 'Proxy', 'Content-Type' => 'application/json'}, converter.mapping_to_json.merge(:redirected_to => http.last_effective_url)] end end code at: https://www.github.com/nolman/proxy_service
  • 28. Link Scraping $.getJSON("/proxies/as_json?url=http://squareup.com", {'mapping': { 'images[]': {'path': 'img[@src]', 'attribute': 'src'}, 'title': {'path': 'title'}, 'description': {'path': 'meta[@name='description'], :attribute:'content'} } }, function(data){ //present data to user });
  • 29. Link Scraping $.getJSON("/proxies/as_json?url=http://squareup.com", {'mapping': { 'images[]': {'path': 'img[@src]', 'attribute': 'src'}, 'title': {'path': 'title'}, 'description': {'path': 'meta[@name='description'], :attribute:'content'} } }, function(data){ //present data to user }); //Response from Goliath { 'images':['/image.png', ...], 'title':'Square', 'description':'Accept credit card payments anywhere with your iPhone, iPad or Android phone.', 'redirected_to':'https://squareup.com/' }
  • 31. Mashups $.getJSON("/proxies/as_json?url=http://sfbay.craigslist.org/sfc/apa/", {'mapping': { 'link[]':{'path':'.//blockquote/p/a', 'attribute': 'href'} } }, function(links_response){ $.each(links_response.link, function(index, value){ $.getJSON("/proxies/as_json", {'url':value, 'mapping':{'address[]':{'path':'.//comment()'}}}, function(address_info){ //display mashup }); }); }); https://gist.github.com/1068959#file_mashup.html http://stark-frost-922.heroku.com/
  • 32. Integrating Goliath with external services and our existing stack • Have Goliath Proxy Requests • Forward the response to our stack
  • 33. Browser Goliath Web Rails GET http://foo.com/? url=http://github.com/users/fred forward_to=http://foo.com/render GET http://github.com/users/fred <xml><name>fred... POST http://foo.com/render body=<xml><name>fred... <div>Welcome fred ... </div> <div>Welcome fred ... </div>
  • 34. Forwarding Proxy class ForwardProxy < Goliath::API use Goliath::Rack::Params # parse query & body params use Goliath::Rack::Render # auto-negotiate response format def response(env) http = EM::HttpRequest.new(params['url']).get(:redirects => 1) http = EM::HttpRequest.new(params['forward_to']).post(:body => {:document => http.response}) [http.response_header.status, http.response_header, http.response] end end code at: https://www.github.com/nolman/proxy_service
  • 35. Rack Routes class ProxyServer < Goliath::API use Goliath::Rack::Params # parse query & body params use Goliath::Rack::Render # auto-negotiate response format map "/forward" do run ForwardProxy.new end map "/as_json" do run XmlAsJsonProxy.new end end code at: https://www.github.com/nolman/proxy_service
  • 36. Fin • Have an idea how Goliath works - EventMachine - Fibers • Advantages of Asynchronous IO • Basic Goliath App • You should try Goliath
  • 37. Any Questions? github: nolman twitter @nolman www.nolanevans.com

Editor's Notes

  1. \n
  2. \n
  3. \n
  4. \n
  5. \n
  6. \n
  7. \n
  8. \n
  9. \n
  10. \n
  11. \n
  12. \n
  13. \n
  14. \n
  15. \n
  16. So if we look at this code, we can see that we are requesting the document found on google.com, and lets say that there is some sort of problem parsing the dom so we raise an error stuff happens\n\n
  17. so surprisingly here&amp;#x2019;s what&amp;#x2019;s printed out when this code runs, the callback is executed outside of the context of the error handler and any exceptions raised are unhandled\n
  18. in ruby 1.9 fibers provide a way for us to untangle this callback spaghetti\n
  19. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  20. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  21. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  22. \n
  23. in ruby 1.9 fibers provide a way for us to untangle this callback spaghetti\n
  24. rack middleware\n
  25. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  26. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  27. for example facebook&amp;#x2019;s link scraper\n
  28. for example facebook&amp;#x2019;s link scraper\n
  29. for example facebook&amp;#x2019;s link scraper\n
  30. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  31. for example facebook&amp;#x2019;s link scraper\n
  32. This approach is useful for when you need to integrate external services with some part of your website/services user experience\n
  33. This approach is useful for when you need to integrate external services with some part of your website/services user experience\n
  34. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  35. so if we look at this code you will see we wrap the fetching of the document in a syncify function\n
  36. Talk about me\n
  37. right now our card auth&amp;#x2019;s happen in our passenger&amp;#x2019;s which are single threaded and blocking\nfibers would be a better solution to this problem and remove a point of failure from our systems\n