Uploaded image for project: 'TinkerPop'
  1. TinkerPop
  2. TINKERPOP-2845

Race conditions in Go GLV

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Critical
    • Resolution: Unresolved
    • 3.7.0
    • None
    • go
    • None

    Description

      While working on writing tests for the Go GLV using gremlin-socket-server, 2 possible race conditions were detected by go test -race. The provided test code I will include is relying on configuration and docker setup which has not yet been merged to tinkerpop and is being included for reference only. I will update this ticket once the relevant supporting code is included in Tinkerpop and these tests can be run.

       

      Race condition 1:

      func TestClientAgainstSocketServer(t *testing.T) {
         // Integration test variables.
         testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
         settings := FromYaml(getEnvOrDefaultString("GREMLIN_SOCKET_SERVER_CONFIG_PATH", "../../gremlin-tools/gremlin-socket-server/conf/test-ws-gremlin.yaml"))
         testSocketServerUrl := getEnvOrDefaultString("GREMLIN_SOCKET_SERVER_URL", "ws://localhost")
         testSocketServerUrl = fmt.Sprintf("%s:%v/gremlin", testSocketServerUrl, settings.PORT)
      
         t.Run("Should try create new connection if closed by server", func(t *testing.T) {
            skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
            client, _ := NewClient(testSocketServerUrl)
      
            //The server will immediately close the connection upon receiving this request creating a 1005 error
            resultSet, _ := client.Submit("1", map[string]interface{}{"requestId": settings.CLOSE_CONNECTION_REQUEST_ID})
      
            resultSet.One()
      
            client.Close()
         })
      } 
      === RUN   TestClientAgainstSocketServer === CONT  TestClientAgainstSocketServer     testing.go:1319: race detected during execution of test --- FAIL: TestClientAgainstSocketServer (1.04s) === RUN   TestClientAgainstSocketServer/Should_try_create_new_connection_if_closed_by_server 2022/12/16 10:43:37 Connecting. 2022/12/16 10:43:38 Read loop error 'websocket: close 1005 (no status)', closing read loop. 2022/12/16 10:43:38 Read loop error 'websocket: close 1005 (no status)', closing read loop. ================== WARNING: DATA RACE Write at 0x00c000358040 by goroutine 15:   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*channelResultSet).setError()       /Users/coleg/tinkerpop/gremlin-go/driver/resultSet.go:79 +0x80   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*synchronizedMap).closeAll()       /Users/coleg/tinkerpop/gremlin-go/driver/connection.go:154 +0xfc   github.com/apache/tinkerpop/gremlin-go/v3/driver.readErrorHandler()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:93 +0xd8   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*gremlinServerWSProtocol).readLoop()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:70 +0x448   github.com/apache/tinkerpop/gremlin-go/v3/driver.newGremlinServerWSProtocol.func1()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:200 +0x4cPrevious read at 0x00c000358040 by goroutine 8:   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*channelResultSet).One()       /Users/coleg/tinkerpop/gremlin-go/driver/resultSet.go:171 +0x34   github.com/apache/tinkerpop/gremlin-go/v3/driver.TestClientAgainstSocketServer.func1()       /Users/coleg/tinkerpop/gremlin-go/driver/client_test.go:122 +0x1a4   testing.tRunner()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1446 +0x188   testing.(*T).Run.func1()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x40Goroutine 15 (running) created at:   github.com/apache/tinkerpop/gremlin-go/v3/driver.newGremlinServerWSProtocol()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:200 +0x398   github.com/apache/tinkerpop/gremlin-go/v3/driver.createConnection()       /Users/coleg/tinkerpop/gremlin-go/driver/connection.go:110 +0x204   github.com/apache/tinkerpop/gremlin-go/v3/driver.newLoadBalancingPool.func1()       /Users/coleg/tinkerpop/gremlin-go/driver/connectionPool.go:150 +0xa8Goroutine 8 (running) created at:   testing.(*T).Run()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x55c   github.com/apache/tinkerpop/gremlin-go/v3/driver.TestClientAgainstSocketServer()       /Users/coleg/tinkerpop/gremlin-go/driver/client_test.go:115 +0x1cc   testing.tRunner()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1446 +0x188   testing.(*T).Run.func1()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x40 ================== 2022/12/16 10:43:38 Connection error callback invoked, closing protocol. 2022/12/16 10:43:38 Closing Client with url 'ws://localhost:45943/gremlin' ================== WARNING: DATA RACE Read at 0x00c00027dc10 by goroutine 8:   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*connection).close()       /Users/coleg/tinkerpop/gremlin-go/driver/connection.go:68 +0x34   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*loadBalancingPool).close()       /Users/coleg/tinkerpop/gremlin-go/driver/connectionPool.go:57 +0x10c   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*Client).Close()       /Users/coleg/tinkerpop/gremlin-go/driver/client.go:147 +0x2d0   github.com/apache/tinkerpop/gremlin-go/v3/driver.TestClientAgainstSocketServer.func1()       /Users/coleg/tinkerpop/gremlin-go/driver/client_test.go:124 +0x1ac   testing.tRunner()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1446 +0x188   testing.(*T).Run.func1()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x40Previous write at 0x00c00027dc10 by goroutine 15:   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*connection).errorCallback()       /Users/coleg/tinkerpop/gremlin-go/driver/connection.go:58 +0x60   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*connection).errorCallback-fm()       <autogenerated>:1 +0x34   github.com/apache/tinkerpop/gremlin-go/v3/driver.readErrorHandler()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:94 +0xe4   github.com/apache/tinkerpop/gremlin-go/v3/driver.(*gremlinServerWSProtocol).readLoop()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:70 +0x448   github.com/apache/tinkerpop/gremlin-go/v3/driver.newGremlinServerWSProtocol.func1()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:200 +0x4cGoroutine 8 (running) created at:   testing.(*T).Run()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x55c   github.com/apache/tinkerpop/gremlin-go/v3/driver.TestClientAgainstSocketServer()       /Users/coleg/tinkerpop/gremlin-go/driver/client_test.go:115 +0x1cc   testing.tRunner()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1446 +0x188   testing.(*T).Run.func1()       /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x40Goroutine 15 (finished) created at:   github.com/apache/tinkerpop/gremlin-go/v3/driver.newGremlinServerWSProtocol()       /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:200 +0x398   github.com/apache/tinkerpop/gremlin-go/v3/driver.createConnection()       /Users/coleg/tinkerpop/gremlin-go/driver/connection.go:110 +0x204   github.com/apache/tinkerpop/gremlin-go/v3/driver.newLoadBalancingPool.func1()       /Users/coleg/tinkerpop/gremlin-go/driver/connectionPool.go:150 +0xa8 ================== 2022/12/16 10:43:38 Ignoring error closing connection: E0101: cannot close connection that has already been closed or has not been connected     testing.go:1319: race detected during execution of test     --- FAIL: TestClientAgainstSocketServer/Should_try_create_new_connection_if_closed_by_server (1.03s) === CONT       testing.go:1319: race detected during execution of test FAILProcess finished with the exit code 1
      

      Race condition 2:

      func TestClientAgainstSocketServer(t *testing.T) {
         // Integration test variables.
         testNoAuthEnable := getEnvOrDefaultBool("RUN_INTEGRATION_TESTS", true)
         settings := FromYaml(getEnvOrDefaultString("GREMLIN_SOCKET_SERVER_CONFIG_PATH", "../../gremlin-tools/gremlin-socket-server/conf/test-ws-gremlin.yaml"))
         testSocketServerUrl := getEnvOrDefaultString("GREMLIN_SOCKET_SERVER_URL", "ws://localhost")
         testSocketServerUrl = fmt.Sprintf("%s:%v/gremlin", testSocketServerUrl, settings.PORT)
      
         t.Run("Should try create new connection if closed by server", func(t *testing.T) {
            skipTestsIfNotEnabled(t, integrationTestSuiteName, testNoAuthEnable)
            client, _ := NewClient(testSocketServerUrl)
            
            //The server will immediately close the connection upon receiving this request creating a 1005 error
            resultSet, _ := client.Submit("1", map[string]interface{}{"requestId": settings.CLOSE_CONNECTION_REQUEST_ID}) 
      
            //Synchronization added to avoid race condition #1
            time.Sleep(5 * time.Second)
            chResultSet := resultSet.(*channelResultSet)
            chResultSet.channelMutex.Lock()
      
            resultSet.One()
      
            chResultSet.channelMutex.Unlock()
      
            resultSet, _ = client.Submit("1", map[string]interface{}{"requestId": settings.SINGLE_VERTEX_REQUEST_ID})
      
            resultSet.One()
      
            client.Close()
         })
      }
      === RUN   TestClientAgainstSocketServer
      === CONT  TestClientAgainstSocketServer
          testing.go:1319: race detected during execution of test
      --- FAIL: TestClientAgainstSocketServer (5.10s)
      === RUN   TestClientAgainstSocketServer/Should_try_create_new_connection_if_closed_by_server
      2022/12/16 10:36:03 Connecting.
      2022/12/16 10:36:04 Read loop error 'websocket: close 1005 (no status)', closing read loop.
      2022/12/16 10:36:04 Read loop error 'websocket: close 1005 (no status)', closing read loop.
      2022/12/16 10:36:04 Connection error callback invoked, closing protocol.
      ==================
      WARNING: DATA RACE
      Read at 0x00c0002fdc10 by goroutine 8:
        github.com/apache/tinkerpop/gremlin-go/v3/driver.(*loadBalancingPool).getLeastUsedConnection()
            /Users/coleg/tinkerpop/gremlin-go/driver/connectionPool.go:102 +0x154
        github.com/apache/tinkerpop/gremlin-go/v3/driver.(*loadBalancingPool).write()
            /Users/coleg/tinkerpop/gremlin-go/driver/connectionPool.go:74 +0x90
        github.com/apache/tinkerpop/gremlin-go/v3/driver.(*Client).Submit()
            /Users/coleg/tinkerpop/gremlin-go/driver/client.go:154 +0x1d4
        github.com/apache/tinkerpop/gremlin-go/v3/driver.TestClientAgainstSocketServer.func1()
            /Users/coleg/tinkerpop/gremlin-go/driver/client_test.go:129 +0x29c
        testing.tRunner()
            /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1446 +0x188
        testing.(*T).Run.func1()
            /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x40Previous write at 0x00c0002fdc10 by goroutine 15:
        github.com/apache/tinkerpop/gremlin-go/v3/driver.(*connection).errorCallback()
            /Users/coleg/tinkerpop/gremlin-go/driver/connection.go:58 +0x60
        github.com/apache/tinkerpop/gremlin-go/v3/driver.(*connection).errorCallback-fm()
            <autogenerated>:1 +0x34
        github.com/apache/tinkerpop/gremlin-go/v3/driver.readErrorHandler()
            /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:94 +0xe4
        github.com/apache/tinkerpop/gremlin-go/v3/driver.(*gremlinServerWSProtocol).readLoop()
            /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:70 +0x448
        github.com/apache/tinkerpop/gremlin-go/v3/driver.newGremlinServerWSProtocol.func1()
            /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:200 +0x4cGoroutine 8 (running) created at:
        testing.(*T).Run()
            /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x55c
        github.com/apache/tinkerpop/gremlin-go/v3/driver.TestClientAgainstSocketServer()
            /Users/coleg/tinkerpop/gremlin-go/driver/client_test.go:116 +0x1cc
        testing.tRunner()
            /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1446 +0x188
        testing.(*T).Run.func1()
            /opt/homebrew/Cellar/go/1.19.1/libexec/src/testing/testing.go:1493 +0x40Goroutine 15 (finished) created at:
        github.com/apache/tinkerpop/gremlin-go/v3/driver.newGremlinServerWSProtocol()
            /Users/coleg/tinkerpop/gremlin-go/driver/protocol.go:200 +0x398
        github.com/apache/tinkerpop/gremlin-go/v3/driver.createConnection()
            /Users/coleg/tinkerpop/gremlin-go/driver/connection.go:110 +0x204
        github.com/apache/tinkerpop/gremlin-go/v3/driver.newLoadBalancingPool.func1()
            /Users/coleg/tinkerpop/gremlin-go/driver/connectionPool.go:150 +0xa8
      ==================
      2022/12/16 10:36:08 Connecting.
      2022/12/16 10:36:08 Closing Client with url 'ws://localhost:45943/gremlin'
      2022/12/16 10:36:08 Closing the connection.
          testing.go:1319: race detected during execution of test
          --- FAIL: TestClientAgainstSocketServer/Should_try_create_new_connection_if_closed_by_server (5.09s)
      === CONT  
          testing.go:1319: race detected during execution of test
      FAILProcess finished with the exit code 1 

      Attachments

        Activity

          People

            Unassigned Unassigned
            colebq Cole Greer
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

              Created:
              Updated: