| 986 | } |
| 987 | |
| 988 | func (bh *blipHandler) handleNoRev(rq *blip.Message) error { |
| 989 | docID, revID := rq.Properties[NorevMessageId], rq.Properties[NorevMessageRev] |
| 990 | var seqStr string |
| 991 | if bh.activeCBMobileSubprotocol <= CBMobileReplicationV2 && bh.clientType == BLIPClientTypeSGR2 { |
| 992 | seqStr = rq.Properties[NorevMessageSeq] |
| 993 | } else { |
| 994 | seqStr = rq.Properties[NorevMessageSequence] |
| 995 | } |
| 996 | base.InfofCtx(bh.loggingCtx, base.KeySyncMsg, "%s: norev for doc %q / %q seq:%q - error: %q - reason: %q", |
| 997 | rq.String(), base.UD(docID), revID, seqStr, rq.Properties[NorevMessageError], rq.Properties[NorevMessageReason]) |
| 998 | |
| 999 | if bh.collectionCtx.sgr2PullProcessedSeqCallback != nil { |
| 1000 | seq, err := ParseJSONSequenceID(seqStr) |
| 1001 | if err != nil { |
| 1002 | base.WarnfCtx(bh.loggingCtx, "Unable to parse sequence %q from norev message: %v - not tracking for checkpointing", seqStr, err) |
| 1003 | } else { |
| 1004 | bh.collectionCtx.sgr2PullProcessedSeqCallback(&seq, IDAndRev{DocID: docID, RevID: revID}) |
| 1005 | } |
| 1006 | } |
| 1007 | |
| 1008 | // Couchbase Lite always sends noreply=true for norev profiles |
| 1009 | // but for testing purposes, it's useful to know which handler processed the message |
| 1010 | if !rq.NoReply() && rq.Properties[SGShowHandler] == trueProperty { |
| 1011 | response := rq.Response() |
| 1012 | response.Properties[SGHandler] = "handleNoRev" |
| 1013 | } |
| 1014 | |
| 1015 | return nil |
| 1016 | } |
| 1017 | |
| 1018 | type processRevStats struct { |
| 1019 | count *base.SgwIntStat // Increments when rev processed successfully |