The document discusses using Ruby proxies with EventMachine to provide transparent scaling, performance improvements, and monitoring capabilities for web applications. Proxies can intercept, cache, and alter requests and responses to balance load across multiple application servers, simulate production traffic for staging environments, and benchmark performance. The EM-Proxy library provides an API and examples for building intercepting, transparent, and other types of proxies with EventMachine for networking applications in Ruby.
Ruby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.comIlya Grigorik
A high-performance proxy server is less than a hundred lines of Ruby code and it is an indispensable tool for anyone who knows how to use it. In this session we will first walk through the basics of event-driven architectures and high-performance network programming in Ruby using the EventMachine framework.
A look at the technologies and the architecture behind the emerging real-time web. We will discuss XMPP/Jabber and AMQP protocols and explore the advantages of each over the commonly used HTTP request-response cycle. As part of the workshop we will look at the available tools and libraries and work through simple examples of creating an event driven, real-time service.
Ruby Proxies for Scale, Performance, and Monitoring - GoGaRuCo - igvita.comIlya Grigorik
A high-performance proxy server is less than a hundred lines of Ruby code and it is an indispensable tool for anyone who knows how to use it. In this session we will first walk through the basics of event-driven architectures and high-performance network programming in Ruby using the EventMachine framework.
A look at the technologies and the architecture behind the emerging real-time web. We will discuss XMPP/Jabber and AMQP protocols and explore the advantages of each over the commonly used HTTP request-response cycle. As part of the workshop we will look at the available tools and libraries and work through simple examples of creating an event driven, real-time service.
Communication in Python and the C10k problemJose Galarza
Talk at the Codemotion Spain 2014 about how to handle communication (polling, long polling, websockets, SSE), concurrency (processes, threads, coroutines, green threads) and the C10K problem in python
No Callbacks, No Threads - RailsConf 2010Ilya Grigorik
Multi-threaded servers compete for the global interpreter lock (GIL) and incur the cost of continuous context switching, potential deadlocks, or plain wasted cycles. Asynchronous servers, on the other hand, create a mess of callbacks and errbacks, complicating the code. But, what if, you could get all the benefits of asynchronous programming, while preserving the synchronous look and feel of the code – no threads, no callbacks?
Scaling Ruby with Evented I/O - Ruby undergroundOmer Gazit
Ruby is considered by many to be slow and unscalable. In this talk we’ll try to disprove this premise by introducing EventMachine. We will cover the basic concepts of evented I/O programming and the Reactor pattern. Talk about best practices and useful libraries for EventMachine and see how to test your event driven code.
Code examples from the presentation can be found at: https://github.com/omerisimo/em_underground
Solving some of the scalability problems at booking.comIvan Kruglov
Booking.com uses Sereal in many applications. One of the biggest use case though is the events pipeline. It was built to delivery messages (events) from generation point to various processors in near real-time fashion. These days it servers billions of messages per day.
One of our processors recently faced scalability issues due to growth of the volume of delivered events.
In this talk I would like to share what problem we had, how we addressed it and which new features of Sereal helped us.
Faster PHP apps using Queues and WorkersRichard Baker
PHP apps typically perform tasks in a synchronous manner; Resizing an image or sending a push notification. For most applications this works well, but as apps grow or experience increased traffic, each task adds extra milliseconds to a request, leaving users waiting.
A common solution is to defer these tasks to the background using a cron task. However, there is a better way. Job queues not only help to decouple your application and improve resilience but will also cut request times.
In this talk I we’ll explore some common queue systems; the features and tradeoffs of each solution, what to queue, refactoring existing code into jobs, and running workers. By the end you’ll be ready to build your next app one job at a time.
Communication in Python and the C10k problemJose Galarza
Talk at the Codemotion Spain 2014 about how to handle communication (polling, long polling, websockets, SSE), concurrency (processes, threads, coroutines, green threads) and the C10K problem in python
No Callbacks, No Threads - RailsConf 2010Ilya Grigorik
Multi-threaded servers compete for the global interpreter lock (GIL) and incur the cost of continuous context switching, potential deadlocks, or plain wasted cycles. Asynchronous servers, on the other hand, create a mess of callbacks and errbacks, complicating the code. But, what if, you could get all the benefits of asynchronous programming, while preserving the synchronous look and feel of the code – no threads, no callbacks?
Scaling Ruby with Evented I/O - Ruby undergroundOmer Gazit
Ruby is considered by many to be slow and unscalable. In this talk we’ll try to disprove this premise by introducing EventMachine. We will cover the basic concepts of evented I/O programming and the Reactor pattern. Talk about best practices and useful libraries for EventMachine and see how to test your event driven code.
Code examples from the presentation can be found at: https://github.com/omerisimo/em_underground
Solving some of the scalability problems at booking.comIvan Kruglov
Booking.com uses Sereal in many applications. One of the biggest use case though is the events pipeline. It was built to delivery messages (events) from generation point to various processors in near real-time fashion. These days it servers billions of messages per day.
One of our processors recently faced scalability issues due to growth of the volume of delivered events.
In this talk I would like to share what problem we had, how we addressed it and which new features of Sereal helped us.
Faster PHP apps using Queues and WorkersRichard Baker
PHP apps typically perform tasks in a synchronous manner; Resizing an image or sending a push notification. For most applications this works well, but as apps grow or experience increased traffic, each task adds extra milliseconds to a request, leaving users waiting.
A common solution is to defer these tasks to the background using a cron task. However, there is a better way. Job queues not only help to decouple your application and improve resilience but will also cut request times.
In this talk I we’ll explore some common queue systems; the features and tradeoffs of each solution, what to queue, refactoring existing code into jobs, and running workers. By the end you’ll be ready to build your next app one job at a time.
Plack basics for Perl websites - YAPC::EU 2011leo lapworth
Run a website with Perl? - you should learn how to use Plack. Most Perl web frameworks support it and it makes your life a lot easier and a lot more fun
Foreman - Process manager for applications with multiple componentsStoyan Zhekov
Splitting an app up in different processes is great for performance and scalability. The downside, however, is that it becomes much more complicated to get the app and all of its parts running.
Foreman is an attempt to make this easier. Using foreman you can declare the various processes that are needed to run your application using a Procfile.
COMET is an upcoming method for delivering real-time interaction to a website by using server-push technologies. At the Snow Sprint 2008 Jean-Nicolas Bes and Ramon Bartl worked on making COMET work for the Open Source CMS Plone.
This is their presentation from the final sprint summary.
In order to understand how to scale Node.js you need to know how the internals work together and what type of problems are best suited for it. With the right combination of tools you can easily have a scalable and reliable Node.js cluster.
Understanding the Rails web model and scalability options.toster
Rails стал отличным ответом на требования многих лет опыта использования классической процессной модели веб-запросов. Такая модель все еще является наиболее надежной и простой для понимания и контроля. Но новое поколение высокодинамичных и интерактивных веб приложений требует принципиально новых требований к масштабированию. Одним из ответов на такие требования может стать сервис Pusher.com, который, в числе прочих вариантов решений, будет рассмотрен в этом докладе
Toster - Understanding the Rails Web Model and Scalability OptionsFabio Akita
In my first time at Russia, I've presented about Reactor Pattern, Eventmachine, WebSocket and the Pusher service as options for when Rails alone is not enough
Project Zero PHP talk at JavaOne 2008.
This talk describes IBM WebSphere sMash and the PHP support within it. For more information visit http://www.projectzero.org
Wakanda: NoSQL & SSJS for Model-driven Web Applications - SourceDevCon 2012Alexandre Morgaut
Wakanda: NoSQL & SSJS for Model-driven Web Applications
A session at SourceDevCon 2012
Developing a business web application is still a long process in 2012.
Model-Driven Development is at the heart of:
requirements design for the contractor and the product manager,
productivity for the developer,
consistency and security for the end-user
evolution toward future applications
The Wakanda platform – via its NoSQL object datastore WakandaDB – intends to let you create such model-driven applications. The presentation will explain and show how to create the application model, with its business and security rules, coded once, then made available everywhere without being bypassable. To add even more consistency, the same language is used everywhere: JavaScript. You'll enjoy the intuitive way to get data from the datastore via either the REST or the SSJS APIs.
You’ll see how to use the defined Model directly in a native framework or the Sencha one.
JavaScript is great, but let's face it, being stuck with just JavaScript in the browser is no fun.
Why not write and run Ruby in the browser, on the client, and on the server as part of your next web application?
Search and Society: Reimagining Information Access for Radical FuturesBhaskar Mitra
The field of Information retrieval (IR) is currently undergoing a transformative shift, at least partly due to the emerging applications of generative AI to information access. In this talk, we will deliberate on the sociotechnical implications of generative AI for information access. We will argue that there is both a critical necessity and an exciting opportunity for the IR community to re-center our research agendas on societal needs while dismantling the artificial separation between the work on fairness, accountability, transparency, and ethics in IR and the rest of IR research. Instead of adopting a reactionary strategy of trying to mitigate potential social harms from emerging technologies, the community should aim to proactively set the research agenda for the kinds of systems we should build inspired by diverse explicitly stated sociotechnical imaginaries. The sociotechnical imaginaries that underpin the design and development of information access technologies needs to be explicitly articulated, and we need to develop theories of change in context of these diverse perspectives. Our guiding future imaginaries must be informed by other academic fields, such as democratic theory and critical theory, and should be co-developed with social science scholars, legal scholars, civil rights and social justice activists, and artists, among others.
Epistemic Interaction - tuning interfaces to provide information for AI supportAlan Dix
Paper presented at SYNERGY workshop at AVI 2024, Genoa, Italy. 3rd June 2024
https://alandix.com/academic/papers/synergy2024-epistemic/
As machine learning integrates deeper into human-computer interactions, the concept of epistemic interaction emerges, aiming to refine these interactions to enhance system adaptability. This approach encourages minor, intentional adjustments in user behaviour to enrich the data available for system learning. This paper introduces epistemic interaction within the context of human-system communication, illustrating how deliberate interaction design can improve system understanding and adaptation. Through concrete examples, we demonstrate the potential of epistemic interaction to significantly advance human-computer interaction by leveraging intuitive human communication strategies to inform system design and functionality, offering a novel pathway for enriching user-system engagements.
Accelerate your Kubernetes clusters with Varnish CachingThijs Feryn
A presentation about the usage and availability of Varnish on Kubernetes. This talk explores the capabilities of Varnish caching and shows how to use the Varnish Helm chart to deploy it to Kubernetes.
This presentation was delivered at K8SUG Singapore. See https://feryn.eu/presentations/accelerate-your-kubernetes-clusters-with-varnish-caching-k8sug-singapore-28-2024 for more details.
Kubernetes & AI - Beauty and the Beast !?! @KCD Istanbul 2024Tobias Schneck
As AI technology is pushing into IT I was wondering myself, as an “infrastructure container kubernetes guy”, how get this fancy AI technology get managed from an infrastructure operational view? Is it possible to apply our lovely cloud native principals as well? What benefit’s both technologies could bring to each other?
Let me take this questions and provide you a short journey through existing deployment models and use cases for AI software. On practical examples, we discuss what cloud/on-premise strategy we may need for applying it to our own infrastructure to get it to work from an enterprise perspective. I want to give an overview about infrastructure requirements and technologies, what could be beneficial or limiting your AI use cases in an enterprise environment. An interactive Demo will give you some insides, what approaches I got already working for real.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
The Art of the Pitch: WordPress Relationships and SalesLaura Byrne
Clients don’t know what they don’t know. What web solutions are right for them? How does WordPress come into the picture? How do you make sure you understand scope and timeline? What do you do if sometime changes?
All these questions and more will be explored as we talk about matching clients’ needs with what your agency offers without pulling teeth or pulling your hair out. Practical tips, and strategies for successful relationship building that leads to closing the deal.
Key Trends Shaping the Future of Infrastructure.pdfCheryl Hung
Keynote at DIGIT West Expo, Glasgow on 29 May 2024.
Cheryl Hung, ochery.com
Sr Director, Infrastructure Ecosystem, Arm.
The key trends across hardware, cloud and open-source; exploring how these areas are likely to mature and develop over the short and long-term, and then considering how organisations can position themselves to adapt and thrive.
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Ramesh Iyer
In today's fast-changing business world, Companies that adapt and embrace new ideas often need help to keep up with the competition. However, fostering a culture of innovation takes much work. It takes vision, leadership and willingness to take risks in the right proportion. Sachin Dev Duggal, co-founder of Builder.ai, has perfected the art of this balance, creating a company culture where creativity and growth are nurtured at each stage.
UiPath Test Automation using UiPath Test Suite series, part 4DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 4. In this session, we will cover Test Manager overview along with SAP heatmap.
The UiPath Test Manager overview with SAP heatmap webinar offers a concise yet comprehensive exploration of the role of a Test Manager within SAP environments, coupled with the utilization of heatmaps for effective testing strategies.
Participants will gain insights into the responsibilities, challenges, and best practices associated with test management in SAP projects. Additionally, the webinar delves into the significance of heatmaps as a visual aid for identifying testing priorities, areas of risk, and resource allocation within SAP landscapes. Through this session, attendees can expect to enhance their understanding of test management principles while learning practical approaches to optimize testing processes in SAP environments using heatmap visualization techniques
What will you get from this session?
1. Insights into SAP testing best practices
2. Heatmap utilization for testing
3. Optimization of testing processes
4. Demo
Topics covered:
Execution from the test manager
Orchestrator execution result
Defect reporting
SAP heatmap example with demo
Speaker:
Deepak Rai, Automation Practice Lead, Boundaryless Group and UiPath MVP
9. Load Balancer
Reverse Proxy App Server
MySQL Proxy
Proxy as Middleware
middleware ftw!
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
10. 90% use case
%w*Transparent Intercepting Caching …+
There are many different types!
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
11. Transparent
HAProxy
App server A App server B
Transparent, Cut-Through Proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
13. Proxy Proxy
App server A App server B App server C
Problem: Staging Environment
Production
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
14. Simulating traffic?
Proxy
Duplication
App server C
“Representative Load / Staging”
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
19. EventMachine: Speed + Convenience
building high performance network apps in Ruby
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
20. p quot;Startingquot;
while true do
EM.run do
timers
p quot;Running in EM reactorquot;
network_io
end
other_io
end
puts quot;Almost donequot;
EventMachine Reactor
concurrency without threads
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
21. p quot;Startingquot;
while true do
EM.run do
timers
p quot;Running in EM reactorquot;
network_io
end
other_io
end
puts quot;Almost donequot;
EventMachine Reactor
concurrency without threads
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
22. C++ core
Easy concurrency
without threading
EventMachine Reactor
concurrency without threads
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
23. http = EM::HttpRequest.new('http://site.com/').get
http.callback {
p http.response
}
# ... do other work, until callback fires.
Event = IO event + block or lambda call
EventMachine Reactor
concurrency without threads
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
24. http = EM::HttpRequest.new('http://site.com/').get
http.callback {
p http.response
}
# ... do other work, until callback fires.
Event = IO event + block or lambda call
EventMachine Reactor
concurrency without threads
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
25. EM.run do
EM.add_timer(1) { p quot;1 second laterquot; }
EM.add_periodic_timer(5) { p quot;every 5 secondsquot;}
EM.defer { long_running_task() }
end
class Server < EM::Connection
def receive_data(data)
send_data(quot;Pong; #{data}quot;)
end
def unbind
p [:connection_completed]
end
end
EM.run do
EM.start_server quot;0.0.0.0quot;, 3000, Server
end
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
26. EM.run do
EM.add_timer(1) { p quot;1 second laterquot; }
EM.add_periodic_timer(5) { p quot;every 5 secondsquot;}
EM.defer { long_running_task() }
end
class Server < EM::Connection
def receive_data(data)
send_data(quot;Pong; #{data}quot;) Connection Handler
end
def unbind
p [:connection_completed]
end
end
EM.run do Start Reactor
EM.start_server quot;0.0.0.0quot;, 3000, Server
end
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
27. http://bit.ly/aiderss-eventmachine
by Dan Sinclair (Twitter: @dj2sincl)
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
28. Proxies for Monitoring, Performance and Scale
welcome to the wonderful world of…
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
29. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
conn.server :name, :host => quot;127.0.0.1quot;, :port => 81
conn.on_data do |data|
# ...
end
Relay Server
conn.on_response do |server, resp|
# ...
end
conn.on_finish do
# ...
end
end
EM-Proxy
www.github.com/igrigorik/em-proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
30. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
conn.server :name, :host => quot;127.0.0.1quot;, :port => 81
conn.on_data do |data|
# ...
end
Process incoming data
conn.on_response do |server, resp|
# ...
end
conn.on_finish do
# ...
end
end
EM-Proxy
www.github.com/igrigorik/em-proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
31. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
conn.server :name, :host => quot;127.0.0.1quot;, :port => 81
conn.on_data do |data|
# ...
end
Process response data
conn.on_response do |server, resp|
# ...
end
conn.on_finish do
# ...
end
end
EM-Proxy
www.github.com/igrigorik/em-proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
32. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
conn.server :name, :host => quot;127.0.0.1quot;, :port => 81
conn.on_data do |data|
# ...
end
conn.on_response do |server, resp|
# ...
end
Post-processing step
conn.on_finish do
# ...
end
end
EM-Proxy
www.github.com/igrigorik/em-proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
33. %w[ <Transparent> Intercepting Caching … +
solution for every problem
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
34. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 81
# modify / process request stream
conn.on_data do |data|
p [:on_data, data]
data
end No data modifications
# modify / process response stream
conn.on_response do |server, resp|
p [:on_response, server, resp]
resp
end
end
Port-Forwarding
transparent proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
35. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 81
conn.on_data do |data|
data
end
conn.on_response do |backend, resp| Alter response
resp.gsub(/hello/, 'good bye')
end
end
Port-Forwarding + Alter
transparent proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
36. %w[ Transparent <Intercepting> Caching … +
solution for every problem
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
37. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
@start = Time.now
@data = Hash.new(quot;quot;)
Prod + Test
conn.server :prod, :host => quot;127.0.0.1quot;, :port => 81
conn.server :test, :host => quot;127.0.0.1quot;, :port => 82
conn.on_data do |data|
data.gsub(/User-Agent: .*?rn/, 'User-Agent: em-proxyrn')
end
conn.on_response do |server, resp|
@data[server] += resp
resp if server == :prod
end
conn.on_finish do
p [:on_finish, Time.now - @start]
p @data
end
end
Duplex HTTP: Benchmarking
Intercepting proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
38. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
@start = Time.now
@data = Hash.new(quot;quot;)
conn.server :prod, :host => quot;127.0.0.1quot;, :port => 81
conn.server :test, :host => quot;127.0.0.1quot;, :port => 82
conn.on_data do |data|
data.gsub(/User-Agent: .*?rn/, 'User-Agent: em-proxyrn')
end
conn.on_response do |server, resp|
Respond from production
@data[server] += resp
resp if server == :prod
end
conn.on_finish do
p [:on_finish, Time.now - @start]
p @data
end
end
Duplex HTTP: Benchmarking
Intercepting proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
39. Proxy.start(:host => quot;0.0.0.0quot;, :port => 80) do |conn|
@start = Time.now
@data = Hash.new(quot;quot;)
conn.server :prod, :host => quot;127.0.0.1quot;, :port => 81
conn.server :test, :host => quot;127.0.0.1quot;, :port => 82
conn.on_data do |data|
data.gsub(/User-Agent: .*?rn/, 'User-Agent: em-proxyrn')
end
conn.on_response do |server, resp|
@data[server] += resp
resp if server == :prod
end
Run post-processing
conn.on_finish do
p [:on_finish, Time.now - @start]
p @data
end
end
Duplex HTTP: Benchmarking
Intercepting proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
44. Hacking SMTP
for fun and profit
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
45. Proxy.start(:host => quot;0.0.0.0quot;, :port => 2524) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 2525
# RCPT TO:<name@address.com>rn
RCPT_CMD = /RCPT TO:<(.*)?>rn/
Intercept Addressee
conn.on_data do |data|
if rcpt = data.match(RCPT_CMD)
if rcpt[1] != quot;ilya@igvita.comquot;
conn.send_data quot;550 No such user herenquot;
data = nil
end
end
data
end
conn.on_response do |backend, resp|
resp
end
Defeating SMTP Wildcards
end
Intercepting proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
46. Proxy.start(:host => quot;0.0.0.0quot;, :port => 2524) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 2525
# RCPT TO:<name@address.com>rn
RCPT_CMD = /RCPT TO:<(.*)?>rn/
conn.on_data do |data|
Allow: ilya@igvita.com
if rcpt = data.match(RCPT_CMD)
if rcpt[1] != quot;ilya@igvita.comquot;
conn.send_data quot;550 No such user herenquot;
data = nil 550 Error otherwise
end
end
data
end
conn.on_response do |backend, resp|
resp
end
Defeating SMTP Wildcards
end
Intercepting proxy
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
50. Proxy.start(:host => quot;0.0.0.0quot;, :port => 2524) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 2525
RCPT_CMD = /RCPT TO:<(.*)?>rn/
FROM_CMD = /MAIL FROM:<(.*)?>rn/
MSG_CMD = /354 Start your message/
MSGEND_CMD = /^.rn/ Intercept commands
conn.on_data do |data|
#…
end
conn.on_response do |server, resp|
p [:resp, resp]
if resp.match(MSG_CMD)
@buffer = true
@msg = quot;quot;
end
resp
SMTP + SPAM Filtering
end
end
building a state-machine
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
51. Proxy.start(:host => quot;0.0.0.0quot;, :port => 2524) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 2525
RCPT_CMD = /RCPT TO:<(.*)?>rn/
FROM_CMD = /MAIL FROM:<(.*)?>rn/
MSG_CMD = /354 Start your message/
MSGEND_CMD = /^.rn/
conn.on_data do |data|
#…
end
conn.on_response do |server, resp|
p [:resp, resp]
if resp.match(MSG_CMD) Flag & Buffer message
@buffer = true
@msg = quot;quot;
end
resp
SMTP + SPAM Filtering
end
end
building a state-machine
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
52. Save data
conn.on_data do |data|
@from = data.match(FROM_CMD)[1] if data.match(FROM_CMD)
@rcpt = data.match(RCPT_CMD)[1] if data.match(RCPT_CMD)
@done = true if data.match(MSGEND_CMD)
if @buffer
@msg += data
Buffer
data = nil
end
if @done
#…
end
data
SMTP + SPAM Filtering
end
building a state-machine
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
53. conn.on_data do |data|
@from = data.match(FROM_CMD)[1] if data.match(FROM_CMD)
@rcpt = data.match(RCPT_CMD)[1] if data.match(RCPT_CMD)
@done = true if data.match(MSGEND_CMD)
if @buffer
@msg += data
Flag end of message
data = nil
end
if @done
#… Process message
end
data
SMTP + SPAM Filtering
end
building a state-machine
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
58. @PostRank: Beanstalkd + Ruby Proxy
because RAM is still expensive
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
59. ~ 93 Bytes of overhead per job
~300 Bytes of data / job
x 80,000,000 jobs in memory
~ 30 GB of RAM = 2 X-Large EC2 instances
Oi, expensive!
Beanstalkd Math
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
60. Observations:
1. Each job is rescheduled several times
2. > 95% are scheduled for > 3 hours into the future
Memory is wasted…
3. Beanstalkd does not have overflow page-to-disk
We’ll add it ourselves!
Extending Beanstalkd
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
62. Proxy.start(:host => quot;0.0.0.0quot;, :port => 11300) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 11301
PUT_CMD = /put (d+) (d+) (d+) (d+)rn/
conn.on_data do |data|
if put = data.match(PUT_CMD) Intercept PUT command
if put[2].to_i > 600
p [:put, :archive]
# INSERT INTO ....
conn.send_data quot;INSERTED 9999rnquot;
data = nil
end
end
data
end
conn.on_response do |backend, resp|
resp
end
end
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
63. Proxy.start(:host => quot;0.0.0.0quot;, :port => 11300) do |conn|
conn.server :srv, :host => quot;127.0.0.1quot;, :port => 11301
PUT_CMD = /put (d+) (d+) (d+) (d+)rn/
conn.on_data do |data|
if put = data.match(PUT_CMD)
if put[2].to_i > 600 If over 10 minutes…
p [:put, :archive]
# INSERT INTO ....
conn.send_data quot;INSERTED 9999rnquot;
data = nil
end
end Archive & Reply
data
end
conn.on_response do |backend, resp|
resp
end
end
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf
64. Overload the protocol
MySQL
EM-Proxy
PUT
RESERVE, PUT, …
put job, 900
Beanstalkd
@PostRank: “Chronos Scheduler”
Ruby Proxies + EventMachine http://bit.ly/railsconf-proxy @igrigorik #railsconf