Skip to content

database.read and database.execute_sql should not return the session to the pool till the stream is closed #3768

Closed

Description

@vkedia

Cloud Spanner API says that at any point in time there can be at most one active transaction. But the way database.read and database.execute_query have been implemented, they return the session to the pool immediately. Now that session can be reused for doing something else even before the stream returned by previous database.read has completed. This needs to be fixed so that the sessions is returned to the pool only after the iterator has been completely consumed or closed.
This needs to be done before Beta.

Activity

  1. vkedia commented on Aug 8, 2017

    @vkedia
    Author
  2. bjwatson commented on Aug 8, 2017

    @bjwatson

    Thanks @vkedia. At a 100K' level, this does sound like a significant usability issue. I'm okay with this being Beta blocking, unless @lukesneeringer or @tseaver have an opinion to the contrary.

  3. added
    api: spannerIssues related to the Spanner API.
    priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.
    release blockingRequired feature/issue must be fixed prior to next release.
    type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.
    on Aug 8, 2017
  4. vkedia commented on Aug 8, 2017

    @vkedia
    Author

    @bjwatson This also might be a breaking change depending on how this resolved. For eg the easiest resolution would be to just remove these methods since one can always do the same thing by using a Snapshot.

  5. bjwatson commented on Aug 8, 2017

    @bjwatson

    @vkedia That sounds like an easy fix, but definitely surface breaking.

  6. tseaver commented on Aug 9, 2017

    @tseaver
    Contributor

    I don't think using Database.snapshot solves the problem. Using the current methods:

    results = database.execute_sql(SQL)  # returns StreamedResultSet

    versus using a snapshot:

    with database.snapshot() as snapshot:
        results = snapshot.execute_sql(SQL) # returns StreamedResultSet

    The 'StreamedResultSet' we return wraps a low-level GAPIC entity with no existing / obvious link to our session. Given that the user may not iterate to the end (or at all), we would likely have to had some machinery for a "deferred return to pool" and trigger that from StreamedResultSet.__del__.

    The other option would be to require that user applications complete all iteration over the StreamedResultSet inside the with database.snapshot() as snapshot: block.

  7. vkedia commented on Aug 9, 2017

    @vkedia
    Author

    It seems fair to me to expect that user will not access the results object outside of the context block. We can possibly do something to invalidate the iterators when the snapshot is checked back in.

  8. tseaver commented on Aug 10, 2017

    @tseaver
    Contributor

    Via #3787.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

api: spannerIssues related to the Spanner API.priority: p1Important issue which blocks shipping the next release. Will be fixed prior to next release.release blockingRequired feature/issue must be fixed prior to next release.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions