apache / apache/cassandra-gocql-driver
HostPoolHostPolicy causes infinite loop/spin when used as fallback for TokenAwareHostPolicy
- Dominant language
- Go
- Stars
- 2.7k
- Forks
- 658
- PR merge metrics
- No merged PRs in 30d
Description
### What version of Cassandra are you using?
2.2.8 (but not relevant)
### What version of Gocql are you using?
v0.0.0-20181124151448-70385f88b28b (in go.mod)
### What did you do?
Used a HostPoolHostPolicy as the fallback for a TokenAwareHostPolicy:
```
cluster.PoolConfig.HostSelectionPolicy = gocql.TokenAwareHostPolicy(
gocql.HostPoolHostPolicy(
hostpool.NewEpsilonGreedy(nil, 0, &hostpool.LinearEpsilonValueCalculator{}),
),
)
```
### What did you expect to see?
The token-aware policy falls back correctly to the host-pool policy.
### What did you see instead?
The CPU spins at 100%. The gocql code has entered a busy loop.
---
### Cause
In the `(*tokenAwareHostPolicy).Pick` function, the fallbackIter is repeatedly queried until it returns nil. However, HostPoolHostPolicy never returns nil, and repeated calls return the same host repeatedly, so the loop spins forever.
Suggested fix:
```
func (r *hostPoolHostPolicy) Pick(qry ExecutableQuery) NextHost {
+ used := false
return func() SelectedHost {
+ if used {
+ return nil
+ }
+ used = true
+
r.mu.RLock()
defer r.mu.RUnlock()
if len(r.hostMap) == 0 {
return nil
}
hostR := r.hp.Get()
host, ok := r.hostMap[hostR.Host()]
if !ok {
return nil
}
return selectedHostPoolHost{
policy: r,
info: host,
hostR: hostR,
}
}
}
```
Contributor guide
Research direction
Start by reading tokenAwareHostPolicy.Pick and hostPoolHostPolicy.Pick, then reproduce the reported TokenAwareHostPolicy/HostPoolHostPolicy configuration. Verify that the fallback iterator returns a host once and then terminates instead of spinning, and add or update coverage if an existing test location is found.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cassandra, go
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Stale
- Clarity
- Clearly specified
- Newbie friendliness
- 45/100