toptobes commented on code in PR #1943:
URL:
https://github.com/apache/cassandra-gocql-driver/pull/1943#discussion_r3607108512
##########
query_executor.go:
##########
@@ -69,16 +71,151 @@ type internalRequest interface {
}
type queryExecutor struct {
- pool *policyConnPool
- policy HostSelectionPolicy
+ pool *policyConnPool
+ policy HostSelectionPolicy
+ interceptor ExecAttemptInterceptor
}
-func (q *queryExecutor) attemptQuery(ctx context.Context, qry internalRequest,
conn *Conn) *Iter {
+type OpType int
+
+const (
+ OpQuery OpType = iota
+ OpBatch
+)
+
+type ImmutableQuery interface {
+ Statement() string
+ Values() []interface{}
+}
+
+type immutableQuery struct {
+ query *Query
+}
+
+func (q *immutableQuery) Statement() string {
+ return q.query.stmt
+}
+
+func (q *immutableQuery) Values() []interface{} {
+ return q.query.values
+}
+
+type ImmutableBatch interface {
+ Type() BatchType
+ Entries() []BatchEntry
+ Cons() Consistency
+}
+
+type immutableBatch struct {
+ batch *Batch
+}
+
+func (b *immutableBatch) Type() BatchType {
+ return b.batch.Type
+}
+
+func (b *immutableBatch) Entries() []BatchEntry {
+ return b.batch.Entries
+}
+
+func (b *immutableBatch) Cons() Consistency {
+ return b.batch.Cons
+}
+
+type QueryAttempt struct {
+ // The op type, whether query or batch.
+ Type OpType
+ // Only one of Query or Batch will be set, depending on the op type.
+ Query ImmutableQuery
+ Batch ImmutableBatch
+ // The host that will receive the query.
+ Host *HostInfo
+ // The local address of the connection used to execute the query.
+ LocalAddr net.Addr
+ // The remote address of the connection used to execute the query.
+ RemoteAddr net.Addr
+ // The number of this query attempt. 0 for the initial attempt, 1 for
the first retry, etc. Note that there may be multiple serial Attempts to
different hosts within a single execution, whether main execution or
speculative.
+ Attempts int
+ // The index of the speculative execution attempt this attempt is
associated with, starting with index 1. -1 indicates this is the "main"
execution.
+ SpeculativeExecutionCount int
+}
+
+// QueryAttemptHandler is a function that attempts query execution. The
interceptor must call this once if it does not return an error.
+type QueryAttemptHandler = func(context.Context) (*Iter, error)
+
+// ExecAttemptInterceptor is the interface implemented by interceptors /
middleware.
+//
+// Interceptors are well-suited to logic that is not specific to a single
query or batch, such as flow control.
+type ExecAttemptInterceptor interface {
+ // Intercept is invoked once immediately before a query or batch
execution attempt, including retry attempts and
+ // speculative execution attempts.
+ //
+ // The interceptor is responsible for calling the `handler` function
and returning the handler result. If the
+ // interceptor wants to bypass the handler and skip query execution, it
should return an error. Failure to
+ // return either the handler result or an error will panic.
+ //
+ // Note that there is no affordance to mutate the query or batch at
this stage -- the handler already encapsulates the original query/batch and
cannot be modified.
+ Intercept(ctx context.Context, attempt QueryAttempt, handler
QueryAttemptHandler) (*Iter, error)
+}
+
+// Use an ExecAttemptInterceptorChain to apply multiple Interceptors at
Intercept time.
+type ExecAttemptInterceptorChain struct {
+ Interceptors []ExecAttemptInterceptor
+}
+
+func (c ExecAttemptInterceptorChain) Intercept(
+ ctx context.Context,
+ attempt QueryAttempt,
+ handler QueryAttemptHandler,
+) (*Iter, error) {
+ return c.Interceptors[0].Intercept(ctx, attempt, c.getNextHandler(0,
attempt, handler))
Review Comment:
I believe this will panic without mercy if you create an empty chain (didn't
see any checks which would stop `Intercept` being called here in case of an
empty chain)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]