-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add LWTRetryPolicy interface #213
Conversation
// This is a similar interface to RetryPolicy | ||
// If a query is recognized as LWT query it, and its RetryPolicy satisfies this | ||
// interface, then this interface will be used instead of RetryPolicy. | ||
type LWTRetryPolicy interface { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since RetryableQuery
and ExecutableQuery
are tightly connected to each other, I would suggest to add IsLWT() bool
to RetryableQuery
and change RetryPolicy.GetRetryType
to GetRetryType(RetryableQuery, error) RetryType
Yes, it is going to be a breaking change, but very light in a sence of fixing it and if user is using built-in retrypolicy it is going to be autoresolved.
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not sure about doing breaking changes. It is a high priority issue and we want to be able to merge it and release as quickly as possible
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know what is the policy about breaking changes in gocql, because I don't usually work on this driver and I'm not a maintainer. If you want me to I can implement proposed changes.
My thinking with avoiding breaking changes was:
- Afaik Golang itself maintains backwards compatibility, so I assume its expected in the libraries too
- Even without breaking changes customers often stay on older version. If updating requires changes it will be harder to move users to current version
- It's not just incompatibility with our old version, but with upstream gocql too, so it makes migration harder (and possibly merges with upstream too)
- If it is acceptable to introduce a breaking change, then we can do that in the future too, removing
LWTRetryPolicy
and applying your proposed change toRetryPolicy
.
func (s *SimpleRetryPolicy) GetRetryTypeLWT(err error) RetryType { | ||
return Retry | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we really do this unconditionally, even if error returned by the DB signifies unability to serve requests? E.g., ServerError
or Overloaded
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My thinking was that as long as we have open connections to the node, it may (at some point) perform the request, so the policy can keep trying.
If we loose connection, then the driver will move to the next node.
It seemed safer to avoid LWT contention at all cost.
func (e *ExponentialBackoffRetryPolicy) GetRetryTypeLWT(err error) RetryType { | ||
return Retry | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
1a2bf5f
to
2853dcd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is one more policy left to cover - DowngradingConsistencyRetryPolicy
There is. I'm not sure how it should be modify, I'd really like some advice |
IMO the only change needed for LWT case is replacing the only occurence of |
AFAIK LWT Queries are run in |
Good catch about this |
But in that case it's no longer |
2853dcd
to
197e902
Compare
@wprzytula failed test is flaky according to @sylwiaszunejko , could you rerun CI? |
The idea is to use a higher consistency level normally, but as an exception allow lower consistency when higher cannot be immediately obtained because of write/read timeout. This is to cope with spikes of load over short time that would otherwise result in timeouts due to requested consistency not reached in time. Datastax recommends in their drivers using DowngradingConsistencyRetryPolicy always with logging its decisions turned on, to debug issues caused by its too consistency downgrades. |
Applications choose a consistency level used that is required for their correctness. If the application is still correct with lower consistency level, then it can use this lower level. If it is not, then downgrading consistency will make the application not correct. |
See java driver documentation for reference. |
197e902
to
47b4bb5
Compare
RetryPolicy may want to return different decisions from `GetRetryType` depending on whether query is LWT or not - to prevent executing LWT on non-primary replica. This is not possible with current interface, because `GetRetryType` doesn't know the query type. This commit introduces new interface, `LWTRetryPolicy`. If configured retry policy also implements `LWTRetryPolicy`, then methods from `LWTRetryPolicy` will be called fro LWT statements instead of methods from `RetryPolicy`.
47b4bb5
to
44c91c7
Compare
RetryPolicy may want to return different decisions from
GetRetryType
depending on whether query is LWT or not - to prevent executing LWT on non-primary replica.This is not possible with current interface, because
GetRetryType
doesn't know the query type.This PR introduces new interface,
LWTRetryPolicy
. If configured retry policy also implementsLWTRetryPolicy
, then methods fromLWTRetryPolicy
will be called for LWT statements instead of methods fromRetryPolicy
.There are alternative approaches to this issue: