DEV Community

Randall
Randall

Posted on

🙏Please, specify your units! 📏

What sucks about this code?

const success = myCache.mset([
    {key: "myKey", val: obj, ttl: 10000},
    {key: "myKey2", val: obj2},
]);
Enter fullscreen mode Exit fullscreen mode

It's not clear at all clear if the ttl is 10,000 milliseconds, seconds, or something else. Just glancing at this code (and knowing that JavaScript setTimeout() uses milliseconds), you might be tempted to think it's in milliseconds. Wrong! It's in seconds!

This snippet is example code from the README of node-cache. This type of unclear code is really prevalent, so I'm not trying to pick on them in particular. Fortunately, the README does say that it's in seconds, but you have to RTFM to be sure, and who's got time for that?

Wouldn't it be nice if the ttl property were named ttlSeconds? Then it's instantly clear what it means to whoever is reading the code.

Or maybe there's an even better solution.

Datetimes

It's also pretty common for datetimes to be represented as an integer number of milliseconds (or seconds) since the Unix epoch ( 00:00:00 UTC on 1 January 1970). For example:

const myBirthday = 700876800000;
Enter fullscreen mode Exit fullscreen mode

This sucks too. You might recognize this as very likely being a number of milliseconds since the Unix epoch, but you have no idea what date this represents.

How about this instead:

const myBirthday = new Date('1992-03-18T00:00:00.000Z');
Enter fullscreen mode Exit fullscreen mode

Now whoever's reading this code knows exactly what date it represents, and code that accesses myBirthday does too. Surrounding code doesn't need tribal knowledge about whether this number is a number of seconds or milliseconds. It's a Date, and has a very specific meaning.

TimeSpans

Jumping back to TTL (time to live) again. A TTL is not a specific date and time, but a length of time (one second, one year, etc), so we can't use Date to represent it.

Naming your TTL property ttlSeconds for clarity is a fine solution in a lot of cases, but what if there were a datatype similar to Date for this?

Some languages actually have such features built in. JavaScript doesn't, but we can use a package like timespan.

import timespan from 'timespan';

const ttl = timespan.fromSeconds(50);

console.log(ttl.totalMilliseconds()); // 50000
console.log(ttl.totalSeconds()); // 50
console.log(ttl.totalMinutes()); // 0.8333333333333334
Enter fullscreen mode Exit fullscreen mode

You can specify your TTL in whatever units you want, and the code you pass your TTL to can read it in whatever units it wants. You don't have to agree on units at all.

If only NASA used constructs like this, they may have been able to save a few bucks.

Conclusion

Just a short one I wanted to get off my chest here. Many bugs have their roots in mix-ups about what units are being used. Fortunately we have some tools at our disposal to mitigate these sort of risks. I wish I saw them used more often!

Top comments (0)