SlideShare a Scribd company logo
Por que Criamos uma Ferramenta
de Load Testing utilizando
Playwright e AWS Batch?
@anderparra
/anderparra
Anderson Parra
Senior Software Engineer
What’s SeatGeek?
With our combination of technological
prowess, user-first attitude and dashing good
looks, we, SeatGeek, are simplifying and
modernizing the ticketing industry.
By simultaneously catering to both the
consumer and enterprise markets, we’re
powering a new, open entertainment industry
where fans have effortless access to
experiences, and teams, venues and shows
have seamless access to their audiences. We
think it’s time that everyone can expect more
from ticketing.
SeatGeek
Vision Statement
Become the largest and
most loved ticket
marketplace by offering
consumers a meaningfully
better ticketing
experience.
The in-house queueing system
Virtual
Waiting Room
Virtual Waiting Room Operation Modes
Transitions from Blockade to Throttle Strate.
The Waiting Room Main States
All traffic to the protected zone is
blocked, showing a waiting room
page to end-users.
Transitions from Blockade to Throttle State.
The Waiting Room Main States
Allows a configurable
number of end-users
per minute into the
protected zone. After
initial seeding, users are
allowed in First-In, First-
Out (FIFO).
Let’s see an example:
I would like to buy
tickets for an
event with high
demand…
Blockade - Waiting
Room Mode
Throttle - Queue
Mode
Virtual Waiting Room Stack Overview
A browser-based load testing tool
Frenzy
import ws from 'k6/ws'
import { check } from 'k6'
export default function () {
const visitorToken = '???'
const url = `wss://stag.vroom.com/?vt=${visitorToken}`
const res = ws.connect(url, {}, (socket) => {
socket.on('open', () => console.log('connected'))
socket.on('message', (m) => {
/* check the message m */
socket.close()
)}
socket.on('close', () => console.log('disconnected'))
socket.on('error', (e) => {
if (e.error() !== 'websocket: close sent') {
console.log('Unexpected error: ', e.error())
}
})
})
check(res, { 'status is 101': (r) => r && r.status === 101 })
}
https://k6.io
case class ProtectedResource(path: String) {
val execute: ChainBuilder = ???
}
object VroomQueue {
val execute: ChainBuilder =
exec(ws("Connecting").connect("/?vt=${visitorToken}"))
}
class QueueSimulation extends Simulation {
val httpProtocol = http
.baseUrl("https://stag.seatgeek.com")
.doNotTrackHeader("1")
.wsBaseUrl("wss://stag.vroom.com")
val scenarioBuilder = scenario("Accessing PZ").exec(
ProtectedResource(path).execute,
doIf(session => session.contains("visitorToken")) {
VroomQueue.execute
})
val execution = scenarioBuilder
.inject(constantUsersPerSec(concurrency) during holdFor)
.protocols(httpProtocol)
setUp(execution)
}
https://gatling.io
So why did we
decide to
create our
tool?
Frenzy Tech Stack
Platform Tools Environment Observability Notification
How is it
connected?
Orchestrator
Protected Zone
seatgeek.com/event-1
JOB 0
JOB 1
JOB 2
Orchestrator
Protected Zone
seatgeek.com/event-1
JOB 0
JOB 1
JOB 2
browsers
browsers
browsers
Orchestrator
Protected Zone
seatgeek.com/event-1
JOB 0
JOB 1
JOB 2
browsers
browsers
browsers
Orchestrator
Protected Zone
seatgeek.com/event-1
JOB 0
JOB 1
JOB 2
browsers
browsers
browsers
Orchestrator
Protected Zone
seatgeek.com/event-1
AWS Batch
JOB 0
JOB 1
JOB 2
simulator
Orchestrator
Protected Zone
seatgeek.com/event-1
AWS Batch
Gitlab CI
simulator
simulator
browser
sessions
browser
sessions
browser
sessions
JOB 0
JOB 1
JOB 2
browsers
browsers
browsers
Orchestrator
Protected Zone
seatgeek.com/event-1
AWS Batch
Gitlab CI
JOB 0
JOB 1
JOB 2
browsers
browsers
browsers
Orchestrator
Protected Zone
seatgeek.com/event-1
AWS Batch
Gitlab CI
JOB 0
JOB 1
JOB 2
browsers
browsers
browsers
Orchestrator
Protected Zone
seatgeek.com/event-1
AWS Batch
Gitlab CI
6.000 AWS Batch jobs, if
each job runs 15 browsers
instances, then it results in
90.000 virtual users
JOB 0
JOB 1
JOB 2
browsers
browsers
browsers
Orchestrator
Protected Zone
seatgeek.com/event-1
AWS Batch
Gitlab CI
Scheduled Executions
► Monday (large)
► Tuesday (small)
► Thursday (small)
func (o *Orchestrator) OrchestrateFrenzy(ctx context.Context, conf FrenzyConfig) {
logger.Info("Transitioning zone to blockade")
_ := o.vroom.TransitionProtectedZone(ctx, conf.zoneULID, vroom.BlockadeState);
job, _ := o.batch.SubmitJob(ctx, &batch.SubmitJobInput{...})
// start watching for running jobs
watchRunningJobsCh := NewWatcher(o.batch).WatchRunningJobs(ctx, *job.JobId)
_ := o.awaitSpinup(ctx, conf, watchRunningJobsCh);
logger.Info("Transitioning zone to throttle")
o.vroom.TransitionProtectedZone(ctx, conf.zoneULID, vroom.ThrottleState);
// start watching for status jobs
watchStatusJobCh := NewWatcher(o.batch).Watch(ctx, *job.JobId)
_ := o.awaitBatchDone(ctx, conf, watchStatusJobCh);
}
func (o *Orchestrator) awaitSpinup(ctx context.Context,
conf FrenzyConfig, watchResultCh <-chan WatchResult) error {
for {
select {
case result := <-watchResultCh:
// await for AWS Batch jobs being in running mode
case <-spinupTimeout.C:
return fmt.Errorf("timed out waiting for virtual users to spin up")
}
}
}
func (o *Orchestrator) awaitBatchDone(ctx context.Context,
conf FrenzyConfig, watchResultCh <-chan WatchResult) error {
for {
select {
case result := <-watchResultCh:
// checks result.JobDetail.Status
case <-doneTimeout.C:
return fmt.Errorf("timed out waiting for job to finish after 1 hour")
}
}
}
Orchestrator
async function simulateUser(i, browser) {
let page;
const context = await browser.newContext();
page = await context.newPage();
await step(`(worker=${i}) WHEN I visit the page`, async () => {
const resp = await page.goto('stag.seatgeek.com/event-1');
expect(resp.status()).to.equal(200, "received non-200");
})
await step(`(worker=${i}) THEN I eventually see the target page`, async () => {
await page.waitForFunction(() => {
// validate if the content page matches to expected target
return true | false;
}, null, { timeout: 90e3 * 60 });
})
}
async function main() {
let browser = await playwright['chromium'].launch({
headless: true
});
let results = await Promise.all(
Array.from({length: numUsers})
.map((_, i) => simulateUser(i, browser)));
}
https://playwright.dev
Why AWS Batch instead of AWS Lambda?
The Lambda max timeout is 900 seconds
(15 minutes).
Lambda functions are short lived
With no max timeout restrictions
we can simulate long queues in
order to find bottlenecks.
AWS Batch Jobs are long lived
Summary
Prepare your apps for huge traffic.
Scaling is always a good thing for a web app, but it can also be a pain point. How can
you be sure you can handle more traffic than you currently have? And if you can’t
handle it, where is problem coming from?
Regardless the tool you are going to use, emulate heavy
traffic and analyse the outcome reports enable you to
find potential bugs and bottle necks.
The End
Thank You!
Thanks to everyone for your patience and time.
Hope everyone has a better understanding of
the loading test importance.
Questions?
If you want to know more about any of this,
please reach me out:
Anderson Parra
@anderparra
/anderparra

More Related Content

Similar to Por que Criamos uma Ferramenta de Load Testing utilizando Playwright e AWS Batch?

An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathon
Luciano Mammino
 
Arduino and the real time web
Arduino and the real time webArduino and the real time web
Arduino and the real time web
Andrew Fisher
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
Paco de la Cruz
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applicationsTom Croucher
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
Matt Raible
 
Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JS
Ilia Idakiev
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
Paweł Kowalczuk
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
Gianluca Carucci
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
soft-shake.ch
 
Going real time with Socket.io
Going real time with Socket.ioGoing real time with Socket.io
Going real time with Socket.io
Arnout Kazemier
 
Scalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureScalable Angular 2 Application Architecture
Scalable Angular 2 Application Architecture
FDConf
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0
Oscar Renalias
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
Frank Lyaruu
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Ismael Celis
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
Frank Lyaruu
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
Garrett Welson
 
JavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptxJavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptx
RAHITNATH
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
Vadym Khondar
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
Fwdays
 

Similar to Por que Criamos uma Ferramenta de Load Testing utilizando Playwright e AWS Batch? (20)

An opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathonAn opinionated intro to Node.js - devrupt hospitality hackathon
An opinionated intro to Node.js - devrupt hospitality hackathon
 
Arduino and the real time web
Arduino and the real time webArduino and the real time web
Arduino and the real time web
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
 
Writing robust Node.js applications
Writing robust Node.js applicationsWriting robust Node.js applications
Writing robust Node.js applications
 
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 202010 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
10 Excellent Ways to Secure Spring Boot Applications - Okta Webinar 2020
 
Deep Dive into Zone.JS
Deep Dive into Zone.JSDeep Dive into Zone.JS
Deep Dive into Zone.JS
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Future Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NETFuture Decoded - Node.js per sviluppatori .NET
Future Decoded - Node.js per sviluppatori .NET
 
soft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.jssoft-shake.ch - Hands on Node.js
soft-shake.ch - Hands on Node.js
 
Going real time with Socket.io
Going real time with Socket.ioGoing real time with Socket.io
Going real time with Socket.io
 
Scalable Angular 2 Application Architecture
Scalable Angular 2 Application ArchitectureScalable Angular 2 Application Architecture
Scalable Angular 2 Application Architecture
 
Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0Asynchronous web apps with the Play Framework 2.0
Asynchronous web apps with the Play Framework 2.0
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
 
Non Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJavaNon Blocking I/O for Everyone with RxJava
Non Blocking I/O for Everyone with RxJava
 
Intro to Asynchronous Javascript
Intro to Asynchronous JavascriptIntro to Asynchronous Javascript
Intro to Asynchronous Javascript
 
JavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptxJavaScript Multithread or Single Thread.pptx
JavaScript Multithread or Single Thread.pptx
 
Reactive programming every day
Reactive programming every dayReactive programming every day
Reactive programming every day
 
Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"Anton Moldovan "Load testing which you always wanted"
Anton Moldovan "Load testing which you always wanted"
 
Network
NetworkNetwork
Network
 

Recently uploaded

Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
Octavian Nadolu
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Albert Hoitingh
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
Neo4j
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Nexer Digital
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
DianaGray10
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
KatiaHIMEUR1
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
Neo4j
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
Alex Pruden
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 

Recently uploaded (20)

Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
Artificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopmentArtificial Intelligence for XMLDevelopment
Artificial Intelligence for XMLDevelopment
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
Encryption in Microsoft 365 - ExpertsLive Netherlands 2024
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
GraphSummit Singapore | Enhancing Changi Airport Group's Passenger Experience...
 
Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?Elizabeth Buie - Older adults: Are we really designing for our future selves?
Elizabeth Buie - Older adults: Are we really designing for our future selves?
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1Communications Mining Series - Zero to Hero - Session 1
Communications Mining Series - Zero to Hero - Session 1
 
20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !Securing your Kubernetes cluster_ a step-by-step guide to success !
Securing your Kubernetes cluster_ a step-by-step guide to success !
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...
 
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdfFIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
FIDO Alliance Osaka Seminar: The WebAuthn API and Discoverable Credentials.pdf
 
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex ProofszkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
zkStudyClub - Reef: Fast Succinct Non-Interactive Zero-Knowledge Regex Proofs
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 

Por que Criamos uma Ferramenta de Load Testing utilizando Playwright e AWS Batch?

  • 1. Por que Criamos uma Ferramenta de Load Testing utilizando Playwright e AWS Batch?
  • 3. What’s SeatGeek? With our combination of technological prowess, user-first attitude and dashing good looks, we, SeatGeek, are simplifying and modernizing the ticketing industry. By simultaneously catering to both the consumer and enterprise markets, we’re powering a new, open entertainment industry where fans have effortless access to experiences, and teams, venues and shows have seamless access to their audiences. We think it’s time that everyone can expect more from ticketing.
  • 4. SeatGeek Vision Statement Become the largest and most loved ticket marketplace by offering consumers a meaningfully better ticketing experience.
  • 5.
  • 6. The in-house queueing system Virtual Waiting Room
  • 7. Virtual Waiting Room Operation Modes
  • 8. Transitions from Blockade to Throttle Strate. The Waiting Room Main States All traffic to the protected zone is blocked, showing a waiting room page to end-users.
  • 9. Transitions from Blockade to Throttle State. The Waiting Room Main States Allows a configurable number of end-users per minute into the protected zone. After initial seeding, users are allowed in First-In, First- Out (FIFO).
  • 10. Let’s see an example: I would like to buy tickets for an event with high demand…
  • 13. Virtual Waiting Room Stack Overview
  • 14.
  • 15. A browser-based load testing tool Frenzy
  • 16. import ws from 'k6/ws' import { check } from 'k6' export default function () { const visitorToken = '???' const url = `wss://stag.vroom.com/?vt=${visitorToken}` const res = ws.connect(url, {}, (socket) => { socket.on('open', () => console.log('connected')) socket.on('message', (m) => { /* check the message m */ socket.close() )} socket.on('close', () => console.log('disconnected')) socket.on('error', (e) => { if (e.error() !== 'websocket: close sent') { console.log('Unexpected error: ', e.error()) } }) }) check(res, { 'status is 101': (r) => r && r.status === 101 }) } https://k6.io
  • 17. case class ProtectedResource(path: String) { val execute: ChainBuilder = ??? } object VroomQueue { val execute: ChainBuilder = exec(ws("Connecting").connect("/?vt=${visitorToken}")) } class QueueSimulation extends Simulation { val httpProtocol = http .baseUrl("https://stag.seatgeek.com") .doNotTrackHeader("1") .wsBaseUrl("wss://stag.vroom.com") val scenarioBuilder = scenario("Accessing PZ").exec( ProtectedResource(path).execute, doIf(session => session.contains("visitorToken")) { VroomQueue.execute }) val execution = scenarioBuilder .inject(constantUsersPerSec(concurrency) during holdFor) .protocols(httpProtocol) setUp(execution) } https://gatling.io
  • 18.
  • 19. So why did we decide to create our tool?
  • 20. Frenzy Tech Stack Platform Tools Environment Observability Notification
  • 23. JOB 0 JOB 1 JOB 2 Orchestrator Protected Zone seatgeek.com/event-1
  • 24. JOB 0 JOB 1 JOB 2 browsers browsers browsers Orchestrator Protected Zone seatgeek.com/event-1
  • 25. JOB 0 JOB 1 JOB 2 browsers browsers browsers Orchestrator Protected Zone seatgeek.com/event-1
  • 26. JOB 0 JOB 1 JOB 2 browsers browsers browsers Orchestrator Protected Zone seatgeek.com/event-1 AWS Batch
  • 27. JOB 0 JOB 1 JOB 2 simulator Orchestrator Protected Zone seatgeek.com/event-1 AWS Batch Gitlab CI simulator simulator browser sessions browser sessions browser sessions
  • 28. JOB 0 JOB 1 JOB 2 browsers browsers browsers Orchestrator Protected Zone seatgeek.com/event-1 AWS Batch Gitlab CI
  • 29. JOB 0 JOB 1 JOB 2 browsers browsers browsers Orchestrator Protected Zone seatgeek.com/event-1 AWS Batch Gitlab CI
  • 30. JOB 0 JOB 1 JOB 2 browsers browsers browsers Orchestrator Protected Zone seatgeek.com/event-1 AWS Batch Gitlab CI 6.000 AWS Batch jobs, if each job runs 15 browsers instances, then it results in 90.000 virtual users
  • 31. JOB 0 JOB 1 JOB 2 browsers browsers browsers Orchestrator Protected Zone seatgeek.com/event-1 AWS Batch Gitlab CI Scheduled Executions ► Monday (large) ► Tuesday (small) ► Thursday (small)
  • 32. func (o *Orchestrator) OrchestrateFrenzy(ctx context.Context, conf FrenzyConfig) { logger.Info("Transitioning zone to blockade") _ := o.vroom.TransitionProtectedZone(ctx, conf.zoneULID, vroom.BlockadeState); job, _ := o.batch.SubmitJob(ctx, &batch.SubmitJobInput{...}) // start watching for running jobs watchRunningJobsCh := NewWatcher(o.batch).WatchRunningJobs(ctx, *job.JobId) _ := o.awaitSpinup(ctx, conf, watchRunningJobsCh); logger.Info("Transitioning zone to throttle") o.vroom.TransitionProtectedZone(ctx, conf.zoneULID, vroom.ThrottleState); // start watching for status jobs watchStatusJobCh := NewWatcher(o.batch).Watch(ctx, *job.JobId) _ := o.awaitBatchDone(ctx, conf, watchStatusJobCh); } func (o *Orchestrator) awaitSpinup(ctx context.Context, conf FrenzyConfig, watchResultCh <-chan WatchResult) error { for { select { case result := <-watchResultCh: // await for AWS Batch jobs being in running mode case <-spinupTimeout.C: return fmt.Errorf("timed out waiting for virtual users to spin up") } } } func (o *Orchestrator) awaitBatchDone(ctx context.Context, conf FrenzyConfig, watchResultCh <-chan WatchResult) error { for { select { case result := <-watchResultCh: // checks result.JobDetail.Status case <-doneTimeout.C: return fmt.Errorf("timed out waiting for job to finish after 1 hour") } } } Orchestrator
  • 33. async function simulateUser(i, browser) { let page; const context = await browser.newContext(); page = await context.newPage(); await step(`(worker=${i}) WHEN I visit the page`, async () => { const resp = await page.goto('stag.seatgeek.com/event-1'); expect(resp.status()).to.equal(200, "received non-200"); }) await step(`(worker=${i}) THEN I eventually see the target page`, async () => { await page.waitForFunction(() => { // validate if the content page matches to expected target return true | false; }, null, { timeout: 90e3 * 60 }); }) } async function main() { let browser = await playwright['chromium'].launch({ headless: true }); let results = await Promise.all( Array.from({length: numUsers}) .map((_, i) => simulateUser(i, browser))); } https://playwright.dev
  • 34. Why AWS Batch instead of AWS Lambda? The Lambda max timeout is 900 seconds (15 minutes). Lambda functions are short lived With no max timeout restrictions we can simulate long queues in order to find bottlenecks. AWS Batch Jobs are long lived
  • 36. Prepare your apps for huge traffic. Scaling is always a good thing for a web app, but it can also be a pain point. How can you be sure you can handle more traffic than you currently have? And if you can’t handle it, where is problem coming from? Regardless the tool you are going to use, emulate heavy traffic and analyse the outcome reports enable you to find potential bugs and bottle necks.
  • 37. The End Thank You! Thanks to everyone for your patience and time. Hope everyone has a better understanding of the loading test importance. Questions? If you want to know more about any of this, please reach me out: Anderson Parra @anderparra /anderparra

Editor's Notes

  1. [Jeff] We’ve been massively fortunate to establish partnerships with some of the leading properties in the world. The common denominator is an unrelenting focus on fans and a shared vision that “better” exists and technology is the path.