Mattermost, Inc.

Using mattermost architecture for backend API

Hi,
I decide to use mattermost for our next project backend. Is this affordable when there are a lot of concurrent users? Because I read code and see that the communication with database is quite complex. It uses channel, for example:

if result := <-Srv.Store.Team().Get(user.TeamId); result.Err != nil {
    c.Err = result.Err
    return
} else {
    team = result.Data.(*model.Team)
}

I am wondering when something wrong with channel and it can not return the value, may be deadlock.
I appreciate all advices or corrections for my question, it’s the first time I use Go as backend of big project.
Thanks.

Hi @RuniVN,

One of the things Golang excels at is concurrency. Our server is designed to handle thousands of concurrent users currently and were we to add high availability it would be able to handle even more with a proper setup.

The reason we use channels for all our database communication is so we can take advantage of the concurrency features Golang offers. This allows us to have non-blocking interaction with the database, so every single one of our database accessors/setters returns a StoreChannel (and uses a goroutine to make the DB query) which will return a result no matter what and should never deadlock. We have unit tests that help to ensure this.

In the example you posted we are actually blocking the current method on the database access, likely because there is no more work that can be done until we have the Team object. In many places in the code you’ll notice we do something like this:

tchan := Srv.Store.Team().Get(user.TeamId)

// do some work

if result := <-tchan; result.Err != nil {
    c.Err = result.Err
    return
} else {
    team = result.Data.(*model.Team)
}

This allows us to start the database query, do some other work and then wait on the channel returning once we hit a point where we can do no more work without the Team object.

If you’d like to read more about Golang’s concurrency features like channels and goroutines take a look here.

Thanks jwilander for your explanation.