5 Commits

Author SHA1 Message Date
Xiaoge Su
a355289d63 Remove cx->clearWatchMetadata() when connection file changed
In NativeAPI.actor.cpp, ::watch ACTOR will call cx->clearWatchMetadata()
when the connectionFileChanged event is triggered. After that, it will
create a new watch metadata for itself.

If there are multiple watches, each of them that receives the
cnnectionFileChanged will clear *all* watch data and create *one* watch
for itself. This does not makes sense. A watch should only clear the
metadata, and then create one, for itself.

cx->clearWatchMetadata() is only used there, thus removed.
2022-11-30 14:31:09 -08:00
Xiaoge Su
8773564390 Do not clear the reference count when deleting the watch metadata
In the following scenario a watch might be deleted by mistake:

Two watches over key A

         Watch 1                     Watch 2                 Reference Count
  |                                                          []
  |   Version 100, Value 10
T |   Add reference count                                    [100]
I |   Metadata added
M |   ...
E |                               Version 200, Value 20
  |                               Add reference count        [100, 200]
  |                               Delete the old metadata
  |                                      *together with the reference count*    <----- [1]
  |                                                          []
  |                               Trigger watch 1
  |                               Update metadata
  |   Triggered
  |   Delete the reference count                             []
  |                               ...
L |   Version 200, Value 20
I |   Add reference count                                    [200]
N |   Same metadata used
E |   ...
  |                               Watch 2 cancelled
  |                               Reduce reference count     []
  |                               Delete the metadata
  |                                (watchPromise removed, send broken_promise to listeners)
  |   broken_promise!
  V

By *not* clear the reference count in [1], just remove 100, this problem
will be fixed, since the watchPromise will still have one reference and
not being removed until watch 1 get triggered/cancelled again.

Tested by running 100k correctness on branch 7.1. One irrelevant
failure occured which will be tracked differently.
2022-11-30 14:31:09 -08:00
Xiaoge Su
b35d1b614e Revert "Merge pull request #8602 from apple/revert-8498-mmmm"
This reverts commit 4d789b2fd9b1632f89149517a3679c317f972a12, reversing
changes made to 9625efd5b9561e0355ca161c3fc76c7b8cf6aed5.
2022-11-30 14:31:09 -08:00
Jingyu Zhou
634bd529e7 Revert "Record the version of each watch"
This reverts commit 4bd24e4d6460c5cf38117b89246561bb0d83e3ef.
2022-10-27 19:46:05 -07:00
Xiaoge Su
4bd24e4d64 Record the version of each watch
In the case
    1. A watch to key A is set, the watchValueMap ACTOR, noted as X, starts waiting.
    2. All watches are cleared due to connection string change.
    3. The watch to key A is restarted with watchValueMap ACTOR Y.
    4. X receives the cancel exception, and tries to dereference the counter. This causes Y gets cancelled.

the reference count will cause watch prematurely terminate. Recording
the versions of each watch would help preventing this issue
2022-10-27 12:42:05 -07:00