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

Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Patryk Bandurski
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersThousandEyes
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?XfilesPro
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...HostedbyConfluent
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 

Recently uploaded (20)

Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
Integration and Automation in Practice: CI/CD in Mule Integration and Automat...
 
Pigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food ManufacturingPigging Solutions in Pet Food Manufacturing
Pigging Solutions in Pet Food Manufacturing
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for PartnersEnhancing Worker Digital Experience: A Hands-on Workshop for Partners
Enhancing Worker Digital Experience: A Hands-on Workshop for Partners
 
How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?How to Remove Document Management Hurdles with X-Docs?
How to Remove Document Management Hurdles with X-Docs?
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
Transforming Data Streams with Kafka Connect: An Introduction to Single Messa...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

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