Improved sessions API

XMLWordPrintableJSON

    • Type: New Feature
    • Resolution: Unresolved
    • Priority: Unknown
    • None
    • Affects Version/s: None
    • Component/s: Sessions, Transactions
    • None
    • Python Drivers
    • Hide

      1. What would you like to communicate to the user about this feature?
      2. Would you like the user to see examples of the syntax and/or executable code and its output?
      3. Which versions of the driver/connector does this apply to?

      Show
      1. What would you like to communicate to the user about this feature? 2. Would you like the user to see examples of the syntax and/or executable code and its output? 3. Which versions of the driver/connector does this apply to?
    • None
    • None
    • None
    • None
    • None
    • None

      Context

      Related to DRIVERS-724. The current session api is very error prone because the "session=session" argument needs to be passed to every single api call. This is easy to forget and even our own docs and internal users have fallen into this trap. For a example, a quick search for "pass session" shows RUBY-1870, FREE-182695, CSHARP-2331, CHARTS-6471, PYTHON-2538, SERVER-37792.

      Here's a made up example:

      with client.start_session() as session, session.start_transaction():
          coll.insert_one({}, session=session)
          doc = coll.find_one({}, session=session)
          if doc:
              coll2.replace_one({"_id": doc["_id"]}, doc)  # Oops, forgot to pass session here!
      

      An alternative design we can use is to bind the session to a contextvar, which is similar to a thread-local but works in an async context as well. We already do something similar to manage the timeouts in pymongo.timeout().

      The API could look like this:

      with client.start_session(bind=True) as session, session.start_transaction():
          coll.insert_one({})
          doc = coll.find_one({})
          if doc:
              coll2.replace_one({"_id": doc["_id"]}, doc)
      

      This would also greatly reduce the cost of adding support for sessions and transactions to third party libraries like MongoEngine (PYTHON-3432). With this new feature, MongoEngine would only need to offer hooks to start the session/transaction:

      with Model1.start_transaction():
          Model1.objects.get()
          Model2.objects.get()
      

      Definition of done

      • Explore different APIs, eg should we add a new MongoClient method for this (eg client.bind_session()) or add a "bind" argument to start_session().
      • Add docs.
      • Extend test_session.py to ensure every API correctly inherits the session.
      • Define the behavior of nested calls.
      • Determine if we need to add an API to query the current session.
      • Define the behavior of using 2 different clients within the block.

      Pitfalls

      We should perf test the implementation to ensure contextvar lookup doesn't add too much overhead.

            Assignee:
            Alex Clark
            Reporter:
            Shane Harvey
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: