Skip to content

Increase thread safety on variables - #592

Merged
kegsay merged 7 commits into
matrix-org:mainfrom
realtyem:thread-safety
Feb 10, 2023
Merged

Increase thread safety on variables#592
kegsay merged 7 commits into
matrix-org:mainfrom
realtyem:thread-safety

Conversation

@realtyem

Copy link
Copy Markdown
Contributor

While experimenting with Complement and trying to speed up a few things, I noticed some race conditions causing inconsistent results. I started tracking them down one-by-one using the -race flag on go test. Fixing these allows heavier usage of t.Parallel() during tests while sharing a deployment and registering fresh users with RegisterUser()(ala, federation_room_join_partial_state_test.go and #471) and it's siblings and derivatives. This alone will not(unfortunately) speed up Complement on Synapse(especially on Github CI), but will pave the way for less odd and inconsistent errors in the future. Hopefully, some flakes will go away as well(looking at you Client Timeout while awaiting headers).

Mutex's and RWMutex's were the main go-to, but atomic.AddInt64() was also used in a few places where I felt it was more appropriate.

There is an entire set of data races I couldn't touch from this repo, those caused by gorilla's mux package. The problem stems from the complement test server that is created to test federation responses. Sometimes a test server is created, then started with Listen(), and then an additional Handler is added on to the server(which is necessary to get the results of the test). This causes a data race in the Router.routes slice when Router.Match is concurrently called. Unfortunately, this package is no longer maintained and has been archived. If someone at matrix.org would like to fork it, I can submit the PR to patch it. I'm still exploring other packages that might meet the requirements as a replacement, but would appreciate suggestions or a fuller list of said requirements than I can get by just reading the source code.

Should be reviewable commit-wise.

Useful links:

Signed-off-by: Jason Little realtyem@gmail.com

…urrent writes.

Appending to a slice is not thread-safe. The actual value is safe, but the header for the slice is
not. Protect it with a Mutex. This will allow more liberal use of t.Parallel() without data races
using RegisterUser(), LoginUser() and Client() to access users on a Homeserver under test when
sharing a deployment.
…cessed concurrently, mainly by SendEventUnsynced. Make it atomic(fix it in the other places it is used as well).
…d-safe parts, State and Timeline. Protect them with a RWMutex,

as most of their usages are reads. This touched the SendJoinRequestHandler as well, as it reads from the State map.
…hat was causing a data race. Protect it with atomics.
…ct it with a RWMutex as RegisterUser() can write concurrently when using t.Parallel().
@realtyem
realtyem marked this pull request as ready for review January 31, 2023 01:19
@realtyem
realtyem requested review from a team and kegsay as code owners January 31, 2023 01:19
@MatMaul

MatMaul commented Feb 1, 2023

Copy link
Copy Markdown
Contributor

Thanks a lot for this PR, some flakes have been annoying us for a while, like TestDeviceListUpdates.

We think your changes make sense, but we also think that having to think about that kind of stuffs in a testing framework is... really annoying :)

As a first, could you split out the part with the changes on the internal framework ?
Those are mostly hidden to people writing tests so we think this is probably ok to have a bit of locking wizardy there.

We are going to put a bit more thinking about that in #complement:matrix.org so feel free to come around there.

@kegsay kegsay self-assigned this Feb 1, 2023
@squahtx

squahtx commented Feb 7, 2023

Copy link
Copy Markdown
Contributor

This mostly touches Complement internals, so I'm taking it off the Synapse team's review queue.

@squahtx
squahtx removed the request for review from a team February 7, 2023 20:02

@kegsay kegsay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The internal package changes are very sane, thanks!

Complement internals are generally not thread-safe to use, but yes in practice we should make them (specifically the Deployment/Server/ServerRoom).

@kegsay
kegsay merged commit 5c444e7 into matrix-org:main Feb 10, 2023
@MatMaul

MatMaul commented Feb 10, 2023

Copy link
Copy Markdown
Contributor

For context we also had a lengthy discussion on should we really use Parallel and locking in tests, and we probably want to avoid that later on, but it needs work to split tests in more packages so go test -p X can parallelized them and we don't explode CI timings.

In the meantime, thanks a lot for that @realtyem , less flakes !

@realtyem
realtyem deleted the thread-safety branch February 11, 2023 01:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants