Challenges / Your first challenge

Your first challenge

Nothing is sending the app traffic, and its code fails on every request. Wire it up, fix one line, and watch a run score itself.

Instance GroupA 30-second run, scored against 2 goals
Start this challengeIt runs in your browser. No account, nothing to install.

The setup

TrafficRequest Generator
Web AppInstance Group · 1 instance

Every challenge works the same way: get the canvas ready, press Run, and the goals score what happens while a script drives the traffic. This one walks you through it.

Drag a connection from Traffic to Web App, then press Run. Every request will fail, and that is the bug you are here to fix.

Once the run starts, select Web App and open its Logs tab to see the error. Fix the line it names, then run again.

The run

Each goal is judged over its own stretch of the run rather than the whole of it.

0 s30 s
  • 8 s · Traffic doubles to twenty requests a second

The code

Ordinary Node against the real AWS SDK, running as real processes in the tab. You can edit any of it once the challenge is open.

Web App / server.js
import express from 'express';
import { Metrics, MetricUnit } from '@aws-lambda-powertools/metrics';

// Glass Garden gives every instance its own PORT, because they all share one machine here.
// In a real deployment they would each be on their own machine, and could all listen on the same port.
const port = Number(process.env.PORT);
if (!port) {
  throw new Error('PORT is not set');
}

// CloudWatch metrics, written the way a Lambda writes them: as a line on stdout that the
// Metrics tab reads. Each addMetric is one observation, not a running total
const metrics = new Metrics();
// What tells one instance's numbers from another's, here and in CloudWatch: a dimension the
// code declares. Remove it and the instances' lines merge into one
metrics.setDefaultDimensions({ instance: String(port) });

const app = express();

app.get('/', (req, res) => {
  metrics.addMetric('requests', MetricUnit.Count, 1);
  metrics.publishStoredMetrics();

  // One name on the line below is not the one this file declares, so every request ends in a
  // 500 instead of an answer. The Logs tab has the error and the line it came from, and the
  // generator's Metrics tab has the failures it is counting
  res.type('text/plain').send(`Hello from the instance on :${instancePort}\n`);
});

// Express hands a failed request here, which is what puts one readable line in the Logs tab
// instead of a raw stack trace. Browsers do not agree on what a stack even contains
app.use((error, req, res, next) => {
  console.error(`${error.name}: ${error.message}`);
  res.status(500).type('text/plain').send('Something went wrong\n');
});

app.listen(port, () => {
  console.log(`Server running on http://localhost:${port}`);
});

More challenges

The concert that oversold

Box Office counts the tickets it has left. Keep the concert from selling more than it has when Box Office scales out.

HTTP Load Balancer, Instance Group, Table (DynamoDB)

30s run · 4 goals

Signups grind to a halt

The signup API hashes every password and stores it while the caller waits. Keep signups answering when the traffic climbs.

HTTP Load Balancer, Instance Group, Table (DynamoDB)

Usually solved with: Queue (SQS), Function (Lambda)

+
30s run · 4 goals