216 results for "":
Writing a Dockerfile for catscii
Now that our service is production-ready, it’s time to deploy it somewhere.
There’s a lot of ways to approach this: what we are going to do, though, is build a docker image. Or, I should say, an OCI image.
This is still a series about Nix, but again: because the best way to see the benefits of Nix is to do it without Nix first, we’ll use only Docker’s tooling to build the image.
Why is my Rust build so slow?
I’ve recently come back to an older project of mine (that powers this website), and as I did some maintenance work: upgrade to newer crates, upgrade to a newer rustc, I noticed that my build was taking too damn long!
For me, this is a big issue. Because I juggle a lot of things at any given time, and I have less and less time to just hyperfocus on an issue, I try to make my setup as productive as possible.
Making our own spectrogram
We recently went way too in-depth into volume and loudness and all the relevant standards, like EBU R 128 — which is important to broadcast engineers, but, I’ll admit, not very entertaining to look at!
Spectrograms, on the other hand, are very fun to look at:
There’s a lot of care that goes into designing a nice spectrogram, and I want to walk you through how I made my own, assembling a couple of Rust libraries like cpal and egui.
Consuming Ethernet frames with the nom crate
Now that we’ve found the best way to find the “default network interface”… what can we do with that interface?
Well, listen for network traffic of course!
use rawsock::open_best_library;
use std::time::Instant;
fn main() -> Result<(), Error> {
let lib = open_best_library()?;
let iface_name = format!(r#"\Device\NPF_{}"#, netinfo::default_nic_guid()?);
let iface = lib.open_interface(&iface_name)?;
println!("Listening for packets...");
// doing some low-cost logging over here
let start = Instant::now();
iface.loop_infinite_dyn(&mut |packet| {
println!(
"{:?} | received {} bytes",
start.elapsed(),
packet.len()
);
})?;
Ok(())
}
Rust modules vs files
A while back, I asked on Twitter what people found confusing in Rust, and one of the top topics was “how the module system maps to files”.
I remember struggling with that a lot when I first started Rust, so I’ll try to explain it in a way that makes sense to me.
Important note
All that follows is written for Rust 2021 edition. I have no interest in learning (or teaching) the ins and outs of the previous version, especially because it was a lot more confusing to me.
Day 10 (Advent of Code 2020)
Day, 10! Day, 10!
Okay, Day 10.
Again, the problem statement is very confusing - but what it all boils down to is this. We have a list of numbers:
16
10
15
5
1
11
7
19
6
12
4
To which we need to add 0
and whatever the maximum was, plus three:
16
10
15
5
1
11
7
19
6
12
4
0
22
From there on, if we take them in order, we’ll have gaps of 1 and gaps of 3:
Developing over SSH
With the previous part’s VM still running, let’s try connecting to our machine over SSH.
Network addresses, loopback and IP nets
Normally, to connect to a machine, you’d find its IP address. On Linux, a decade
ago, you would’ve used ifconfig
. Nowadays you can use ip addr
:
The loopback interface (lo
) is local, so it’s not useful to reach the box from
the outside: you can see it can be accessed over IPv4 at address 127.0.0.1 but
not just! What we’re reading here is 127.0.0.1/8, which corresponds to the range
127.0.0.1 - 127.255.255.255
Summer fasterthanlime update
There are news!
TL;DR: If you’re a patron or sponsor, check your Profile page to get detailed explainers of every perk. You’ll need to log in. Duh.
Here are all the changes I’m implementing, summarized as a table:
Before | After |
📚 Articles remain exclusive for 6 months | Early access (couple weeks) for Silver tier |
🎞️ No early access for video |
Day 11 (Advent of Code 2022)
It’s a new day, it’s a new advent of code puzzle.
In that one, we have to apparently cosplay as an IBM mainframe and just.. crunch them numbers. This doesn’t look fun, and I can’t think of a clever twist to make it fun, so let’s try to make it short and sweet.
Parsing
Our input looks like this:
Monkey 0:
Starting items: 79, 98
Operation: new = old * 19
Test: divisible by 23
If true: throw to monkey 2
If false: throw to monkey 3
Monkey 1:
Starting items: 54, 65, 75, 74
Operation: new = old + 6
Test: divisible by 19
If true: throw to monkey 2
If false: throw to monkey 0
(etc)
What's in a Linux executable?
Executables have been fascinating to me ever since I discovered, as a kid,
that they were just files. If you renamed a .exe
to something else, you
could open it in notepad! And if you renamed something else to a .exe
,
you’d get a neat error dialog.
Clearly, something was different about these files. Seen from notepad, they were mostly gibberish, but there had to be order in that chaos. 12-year-old me knew that, although he didn’t quite know how or where to dig to make sense of it all.