From 6c379f7d13b05236b33954e7b3fbc5f07dd54ec1 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Thu, 16 Nov 2017 16:59:38 +0000 Subject: [PATCH] Fix /sync when we have no events We used a since token of 0 to mean that no token was given. However, naffka streams start at 0. This causes clients to get stuck spinning forever until an event is sent. This changes it so that we pass around pointers instead, with nil meaning a since token wasn't given. --- .../matrix-org/dendrite/syncapi/sync/request.go | 11 ++++++----- .../matrix-org/dendrite/syncapi/sync/requestpool.go | 12 ++++++------ 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/request.go b/src/github.com/matrix-org/dendrite/syncapi/sync/request.go index 7dec55fe1..c22767f7a 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/request.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/request.go @@ -34,7 +34,7 @@ type syncRequest struct { userID string limit int timeout time.Duration - since types.StreamPosition + since *types.StreamPosition wantFullState bool log *log.Entry } @@ -70,13 +70,14 @@ func getTimeout(timeoutMS string) time.Duration { return time.Duration(i) * time.Millisecond } -func getSyncStreamPosition(since string) (types.StreamPosition, error) { +func getSyncStreamPosition(since string) (*types.StreamPosition, error) { if since == "" { - return types.StreamPosition(0), nil + return nil, nil } i, err := strconv.Atoi(since) if err != nil { - return types.StreamPosition(0), err + return nil, err } - return types.StreamPosition(i), nil + token := types.StreamPosition(i) + return &token, nil } diff --git a/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go b/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go index 3b6775618..15993b774 100644 --- a/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go +++ b/src/github.com/matrix-org/dendrite/syncapi/sync/requestpool.go @@ -64,7 +64,7 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtype currPos := rp.notifier.CurrentPosition() // If this is an initial sync or timeout=0 we return immediately - if syncReq.since == types.StreamPosition(0) || syncReq.timeout == 0 { + if syncReq.since == nil || syncReq.timeout == 0 { syncData, err := rp.currentSyncForUser(*syncReq, currPos) if err != nil { return httputil.LogThenError(req, err) @@ -93,7 +93,7 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtype case <-timer.C: return util.JSONResponse{ Code: 200, - JSON: types.NewResponse(syncReq.since), + JSON: types.NewResponse(currPos), } // Or for the request to be cancelled case <-req.Context().Done(): @@ -121,10 +121,10 @@ func (rp *RequestPool) OnIncomingSyncRequest(req *http.Request, device *authtype func (rp *RequestPool) currentSyncForUser(req syncRequest, currentPos types.StreamPosition) (res *types.Response, err error) { // TODO: handle ignored users - if req.since == types.StreamPosition(0) { + if req.since == nil { res, err = rp.db.CompleteSync(req.ctx, req.userID, req.limit) } else { - res, err = rp.db.IncrementalSync(req.ctx, req.userID, req.since, currentPos, req.limit) + res, err = rp.db.IncrementalSync(req.ctx, req.userID, *req.since, currentPos, req.limit) } if err != nil { @@ -148,7 +148,7 @@ func (rp *RequestPool) appendAccountData( return nil, err } - if req.since == types.StreamPosition(0) { + if req.since == nil { // If this is the initial sync, we don't need to check if a data has // already been sent. Instead, we send the whole batch. var global []gomatrixserverlib.ClientEvent @@ -170,7 +170,7 @@ func (rp *RequestPool) appendAccountData( } // Sync is not initial, get all account data since the latest sync - dataTypes, err := rp.db.GetAccountDataInRange(req.ctx, userID, req.since, currentPos) + dataTypes, err := rp.db.GetAccountDataInRange(req.ctx, userID, *req.since, currentPos) if err != nil { return nil, err }