Skip to content
Swizec Teller - a geek with a hatswizec.com

I built a node app to thaw my favorite snack πŸ₯•

The office fridge hates me and keeps freezing my carrots. I love carrots. They're the perfect low calorie crunchy snack for those afternoons when you're chasing an errant semicolon for two hours and your code isn't working.

But they're not very tasty frozen. In fact they're disgusting when frozen.

You gotta thaw those suckers.

How do you thaw carrots at the office? With your laptop!

But sometimes that doesn't work. Maybe you're chasing that errant semicolon for so long that your computer cools down. Maybe webpack is actually fast for once. Maybe even VSCode and Chrome and XCode aren't doing the job.

Never thought I'd say this, but sometimes macs just don't wanna get hot no matter what you do.

So I built a tool! A node app. An app that thaws your carrots. Keeps your hands warm. In winter it might even heat your room.

The greatest contribution to computer science known to man! Or woman.

πŸ₯• thaw-carrots -t 90

Install globally with npm or yarn – npm install -g thaw-carrots, run with your favorite temperature, and thaw-carrots will keep your CPU busy just enough to give you a nice even warm throughout your best carrot thawing areas.

Here's how it works πŸ‘‡

With just 14 dependencies this might be the smallest node app you've ever seen. Thanks to @lukeed05 and his obsession with zero dependency code.

thaw-carrots uses mri to parse command line arguments, kleur and single-line-log for pretty console output, and systeminformationto read CPU temperatures.

The approach is simple:

  • run an infinite loop
  • read temperature
  • if temperature below target, add expensive background jobs
  • if temperature above target, remove an expensive job
  • print info
  • repeat

29 lines of code, 2 hours of tinkering

async function thawMyCarrots(targetTemp) {
let temp = await readTemp(),
temps = [temp, temp, temp],
children = [];
while (1) {
if (avg(temps) < targetTemp) {
if (children.length < 10) {
children.push(fork(`${__dirname}/eat-cpu`));
}
} else if (avg(temps) > targetTemp) {
if (children.length > 0) {
children.pop().kill();
}
}
temp = await readTemp();
temps.shift();
temps.push(temp);
sll(
"Current temp",
kleur.bold.red(temp.main.toFixed(2)),
"\nCores at",
kleur.bold.gray(temp.cores),
`\nChildren: ${children.length}`
);
sleep.msleep(500);
}
}

We read the current CPU temperature, pre-fill our running tally of 3 measurements, and create an empty pool of children processes. Then start the loop.

The loop checks an average of the last 3 temperatures and decides what to do. If we have to warm up, we fork a new subprocess using the eat-cpu file. If it's time to cool off, we kill one of the forks.

I kept max forks at 10 because that seemed reasonable.

Update our running array of temperature measurements, print current values to the screen, wait 500 milliseconds, do it all again. Perfect πŸ‘Œ

How to warm a CPU

To warm a CPU, you have to make it work. Like an athlete at the gym, the CPU gets warm when it's working hard.

But what's hard for a CPU?

You want a process that's heavy on CPU and light on memory. Easy to spin up and down, make harder or easier. You want fine grained control over that temperature and you're fighting everything your OS was designed to prevent.

The low memory requirement disqualifies calculating primes, playing with big numbers, mining bitcoin, or running Slack. You'd be surprised how many people recommended I just run Slack or Chrome or Hangouts to thaw my carrots.

Those fools!

My first attempt was using the collatz conjecture. Finite calculation, lots of addition and division and multiplication, handles big numbers okay, can run for a long time to find the full chain. No need to keep anything in memory while you're running.

But my CPU was too good at that. Didn't warm up for shit. And when the numbers got really high, Collatz fast became too slow to compute. Didn't have the fine grained control.

Then I found this little gem from @sqren. A gist called "cpu-intensive.js". Perfect!

Looks like this:

function mySlowFunction(baseNumber) {
console.time('mySlowFunction');
var result = 0;
for (var i = Math.pow(baseNumber, 10); i >= 0; i--) {
result += Math.atan(i) * Math.tan(i);
};
console.timeEnd('mySlowFunction');
return result;
}
mySlowFunction(3);

I don't know what it's doing. It's some sort of maths. But it runs good and strong with small inputs. It's easy to spin up and down. And doesn't keep anything in memory.

One wasn't enough so I'm running up to 10 in parallel πŸ”₯

πŸ₯•

You can see thaw-carrots on GitHub. Install via npm.

Can't wait to try it at the office today. Nom!

Enjoy πŸ₯•

Did you enjoy this article?

Published on October 11th, 2018 in Uncategorized

Learned something new?
Want to become a high value JavaScript expert?

Here's how it works πŸ‘‡

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet πŸ“–right away. After that you'll get thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over my 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

Start with an interactive cheatsheet πŸ“–

Then get thoughtful letters πŸ’Œ on mindsets, tactics, and technical skills for your career.

"Man, love your simple writing! Yours is the only email I open from marketers and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. πŸ‘Œ"

~ Ashish Kumar

Join over 10,000 engineers just like you already improving their careers with my letters, workshops, courses, and talks. ✌️

Have a burning question that you think I can answer?Β I don't have all of the answers, but I have some! Hit me up on twitter or book a 30min ama for in-depth help.

Ready to Stop copy pasting D3 examples and create data visualizations of your own? Β Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization

Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.

Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first πŸ’° on the side with ServerlessReact.Dev

Want to brush up on your modern JavaScript syntax?Β Check out my interactive cheatsheet: es6cheatsheet.com

By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❀️