Skip to content

Conversation

@kmahar
Copy link
Contributor

@kmahar kmahar commented Apr 17, 2020

Putting this up as a draft as we should probably talk through the approach more but I figured I'd let you all talk a look.
This seems like a mostly reasonable approach to me aside from the fact that we really end up in nested closure hell in places where a libmongoc method takes in 3+ arguments.

I think there is more work to do to ensure these problems don't plague any other types. for example I think we might be vulnerable to similar issues with ReadPreference as it follows the same "struct backed by a private class wrapping a C type" pattern.

To summarize main changes here:

  • BSONValue protocol's encode method now takes in an inout Document rather than a DocumentStorage
  • DocumentStorage is a private type, and its property _bson is now fileprivate. this means both are only accessible within Document.swift.
  • the only way to access a Document's underlying bson_t is via helpers, all of which use withExtendedLifetime to guarantee the Document stays valid for the duration of the provided closure. These are:
    • the existing withMutableBSONPointer
    • a new withBSONPointer, same as the previous but the pointer is immutable
    • a new withOptionalBSONPointer, which is to simplify usage in places where we have an optional document we may need to pass to a libmongoc API (basically this is just used for options documents)
  • DocumentIterator previously stored a reference to the DocumentStorage it came from. however I don't think this is really different than it just storing a copy of the Document it's iterating over -- in both cases we should get CoW behavior if someone tries to modify a copy of that document which is backed by the same storage. changing this this enabled me to make the change in the previous bullet point.

@kmahar kmahar requested review from mbroadst and patrickfreed April 17, 2020 04:21
@codecov-io
Copy link

codecov-io commented Apr 17, 2020

Codecov Report

Merging #453 into master will increase coverage by 0.14%.
The diff coverage is 87.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #453      +/-   ##
==========================================
+ Coverage   76.21%   76.35%   +0.14%     
==========================================
  Files         117      117              
  Lines       12820    12896      +76     
==========================================
+ Hits         9771     9847      +76     
  Misses       3049     3049              
Impacted Files Coverage Δ
Sources/MongoSwift/BSON/BSONEncoder.swift 64.54% <0.00%> (ø)
Sources/MongoSwift/ClientSession.swift 40.41% <0.00%> (-0.28%) ⬇️
...MongoSwift/Operations/FindAndModifyOperation.swift 81.11% <75.00%> (+0.21%) ⬆️
...ngoSwift/Operations/ListCollectionsOperation.swift 93.33% <75.00%> (+0.11%) ⬆️
...s/MongoSwift/Operations/ListIndexesOperation.swift 93.75% <75.00%> (+0.20%) ⬆️
Sources/MongoSwift/Operations/WatchOperation.swift 80.00% <75.00%> (+0.58%) ⬆️
Sources/MongoSwift/BSON/BSONValue.swift 76.04% <78.02%> (+0.91%) ⬆️
Sources/MongoSwift/Operations/FindOperation.swift 97.82% <80.00%> (+0.04%) ⬆️
...ces/MongoSwift/Operations/AggregateOperation.swift 97.50% <90.90%> (+0.13%) ⬆️
Sources/MongoSwift/BSON/Document.swift 88.46% <93.87%> (+1.24%) ⬆️
... and 16 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 8727aaf...ec16b9a. Read the comment docs.

@kmahar
Copy link
Contributor Author

kmahar commented Apr 18, 2020

made a few changes in my latest commit:

  • moved the helpers onto Document itself, excluding the convenience one, withOptionalBSONPointer since that needs to take in an optional. it is implemented by just delegating to the non optional helper. in addition to making the helper usages a bit more concise, this enabled me to make _storage private.
  • nested the DocumentStorage type definition within Document and renamed it just Storage

Copy link
Member

@mbroadst mbroadst left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@kmahar kmahar marked this pull request as ready for review April 20, 2020 16:26
Copy link
Contributor

@patrickfreed patrickfreed left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great!

By the way, this also closes SWIFT-739 since the pointers are all accessed from Document.

@kmahar kmahar merged commit b8a3726 into master Apr 21, 2020
@kmahar kmahar deleted the fix-lifetime-issues branch April 21, 2020 03:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants