Skip to content

Commit

Permalink
Use a truly random Destination for DestinationAnyShard
Browse files Browse the repository at this point in the history
Signed-off-by: Aaron Young <[email protected]>
  • Loading branch information
eeSeeGee committed Jan 15, 2019
1 parent b06cf39 commit 87a9adf
Show file tree
Hide file tree
Showing 8 changed files with 416 additions and 352 deletions.
23 changes: 20 additions & 3 deletions go/vt/key/destination.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package key
import (
"bytes"
"encoding/hex"
"math/rand"
"strings"

"vitess.io/vitess/go/vt/vterrors"
Expand All @@ -27,6 +28,9 @@ import (
vtrpcpb "vitess.io/vitess/go/vt/proto/vtrpc"
)

// AnyShardPicker makes a choice on what shard to use when any shard will do. Used for testing.
var AnyShardPicker DestinationAnyShardPicker = DestinationAnyShardPickerRandomShard{}

// Destination is an interface definition for a query destination,
// within a given Keyspace / Tablet Type. It is meant to be an internal
// data structure, with multiple possible implementations.
Expand Down Expand Up @@ -369,12 +373,25 @@ func (d DestinationKeyspaceIDs) String() string {
return buffer.String()
}

// DestinationAnyShardPicker exposes an interface that will pick an index given a number of available shards.
type DestinationAnyShardPicker interface {
// PickShard picks a shard given a number of shards
PickShard(shardCount int) int
}

// DestinationAnyShardPickerRandomShard picks a random shard.
type DestinationAnyShardPickerRandomShard struct{}

// PickShard is DestinationAnyShardPickerRandomShard's implmentation.
func (dp DestinationAnyShardPickerRandomShard) PickShard(shardCount int) int {
return rand.Intn(shardCount)
}

//
// DestinationAnyShard
//

// DestinationAnyShard is the destination for any one shard in the
// keyspace. This usually maps to the first one in the list.
// DestinationAnyShard is the destination for any one shard in the keyspace.
// It implements the Destination interface.
type DestinationAnyShard struct{}

Expand All @@ -388,7 +405,7 @@ func (d DestinationAnyShard) Resolve(allShards []*topodatapb.ShardReference, add
if len(allShards) == 0 {
return vterrors.Errorf(vtrpcpb.Code_UNAVAILABLE, "no shard in keyspace")
}
return addShard(allShards[0].Name)
return addShard(allShards[AnyShardPicker.PickShard(len(allShards))].Name)
}

// String is part of the Destination interface.
Expand Down
31 changes: 31 additions & 0 deletions go/vt/vtgate/engine/insert.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,37 @@ type Insert struct {
MultiShardAutocommit bool
}

// NewQueryInsert creates an Insert with a query string.
func NewQueryInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, query string) *Insert {
return &Insert{
Opcode: opcode,
Keyspace: keyspace,
Query: query,
}
}

// NewSimpleInsert creates an Insert for a Table.
func NewSimpleInsert(opcode InsertOpcode, table *vindexes.Table, keyspace *vindexes.Keyspace) *Insert {
return &Insert{
Opcode: opcode,
Table: table,
Keyspace: keyspace,
}
}

// NewInsert creates a new Insert.
func NewInsert(opcode InsertOpcode, keyspace *vindexes.Keyspace, vindexValues []sqltypes.PlanValue, table *vindexes.Table, prefix string, mid []string, suffix string) *Insert {
return &Insert{
Opcode: opcode,
Keyspace: keyspace,
VindexValues: vindexValues,
Table: table,
Prefix: prefix,
Mid: mid,
Suffix: suffix,
}
}

// MarshalJSON serializes the Insert into a JSON representation.
// It's used for testing and diagnostics.
func (ins *Insert) MarshalJSON() ([]byte, error) {
Expand Down
Loading

0 comments on commit 87a9adf

Please sign in to comment.