Post

24 February 2025

24 February 2025

Web frameworks are moving back to less complex frameworks, which was the original intention of Jamstack. For example Astro and Vue which have no Javascript by default, and Eleventy. And away from more complex frameworks like React.

.NET OSS Projects: Better to Re-license or Die?

FluentAssertions recently went from OSS to a commercial license. The internet went crazy, similarly to when Moq tried to commercialize an OSS project, but in a different way. Moq tried to communicate its change up front, but no-one listened. FluentAssertions seems to have made a random decision to commercialize, but it seems doomed to failure because it’s so easy to stick with the free version or move to something else. Anyway, same conclusion - making money from OSS is hard.

Software Testing Anti-patterns

An old article, but still as true as ever.

How Precision Time Protocol handles leap seconds

Facebook’s approach to a massive-scale problem. NTP’s smearing of a leap second over a day doesn’t cut it any more. PTP provides time precision to the nanosecond which allows for a much smoother smearing. But what Facebook is really proposing is to get rid of leap seconds altogether and keep UTC linear.

.NET 9 HybridCache

New feature in .NET 9.x (after 9.0): hybrid cache which is a combination of in-memory and distributed cache, with feature like stampede protection:

Cache stampede happens when a frequently used cache entry is revoked, and too many requests try to repopulate the same cache entry at the same time

Death of a thousand nits

Okay article about how to avoid nitpicking in code reviews. Don’t make (or respond to) comments about “not my style”. And don’t ask questions about things you don’t understand (eg language features) - google it yourself. Basically it’s saying only make comments that add value.

The Curious Case of .NET ConcurrentDictionary and Closures

This creates a closure:

1
2
3
4
5
6
7
8
void SayHello(string name)
{
    var hello = () =>
    {
        Console.WriteLine($"Hello {name}");
    };
    hello();
}

name needs to be captured. The solution is to pass state in as arguments:

1
2
3
4
5
6
7
8
void SayHello(string name)
{
    var hello = (string n) =>
    {
        Console.WriteLine($"Hello {n}");
    };
    hello(name);
}

Moving to the specific example of ConcurrentDictionary:

1
2
3
4
5
6
7
var result = concurrentDictionary.GetOrAdd(
    key: key,
    valueFactory: (k) =>
    {
        Console.WriteLine($"Building {k}");
        return new Item(value, DateTime.Now);
    });

key is okay, but value is a capture. To solve it, we use the second parameter to the lambda arg, and the third parameter to the method factoryArgument:

1
2
3
4
5
6
7
8
var result = concurrentDictionary.GetOrAdd(
    key: key,
    valueFactory: (k, arg) =>
    {
        Console.WriteLine($"Building {k}");
        return new Item(arg, DateTime.Now);
    },
    factoryArgument: value);

This avoids closures, reduces allocations, and avoids potentially nasty concurrency or memory leak issues.

Using ‘in’ C# Keyword as a Parameter Modifier

The in parameter modifier passes the parameter as a read-only reference.

1
2
3
public void Foo(in string bar) {
  // do stuff
}

Any attempt to modify bar will result in a compile-time error.

As well as the obvious benefit of clarifying intent, this allows for more efficient code.

Normally, value types (such as int) have their value copied over to the parameter (“pass by value”), and reference types (such as string) are passed by not-readonly reference. Using the in modifier changes the behavior:

  • Value types are now passed by reference (and are readonly), instead of “pass by value”
  • Reference types are now passed by readonly reference

This prevents the value passed in being modified as a side-effect.

It also means the compiler doesn’t need to make a copy of the object, hence increasing efficiency.

A Tour of WebAuthn

A long and detailed article (actually a book) about WebAuthn - an API to allow you to interact with hardware security keys in the browser.

This post is licensed under CC BY 4.0 by the author.