1
0
Fork 0

Merge pull request #754 from rqlite/noop-store-test

Support Noop commands in Raft Log
master
Philip O'Toole 4 years ago committed by GitHub
commit a8559b49e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -9,7 +9,9 @@
- [PR #738](https://github.com/rqlite/rqlite/pull/738): Switch to rqlite fork of mattn/go-sqlite3. The SQLite C code remains unchanged.
- [PR #741](https://github.com/rqlite/rqlite/pull/741): Tighten up Store-level locking.
- [PR #747](https://github.com/rqlite/rqlite/pull/747): Time snapshot, restore, and startup times.
- [PR #750](https://github.com/rqlite/rqlite/pull/750): Build on-disk databases in-memory first. Fixes [issue #731](https://github.com/rqlite/rqlite/issues/731).
- [PR #750](https://github.com/rqlite/rqlite/pull/750): Build on-disk databases in-memory first. Fixes [issue #731](https://github.com/rqlite/rqlite/
issues/731).
- [PR #754](https://github.com/rqlite/rqlite/pull/754): Support Noop commands in Raft Log.
## 5.9.0 (January 24th 2021)
### New features

@ -82,6 +82,7 @@ const (
Command_COMMAND_TYPE_EXECUTE Command_Type = 2
Command_COMMAND_TYPE_METADATA_SET Command_Type = 3
Command_COMMAND_TYPE_METADATA_DELETE Command_Type = 4
Command_COMMAND_TYPE_NOOP Command_Type = 5
)
// Enum value maps for Command_Type.
@ -92,6 +93,7 @@ var (
2: "COMMAND_TYPE_EXECUTE",
3: "COMMAND_TYPE_METADATA_SET",
4: "COMMAND_TYPE_METADATA_DELETE",
5: "COMMAND_TYPE_NOOP",
}
Command_Type_value = map[string]int32{
"COMMAND_TYPE_UNKNOWN": 0,
@ -99,6 +101,7 @@ var (
"COMMAND_TYPE_EXECUTE": 2,
"COMMAND_TYPE_METADATA_SET": 3,
"COMMAND_TYPE_METADATA_DELETE": 4,
"COMMAND_TYPE_NOOP": 5,
}
)
@ -126,7 +129,7 @@ func (x Command_Type) Number() protoreflect.EnumNumber {
// Deprecated: Use Command_Type.Descriptor instead.
func (Command_Type) EnumDescriptor() ([]byte, []int) {
return file_command_proto_rawDescGZIP(), []int{7, 0}
return file_command_proto_rawDescGZIP(), []int{8, 0}
}
type Parameter struct {
@ -589,6 +592,53 @@ func (x *MetadataDelete) GetRaftId() string {
return ""
}
type Noop struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (x *Noop) Reset() {
*x = Noop{}
if protoimpl.UnsafeEnabled {
mi := &file_command_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *Noop) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*Noop) ProtoMessage() {}
func (x *Noop) ProtoReflect() protoreflect.Message {
mi := &file_command_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use Noop.ProtoReflect.Descriptor instead.
func (*Noop) Descriptor() ([]byte, []int) {
return file_command_proto_rawDescGZIP(), []int{7}
}
func (x *Noop) GetId() string {
if x != nil {
return x.Id
}
return ""
}
type Command struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
@ -602,7 +652,7 @@ type Command struct {
func (x *Command) Reset() {
*x = Command{}
if protoimpl.UnsafeEnabled {
mi := &file_command_proto_msgTypes[7]
mi := &file_command_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
@ -615,7 +665,7 @@ func (x *Command) String() string {
func (*Command) ProtoMessage() {}
func (x *Command) ProtoReflect() protoreflect.Message {
mi := &file_command_proto_msgTypes[7]
mi := &file_command_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
@ -628,7 +678,7 @@ func (x *Command) ProtoReflect() protoreflect.Message {
// Deprecated: Use Command.ProtoReflect.Descriptor instead.
func (*Command) Descriptor() ([]byte, []int) {
return file_command_proto_rawDescGZIP(), []int{7}
return file_command_proto_rawDescGZIP(), []int{8}
}
func (x *Command) GetType() Command_Type {
@ -708,27 +758,30 @@ var file_command_proto_rawDesc = []byte{
0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x29, 0x0a,
0x0e, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x12,
0x17, 0x0a, 0x07, 0x72, 0x61, 0x66, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x72, 0x61, 0x66, 0x74, 0x49, 0x64, 0x22, 0x8b, 0x02, 0x0a, 0x07, 0x43, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x12, 0x29, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01,
0x28, 0x0e, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x43, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, 0x79, 0x70, 0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12,
0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x62, 0x5f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02,
0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75, 0x62, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x03,
0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f, 0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64,
0x22, 0x93, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70, 0x65, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4d,
0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57,
0x4e, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54,
0x59, 0x50, 0x45, 0x5f, 0x51, 0x55, 0x45, 0x52, 0x59, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43,
0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x45, 0x43,
0x55, 0x54, 0x45, 0x10, 0x02, 0x12, 0x1d, 0x0a, 0x19, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44,
0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53,
0x45, 0x54, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f,
0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x44, 0x45,
0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x42, 0x22, 0x5a, 0x20, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x71, 0x6c, 0x69, 0x74, 0x65, 0x2f, 0x72, 0x71, 0x6c, 0x69,
0x74, 0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
0x52, 0x06, 0x72, 0x61, 0x66, 0x74, 0x49, 0x64, 0x22, 0x16, 0x0a, 0x04, 0x4e, 0x6f, 0x6f, 0x70,
0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64,
0x22, 0xa2, 0x02, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x29, 0x0a, 0x04,
0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x63, 0x6f, 0x6d,
0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x2e, 0x54, 0x79, 0x70,
0x65, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x75, 0x62, 0x5f, 0x63,
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x75,
0x62, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1e, 0x0a, 0x0a, 0x63, 0x6f, 0x6d, 0x70,
0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x63, 0x6f,
0x6d, 0x70, 0x72, 0x65, 0x73, 0x73, 0x65, 0x64, 0x22, 0xaa, 0x01, 0x0a, 0x04, 0x54, 0x79, 0x70,
0x65, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50,
0x45, 0x5f, 0x55, 0x4e, 0x4b, 0x4e, 0x4f, 0x57, 0x4e, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x43,
0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x51, 0x55, 0x45, 0x52,
0x59, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54,
0x59, 0x50, 0x45, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x45, 0x10, 0x02, 0x12, 0x1d, 0x0a,
0x19, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45,
0x54, 0x41, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x45, 0x54, 0x10, 0x03, 0x12, 0x20, 0x0a, 0x1c,
0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4d, 0x45, 0x54,
0x41, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x44, 0x45, 0x4c, 0x45, 0x54, 0x45, 0x10, 0x04, 0x12, 0x15,
0x0a, 0x11, 0x43, 0x4f, 0x4d, 0x4d, 0x41, 0x4e, 0x44, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e,
0x4f, 0x4f, 0x50, 0x10, 0x05, 0x42, 0x22, 0x5a, 0x20, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e,
0x63, 0x6f, 0x6d, 0x2f, 0x72, 0x71, 0x6c, 0x69, 0x74, 0x65, 0x2f, 0x72, 0x71, 0x6c, 0x69, 0x74,
0x65, 0x2f, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f,
0x33,
}
var (
@ -744,7 +797,7 @@ func file_command_proto_rawDescGZIP() []byte {
}
var file_command_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
var file_command_proto_msgTypes = make([]protoimpl.MessageInfo, 9)
var file_command_proto_msgTypes = make([]protoimpl.MessageInfo, 10)
var file_command_proto_goTypes = []interface{}{
(QueryRequest_Level)(0), // 0: command.QueryRequest.Level
(Command_Type)(0), // 1: command.Command.Type
@ -755,8 +808,9 @@ var file_command_proto_goTypes = []interface{}{
(*ExecuteRequest)(nil), // 6: command.ExecuteRequest
(*MetadataSet)(nil), // 7: command.MetadataSet
(*MetadataDelete)(nil), // 8: command.MetadataDelete
(*Command)(nil), // 9: command.Command
nil, // 10: command.MetadataSet.DataEntry
(*Noop)(nil), // 9: command.Noop
(*Command)(nil), // 10: command.Command
nil, // 11: command.MetadataSet.DataEntry
}
var file_command_proto_depIdxs = []int32{
2, // 0: command.Statement.parameters:type_name -> command.Parameter
@ -764,7 +818,7 @@ var file_command_proto_depIdxs = []int32{
4, // 2: command.QueryRequest.request:type_name -> command.Request
0, // 3: command.QueryRequest.level:type_name -> command.QueryRequest.Level
4, // 4: command.ExecuteRequest.request:type_name -> command.Request
10, // 5: command.MetadataSet.data:type_name -> command.MetadataSet.DataEntry
11, // 5: command.MetadataSet.data:type_name -> command.MetadataSet.DataEntry
1, // 6: command.Command.type:type_name -> command.Command.Type
7, // [7:7] is the sub-list for method output_type
7, // [7:7] is the sub-list for method input_type
@ -864,6 +918,18 @@ func file_command_proto_init() {
}
}
file_command_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Noop); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_command_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Command); i {
case 0:
return &v.state
@ -889,7 +955,7 @@ func file_command_proto_init() {
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_command_proto_rawDesc,
NumEnums: 2,
NumMessages: 9,
NumMessages: 10,
NumExtensions: 0,
NumServices: 0,
},

@ -49,6 +49,10 @@ message MetadataDelete {
string raft_id = 1;
}
message Noop {
string id = 1;
}
message Command {
enum Type {
COMMAND_TYPE_UNKNOWN = 0;
@ -56,6 +60,7 @@ message Command {
COMMAND_TYPE_EXECUTE = 2;
COMMAND_TYPE_METADATA_SET = 3;
COMMAND_TYPE_METADATA_DELETE = 4;
COMMAND_TYPE_NOOP = 5;
}
Type type = 1;
bytes sub_command = 2;

@ -165,6 +165,16 @@ func UnMarshalMetadataDelete(b []byte, c *MetadataDelete) error {
return proto.Unmarshal(b, c)
}
// MarshalNoop marshals a Noop command
func MarshalNoop(c *Noop) ([]byte, error) {
return proto.Marshal(c)
}
// UnmarshalNoop unmarshals a Noop command
func UnMarshalNoop(b []byte, c *Noop) error {
return proto.Unmarshal(b, c)
}
// UnmarshalSubCommand unmarshalls a sub command m. It assumes that
// m is the correct type.
func UnmarshalSubCommand(c *Command, m proto.Message) error {

@ -743,6 +743,37 @@ func (s *Store) SetMetadata(md map[string]string) error {
return s.setMetadata(s.raftID, md)
}
// Noop writes a noop command to the Raft log. A noop command simply
// consumes a slot in the Raft log, but has no other affect on the
// system.
func (s *Store) Noop(id string) error {
n := &command.Noop{
Id: id,
}
b, err := command.MarshalNoop(n)
if err != nil {
return err
}
c := &command.Command{
Type: command.Command_COMMAND_TYPE_NOOP,
SubCommand: b,
}
bc, err := command.Marshal(c)
if err != nil {
return err
}
f := s.raft.Apply(bc, s.ApplyTimeout)
if e := f.(raft.Future); e.Error() != nil {
if e.Error() == raft.ErrNotLeader {
return ErrNotLeader
}
return e.Error()
}
return nil
}
// setMetadata adds the metadata md to any existing metadata for
// the given node ID.
func (s *Store) setMetadata(id string, md map[string]string) error {
@ -1022,6 +1053,8 @@ func (s *Store) Apply(l *raft.Log) (e interface{}) {
delete(s.meta, md.RaftId)
}()
return &fsmGenericResponse{}
case command.Command_COMMAND_TYPE_NOOP:
return &fsmGenericResponse{}
default:
return &fsmGenericResponse{error: fmt.Errorf("unhandled command: %v", c.Type)}
}

@ -1155,6 +1155,19 @@ func Test_SingleNodeRestoreNoncompressed(t *testing.T) {
}
}
func Test_SingleNodeNoop(t *testing.T) {
s0 := mustNewStore(true)
if err := s0.Open(true); err != nil {
t.Fatalf("failed to open single-node store: %s", err.Error())
}
defer s0.Close(true)
s0.WaitForLeader(10 * time.Second)
if err := s0.Noop("1"); err != nil {
t.Fatalf("failed to write noop command: %s", err.Error())
}
}
func Test_MetadataMultinode(t *testing.T) {
s0 := mustNewStore(true)
if err := s0.Open(true); err != nil {

Loading…
Cancel
Save