forked from apache/cassandra-gocql-driver
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Remove the atomic waiting variable, it can lead to a case where a stream is released twice which will cause data races and unforseen panics. The case this can happen is that in exec the frame is written and the response is received before call.waiting is set from 0 to 1. This is most likely down to the runtime scheduling the recv() io goroutine before the atomic store happens. The recv() goroutine sees that call.waiting is 0 and assumes that is has timed out, releasing the stream. Then the exec() goroutine is scheduled which sets call.waiting to 1 and then blocks in the select waiting for the response, which never comes so the timeout option is selected which then releases the stream again. Solve this by removing the call.waiting synchronisation which was not protecting anything as the channels were providing specific synchronisation points. Add a stress test benchmark which can reproduce panics that this patch fixes. Updates apache#439, apache#435, apache#437, apache#430
- Loading branch information
Showing
3 changed files
with
82 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// +build all integration | ||
|
||
package gocql | ||
|
||
import ( | ||
"sync/atomic" | ||
|
||
"testing" | ||
) | ||
|
||
func BenchmarkConnStress(b *testing.B) { | ||
const workers = 16 | ||
|
||
cluster := createCluster() | ||
cluster.NumConns = 1 | ||
cluster.NumStreams = workers | ||
session := createSessionFromCluster(cluster, b) | ||
defer session.Close() | ||
|
||
if err := createTable(session, "CREATE TABLE IF NOT EXISTS conn_stress (id int primary key)"); err != nil { | ||
b.Fatal(err) | ||
} | ||
|
||
var seed uint64 | ||
writer := func(pb *testing.PB) { | ||
seed := atomic.AddUint64(&seed, 1) | ||
var i uint64 = 0 | ||
for pb.Next() { | ||
if err := session.Query("insert into conn_stress (id) values (?)", i*seed).Exec(); err != nil { | ||
b.Error(err) | ||
return | ||
} | ||
i++ | ||
} | ||
} | ||
|
||
b.SetParallelism(workers) | ||
b.RunParallel(writer) | ||
|
||
} |