googleapis / ruby-spanner

Apache License 2.0
4 stars 9 forks source link

List all sessions for a given project/instance/database to support stale transaction roll back on the emulator #76

Open abachman opened 9 months ago

abachman commented 9 months ago

Feature request: I'd like better access to the Ruby Spanner RPC list_sessions method to support Emulator session transaction resetting.

Background

Facts:

  1. The Spanner local emulator only permits one transaction to be open at a time.
  2. Opening a transaction and then crashing or killing a program while a transaction is open can result in the client going away and the stale transaction left open until the emulator is restarted.

Annoying, because rebuilding large (100+ table, 300+ index, 1000s of columns) database from scratch can take up to 30 seconds. It'd be much faster to just clear stale open transactions for detached sessions.

Fast forward, I figured out how to do this with the existing library, but it required this monkey patch:

module Google
  module Cloud
    module Spanner
      class Service
        # add a missing list_sessions method
        # @param database [String] in the form of a full Spanner identifier like
        #                          "project/.../instance/.../database/..."
        def list_sessions(database:, call_options: nil, token: nil, max: nil)
          opts = default_options call_options: call_options
          request = {
            database: database,
            page_size: max,
            page_token: token
          }
          paged_enum = service.list_sessions request, opts
          paged_enum.response
        end
      end
    end
  end
end

And then some egregious private API calling to:

So, it'd be cool to have list_sessions as a first class method on whatever class or classes where it makes sense.

Betyho commented 3 months ago

module Google module Cloud module Spanner class Service

add a missing list_sessions method

    # @param database [String] in the form of a full Spanner identifier like
    #                          "project/.../instance/.../database/..."
    def list_sessions(database:, call_options: nil, token: nil, max: nil)
      opts = default_options call_options: call_options
      request = {
        database: database,
        page_size: max,
        page_token: token
      }
      paged_enum = service.list_sessions request, opts
      paged_enum.response
    end
  end
end

end end