It is possible to get the influxdb2.Client to panic if Client.Close() is called at the same time from multiple goroutines:
panic: close of closed channel
goroutine 341 [running]:
github.com/influxdata/influxdb-client-go/v2/api.(*WriteAPIImpl).Close(0xc0001b15e0)
/go/pkg/mod/github.com/influxdata/influxdb-client-go/v2@v2.2.0/api/write.go:176 +0x6f
github.com/influxdata/influxdb-client-go/v2.(*clientImpl).Close(0xc00064e0c0)
/go/pkg/mod/github.com/influxdata/influxdb-client-go/v2@v2.2.0/client.go:218 +0x8e
It appears the cause is that on calling Client.Close, it is looping through all non-blocking WriteAPI's, and closing a channel on the struct. Before doing this channel closing, the Close method mkes sure the channel is not nil. The channel is set to nilafter some processing is done, so two goroutines can pass this nil check, causing them both to attempt to close the channel.
I think a fix to this would be to place a shutdown mutex on the non-blocking WriteAPI object, lock it when WriteAPI.Close() is called, set the channel to nil with the lock, and check for the channel being nil after the lock is acquired. That way, if two goroutines call client.Close() at the same time, the second goroutine will see that the first has set the channel to nil, and will not attempt the shutdown processing.
Steps to reproduce:
Create one influxdb2.Client object to be accessed from multiple goroutines
Start a goroutine reading from influxdb every second, calling a defer client.Close()
Start a goroutine writing 300 points once per second using non-blocking WriteAPI, also calling defer client.Close() at the end of its call
There should be a panic within a few seconds
Expected behavior:
There should be no panic if two goroutines try to close the client.
Actual behavior:
The client panics
Specifications:
Client Version: 2.2.0
InfluxDB Version: 2.1
Platform: Linux
Edit: I haven't used the latest client, but checked the 2.8.1 tag and see the same issue should still exist in latest.
It is possible to get the
influxdb2.Client
to panic ifClient.Close()
is called at the same time from multiple goroutines:It appears the cause is that on calling
Client.Close
, it is looping through all non-blocking WriteAPI's, and closing a channel on the struct. Before doing this channel closing, theClose
method mkes sure the channel is not nil. The channel is set tonil
after some processing is done, so two goroutines can pass thisnil
check, causing them both to attempt to close the channel.I think a fix to this would be to place a
shutdown
mutex on the non-blocking WriteAPI object, lock it whenWriteAPI.Close()
is called, set the channel tonil
with the lock, and check for the channel beingnil
after the lock is acquired. That way, if two goroutines callclient.Close()
at the same time, the second goroutine will see that the first has set the channel tonil
, and will not attempt the shutdown processing.Steps to reproduce:
influxdb2.Client
object to be accessed from multiple goroutinesdefer client.Close()
defer client.Close()
at the end of its callExpected behavior: There should be no panic if two goroutines try to close the client.
Actual behavior: The client panics
Specifications:
Edit: I haven't used the latest client, but checked the 2.8.1 tag and see the same issue should still exist in latest.