Live data from Hacker News

What happened to Vivaldi Social?

thomasp.vivaldi.net

61–70 of 83 posts

Re: What happened to Vivaldi Social?

#61
post #26

Earlier quoted context omitted.

Yeah, because Mastodon is the most happening place online lol. I can't believe people on hacker news talk like this. Embarrassing how far this community has declined. Can't even discuss protocols without these stupid comments.

> Yeah, because Mastodon is the most happening place online lol. Compared to other Twitter alternatives? It absolutely is. It's not even a contest, it's in a league of its own. As embarassing as it sounds, Bluesky, Nostr, Post.news, Spoutible etc don't come even close. (Threads does of course, but the two should be compatible in the near future.) It's also the only one that 1) didn't come to life as a reaction to Twi…

> didn't come to life as a reaction to Twitter changing ownership

Small correction, it came to life years before the actual purchase due to the _possibility_ that Twitter could be purchased. This gave it years to mature, and I think the time was well spent for the most part.

Agree with the rest of your points though. Mastodon is really a great platform, even if it's not the best platform for every type of user or use case, and I truly do not understand why it provokes such vitriolic detractors. I was astonished that it was actually easier for me to get updates about what was happening to Twitter during its API and connectivity issues last month from my Mastodon feed than anywhere else, including Twitter itself.

Re: What happened to Vivaldi Social?

#62
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

I finally made an account just to respond to this, I hope you don't find that too aggressive a move. Null is a perfectly valid value for data, and should be treated as such. A default value (e.g. -1 for a Boolean or an empty for a string) can make your system appear to work where NULL would introduce a runtime error, but that doesn't mean your system is performing as expected, it just makes it quieter. I know it's te…

I agree with you re: NULL being a useful thing. I personally use nullable floats in an internal company program to denote unknown values. However, the "billion-dollar mistake" everyone brings up with it has to do with NULL allowance being implicit. In languages like C/C++, Java, C#[a] (and more), any pointer could be NULL and the only way to know is to do a NULL check. In SQL (which we're talking about here), one must explicitly call out `NOT NULL` in the column's definition.[b] Rust (and other FP languages) gets a point here by having "optional" types one must use to have a NULL-like system.

[a]: C# is fixing this with "nullable reference types", but as long as it's still opt-in, it's not perfect (backwards compatibility and everything). I can still forcibly pass a NULL to a function (defined to not take a null value) with the null-forgiving operator: `null!`. This means library code still needs `ArgumentNullException.ThrowIfNull(arg)` guards everywhere, just in case the caller is stupid. One could argue this is the caller shooting themselves in the foot like `Option.unwrap_unchecked` in Rust, but "good practice" in C# (depending on who you ask) tends to dictate guard checks.

[b]: Which is kind of stupid, IMO. Why should `my_column BOOL` be able to be null in the first place? Nullable pointers I can understand, but implicitly nullable everything is a horrible idea.

Re: What happened to Vivaldi Social?

#63
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

> the account merge code could have been narrowly scoped

IMO automated merging/deduplication of "similar" records is one of those incredibly hard problems, with edge cases and race conditions galore, that should have a human in the loop whenever possible, and should pass data (especially data consumed asynchronously) as explicitly as possible, with numerous checks to ensure that facts haven't shifted on the ground.

In many cases, it requires the implementors to start by thinking about all the concerns and interactivity requirements that e.g. a Git-style merge conflict would have, and try to make simplifying assumptions based on the problem domain from that starting position.

Looking at the Mastodon source [0], and seeing that there's not even an explicit list of to-merge-from IDs passed from the initiator of the merge request to the asynchronous executor of the merge logic, it seems like it was only a matter of time before something like this happened.

This is not a criticism of Mastodon, by the way! I've personally written, and been bitten by, merge logic with far worse race conditions, and it's frankly incredible that a feature like this even exists for what is effectively [1] a volunteer project! But it is a cautionary tale nonetheless.

[0] https://github.com/mastodon/mastodon/blob/main/app/workers/a... (note: AGPL)

[1] https://opencollective.com/mastodon

Re: What happened to Vivaldi Social?

#64
post #44

I'll never forget the first time I had to restore a massive sql dump and realized that vim actually segfaults trying to read it. That's when I discovered the magic of spit(1) "split a file into pieces". I just split the huge dump into one file per table. Of course a table can also be massive, but at least the file is now more uniform which means you can easier run other tools on it like sed or awk to transform querie…

I once had to administer a system where a particular folder had so many files that things stopped working, even the ls command would not complete. (It was probably on ext3 or ext2.) The workaround involved writing a python script that handled everything in a gradual manner, moving files into subdirectories based on shared prefixes.

oh yes. ls uses 4k buffers for dirents, and in a directory with lots of entries, the time for userspace to hit the kernel to list the entities until that 4k buffer is full, back in the day, became noticable. In my dealings with a system like that, I had a hacked copy of ls that used bigger buffers so at least it wouldn't hang. Tab completion would also hang if there were too many entries.

Re: What happened to Vivaldi Social?

#65
post #58
post #46

Earlier quoted context omitted.

What's the alternative, an empty string? IMO the problem (at least in this case) is not NULL in the DB, but NULL at the application level. If NULL is some sort of Maybe monad and you're forced to deal with it, well, you're forced to deal with it, think about it, etc. Empty string, whatever NULL string is in your language of choice, or some sort of sigil value you invent... not much of a difference.

The problem is precisely that NULL is not some sort of Maybe monad, but people keep trying to use it as such. It's a lot like using NaN as a sentinel value for floats - sure, you can do that, but when something goes wrong, instead of an error at the point where the problem is, you end up dealing with a mysterious NULL somewhere way down the line. And that's the best case - the worst is that you get wrong query result…

With empty string there's gotcha: Oracle treats empty string and null as the same values. If you really need sentinel value, generate UUID.

Re: What happened to Vivaldi Social?

#66

Earlier quoted context omitted.

I finally made an account just to respond to this, I hope you don't find that too aggressive a move. Null is a perfectly valid value for data, and should be treated as such. A default value (e.g. -1 for a Boolean or an empty for a string) can make your system appear to work where NULL would introduce a runtime error, but that doesn't mean your system is performing as expected, it just makes it quieter. I know it's te…

I agree with you re: NULL being a useful thing. I personally use nullable floats in an internal company program to denote unknown values. However, the "billion-dollar mistake" everyone brings up with it has to do with NULL allowance being implicit . In languages like C/C++, Java, C#[a] (and more), any pointer could be NULL and the only way to know is to do a NULL check. In SQL (which we're talking about here), one mu…

In SQL as you've said, nullability is explicit. It's arguably the wrong way around (i.e. NOT NULL rather than NULLABLE), but it is explicit. I feel the issue comes from the intersection of languages without explicit nullability and their data storage techs; removing that explicit typing from SQL doesn't fix the issue.

(I feel you agree with this btw, just being explicit)

Re: What happened to Vivaldi Social?

#67
post #54

Earlier quoted context omitted.

Joins are cheap. Wide tables are often a sign that a data-model is a bit too CRUDdy. Foreign key relationships often do a much better job modeling optionality/cardinality in relational systems. In this case, a `user_uris` table with non-nullable columns and a unique constraint on `user_id` is the first option that comes to mind.

I had a situation where I'm not really sure I could have used something else than null: I need a value in one of two columns exactly (meaning one is NULL and the other not). You can build a constraint to check that if it's in the same table, but across tables it seems to be a bit more complex right ?

You could have the first column indicate the type of value and the second column the value. If you now have your columns named "a" and "b" you could have the first column named "type" only allowing values "a" or "b" and the second column would be "value" where the actual value is stored.

Re: What happened to Vivaldi Social?

#68
post #58

Earlier quoted context omitted.

The problem is precisely that NULL is not some sort of Maybe monad, but people keep trying to use it as such. It's a lot like using NaN as a sentinel value for floats - sure, you can do that, but when something goes wrong, instead of an error at the point where the problem is, you end up dealing with a mysterious NULL somewhere way down the line. And that's the best case - the worst is that you get wrong query result…

With empty string there's gotcha: Oracle treats empty string and null as the same values. If you really need sentinel value, generate UUID.

I believe that's a nasty implementation detail of Oracle and not a problem for anybody using anything else.

A generated UUID, if possible, is probably much more clear because it will only be there if it was inserted very deliberately.

But at that point honestly I'd usually prefer breaking the field out into its own table.

Re: What happened to Vivaldi Social?

#69
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

Even if there is null, the merge function should have done some sort of null / istruthy check. That’s unbelievable.

Re: What happened to Vivaldi Social?

#70
post #63
post #27

Great writeup (including the human cost, e.g. loss / lack of sleep, which in my experience has a huge impact on complicated incident resolution). Here’s what jumped out at me: “The new account was created in our database with a null value in the URI field.” Almost every time I see a database-related postmortem — and I have seen a lot of them — NULL is lurking somewhere in the vicinity of the crime scene. Even if NULL…

> the account merge code could have been narrowly scoped IMO automated merging/deduplication of "similar" records is one of those incredibly hard problems, with edge cases and race conditions galore, that should have a human in the loop whenever possible, and should pass data (especially data consumed asynchronously) as explicitly as possible, with numerous checks to ensure that facts haven't shifted on the ground. I…

It’s not hard not to merge on null.

I agree rest of it can be hard, and would be nervous. But this should have been obvious

Post reply on HN