diff --git a/clientapi/routing/joinroom.go b/clientapi/routing/joinroom.go index c10113574..578aaec56 100644 --- a/clientapi/routing/joinroom.go +++ b/clientapi/routing/joinroom.go @@ -16,9 +16,11 @@ package routing import ( "net/http" + "time" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/clientapi/httputil" + "github.com/matrix-org/dendrite/clientapi/jsonerror" roomserverAPI "github.com/matrix-org/dendrite/roomserver/api" "github.com/matrix-org/dendrite/userapi/api" "github.com/matrix-org/dendrite/userapi/storage/accounts" @@ -74,16 +76,32 @@ func JoinRoomByIDOrAlias( } // Ask the roomserver to perform the join. - rsAPI.PerformJoin(req.Context(), &joinReq, &joinRes) - if joinRes.Error != nil { - return joinRes.Error.JSONResponse() - } + done := make(chan util.JSONResponse, 1) + go func() { + defer close(done) + rsAPI.PerformJoin(req.Context(), &joinReq, &joinRes) + if joinRes.Error != nil { + done <- joinRes.Error.JSONResponse() + } else { + done <- util.JSONResponse{ + Code: http.StatusOK, + // TODO: Put the response struct somewhere internal. + JSON: struct { + RoomID string `json:"room_id"` + }{joinRes.RoomID}, + } + } + }() - return util.JSONResponse{ - Code: http.StatusOK, - // TODO: Put the response struct somewhere internal. - JSON: struct { - RoomID string `json:"room_id"` - }{joinRes.RoomID}, + // Wait either for the join to finish, or for us to hit a reasonable + // timeout, at which point we'll just return a 200 to placate clients. + select { + case <-time.After(time.Second * 20): + return util.JSONResponse{ + Code: http.StatusAccepted, + JSON: jsonerror.Unknown("The room join will continue in the background."), + } + case result := <-done: + return result } }