Skip to content

Spanner service never completes a closeAsync when there is an unused ReadContext #1986

@danielcompton

Description

@danielcompton

I noticed after working on some code that my Spanner service was throwing a TimeoutException after calling closeAsync on it with a timeout on the get. I tracked it down to a stray ReadContext that I created in my code but never consumed or closed. If a timeout isn't set when dereferencing the future then it doesn't seem to ever return.

This is a minimal example in Clojure, but you should be able to get the gist of it. The important part is that a ReadContext is created but never closed.

(let [ ;; setup spanner
      options (.. (SpannerOptions/newBuilder)
                  (build))
      service (.getService options)
      db      (DatabaseId/of (.getProjectId options) "deps-dev" "deps-dev")
      clientProject (.. service (getOptions) (getProjectId))
      db-client (.getDatabaseClient service db)]
  ;; create a ReadContext
  (.singleUse db-client)
  (.get (.closeAsync ^Spanner service) 3 TimeUnit/SECONDS))

;; throws a j.u.c.TimeoutException

I realise that ReadContext is an AutoCloseable, but I found the behaviour a little surprising still. I'm not sure what (if any) changes could/should be made here, but I thought I'd raise the issue as I didn't see anything about this documented in the ReadContext javadoc except for maybe this comment "TODO(user): Add logging and tracking of leaked sessions." on closeAsync. A few options I can see:

  1. Do nothing. It's an autocloseable and if you don't close it then it's on you.
  2. Log about the leaked ReadContext and close anyway
  3. Return something from the future instead of nil
  4. Document in closeAsync that it should be dereferenced with a timeout to prevent hangs (good practice in general)
  5. Document in ReadContext that not closing it will lead to timeouts on closing the Spanner service.

Metadata

Metadata

Assignees

Labels

api: spannerIssues related to the Spanner API.type: bugError or flaw in code with unintended results or allowing sub-optimal usage patterns.

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions