cleanup and comments

This commit is contained in:
Sergey Cherepanov 2022-10-07 15:06:54 +03:00 committed by Mikhail Iudin
parent 7bb3d5e144
commit 77aa5a65d9
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
10 changed files with 78 additions and 87 deletions

View File

@ -14,7 +14,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/config" "github.com/anytypeio/go-anytype-infrastructure-experiments/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusclient"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserrs" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr"
"github.com/anytypeio/go-anytype-infrastructure-experiments/node/account" "github.com/anytypeio/go-anytype-infrastructure-experiments/node/account"
"go.uber.org/zap" "go.uber.org/zap"
"gopkg.in/mgo.v2/bson" "gopkg.in/mgo.v2/bson"
@ -154,7 +154,7 @@ func testCreateLogAndRecord(service consensusclient.Service) (err error) {
}, },
}, },
}) })
if err != consensuserrs.ErrLogExists { if err != consensuserr.ErrLogExists {
return fmt.Errorf("unexpected error: '%v' want LogExists", zap.Error(err)) return fmt.Errorf("unexpected error: '%v' want LogExists", zap.Error(err))
} }
err = nil err = nil
@ -181,7 +181,7 @@ func testCreateLogAndRecord(service consensusclient.Service) (err error) {
PrevId: []byte(bson.NewObjectId()), PrevId: []byte(bson.NewObjectId()),
CreatedUnix: uint64(time.Now().Unix()), CreatedUnix: uint64(time.Now().Unix()),
}) })
if err != consensuserrs.ErrConflict { if err != consensuserr.ErrConflict {
return fmt.Errorf("unexpected error: '%v' want Conflict", zap.Error(err)) return fmt.Errorf("unexpected error: '%v' want Conflict", zap.Error(err))
} }
err = nil err = nil

View File

@ -59,7 +59,6 @@ func (ErrCodes) EnumDescriptor() ([]byte, []int) {
type Log struct { type Log struct {
Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
Records []*Record `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"` Records []*Record `protobuf:"bytes,2,rep,name=records,proto3" json:"records,omitempty"`
CreatedUnix uint64 `protobuf:"varint,3,opt,name=createdUnix,proto3" json:"createdUnix,omitempty"`
} }
func (m *Log) Reset() { *m = Log{} } func (m *Log) Reset() { *m = Log{} }
@ -109,13 +108,6 @@ func (m *Log) GetRecords() []*Record {
return nil return nil
} }
func (m *Log) GetCreatedUnix() uint64 {
if m != nil {
return m.CreatedUnix
}
return 0
}
type Record struct { type Record struct {
Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` Id []byte `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
PrevId []byte `protobuf:"bytes,2,opt,name=prevId,proto3" json:"prevId,omitempty"` PrevId []byte `protobuf:"bytes,2,opt,name=prevId,proto3" json:"prevId,omitempty"`
@ -436,37 +428,37 @@ func init() {
} }
var fileDescriptor_b8d7f1c16b400059 = []byte{ var fileDescriptor_b8d7f1c16b400059 = []byte{
// 480 bytes of a gzipped FileDescriptorProto // 474 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x41, 0x8b, 0xd3, 0x40, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x94, 0x53, 0x4f, 0x8b, 0xd3, 0x40,
0x14, 0xee, 0x24, 0x6b, 0xb7, 0x7d, 0x69, 0xbb, 0xf1, 0xb1, 0x48, 0xe8, 0x62, 0x08, 0xf1, 0x12, 0x14, 0xef, 0x24, 0xb5, 0xdb, 0xbe, 0xb4, 0xdd, 0xf8, 0x58, 0x24, 0x74, 0x31, 0x84, 0x78, 0x09,
0x44, 0xba, 0x52, 0x05, 0x4f, 0x1e, 0xd6, 0x52, 0xa1, 0x52, 0x2d, 0x04, 0xaa, 0xe0, 0xc9, 0x98, 0x22, 0x5d, 0xa9, 0x82, 0x27, 0x0f, 0x6b, 0xa9, 0x50, 0xa9, 0x16, 0x02, 0x55, 0xf0, 0x64, 0xcc,
0x99, 0xc6, 0xb0, 0x21, 0x53, 0x67, 0xd2, 0xb5, 0xfb, 0x2f, 0xfc, 0x21, 0xfe, 0x10, 0x6f, 0xee, 0x4c, 0x63, 0xd8, 0x90, 0xa9, 0x33, 0xe9, 0xda, 0xfd, 0x16, 0x7e, 0x10, 0x3f, 0x88, 0x37, 0xf7,
0xd1, 0xa3, 0xb4, 0x7f, 0x44, 0x3a, 0x69, 0x6a, 0xb2, 0xdd, 0x1e, 0xbc, 0x24, 0x79, 0xdf, 0x37, 0xe8, 0x51, 0xda, 0x2f, 0x22, 0x9d, 0x34, 0x35, 0x71, 0xb7, 0x87, 0xbd, 0x24, 0xf3, 0x7e, 0xbf,
0xef, 0x7d, 0xdf, 0xbc, 0x8f, 0xc0, 0x79, 0xc8, 0x53, 0xc9, 0x52, 0xb9, 0x90, 0xff, 0xbe, 0xe6, 0xf7, 0xe7, 0x37, 0xef, 0xc7, 0xc0, 0x59, 0xc8, 0x53, 0xc9, 0x52, 0xb9, 0x94, 0xff, 0x4e, 0x0b,
0x82, 0x67, 0xfc, 0x5c, 0x3d, 0x4b, 0x68, 0x4f, 0x01, 0xd8, 0x0a, 0xd2, 0xeb, 0x41, 0x81, 0xb9, 0xc1, 0x33, 0x7e, 0xa6, 0xbe, 0x25, 0xb4, 0xaf, 0x00, 0x6c, 0x07, 0xe9, 0xd5, 0xb0, 0xc0, 0xdc,
0x11, 0xe8, 0x63, 0x1e, 0x61, 0x07, 0xb4, 0x98, 0x5a, 0xc4, 0x21, 0x5e, 0xcb, 0xd7, 0x62, 0x8a, 0x11, 0xe8, 0x13, 0x1e, 0x61, 0x17, 0xb4, 0x98, 0x5a, 0xc4, 0x21, 0x5e, 0xdb, 0xd7, 0x62, 0x8a,
0x3d, 0x38, 0x16, 0x2c, 0xe4, 0x82, 0x4a, 0x4b, 0x73, 0x74, 0xcf, 0xe8, 0x9f, 0xf6, 0xca, 0x6d, 0x7d, 0x38, 0x12, 0x2c, 0xe4, 0x82, 0x4a, 0x4b, 0x73, 0x74, 0xcf, 0x18, 0x9c, 0xf4, 0xcb, 0x65,
0x3d, 0x5f, 0x91, 0x7e, 0x71, 0x08, 0x1d, 0x30, 0x42, 0xc1, 0x82, 0x8c, 0xd1, 0x69, 0x1a, 0x2f, 0x7d, 0x5f, 0x91, 0x7e, 0x91, 0xe4, 0x26, 0xd0, 0xc8, 0xa1, 0x1b, 0x9d, 0x1e, 0x40, 0x63, 0x21,
0x2d, 0xdd, 0x21, 0xde, 0x91, 0x5f, 0x86, 0xdc, 0x04, 0xea, 0x79, 0xd3, 0x9e, 0xd6, 0x03, 0xa8, 0xd8, 0xe5, 0x98, 0x5a, 0x9a, 0xc2, 0x76, 0x11, 0x5a, 0x70, 0xb4, 0x08, 0xae, 0x12, 0x1e, 0x50,
0xcf, 0x05, 0xbb, 0x1a, 0x51, 0x4b, 0x53, 0xd8, 0xb6, 0x42, 0x0b, 0x8e, 0xe7, 0xc1, 0x75, 0xc2, 0x4b, 0x57, 0x44, 0x11, 0xa2, 0x03, 0x46, 0x28, 0x58, 0x90, 0x31, 0x3a, 0x4b, 0xe3, 0x95, 0x55,
0x03, 0xaa, 0xe6, 0xb5, 0xfc, 0xa2, 0xbc, 0xad, 0x76, 0xb4, 0xaf, 0x76, 0x04, 0xda, 0xe4, 0xd2, 0x77, 0x88, 0x57, 0xf7, 0xcb, 0x90, 0x5b, 0x07, 0x6d, 0x7a, 0xe1, 0x3e, 0x87, 0xce, 0x39, 0xa5,
0x7d, 0x0e, 0xed, 0x0b, 0x4a, 0xc7, 0x3c, 0xf2, 0xd9, 0xd7, 0x05, 0x93, 0x19, 0x3e, 0x02, 0x3d, 0x13, 0x1e, 0xf9, 0xec, 0xeb, 0x92, 0xc9, 0x0c, 0x1f, 0x81, 0x9e, 0xf0, 0x48, 0xcd, 0x36, 0x06,
0xe1, 0x91, 0xd2, 0x36, 0xfa, 0xf7, 0xab, 0x57, 0xda, 0x1c, 0xdb, 0xb0, 0xee, 0x7b, 0x30, 0x2f, 0xf7, 0xab, 0x82, 0xb7, 0x69, 0x5b, 0xd6, 0x7d, 0x0f, 0xe6, 0x39, 0xa5, 0x3b, 0xfd, 0xbb, 0xc2,
0x28, 0xdd, 0xde, 0x70, 0xdb, 0x78, 0x0a, 0xf7, 0x12, 0x1e, 0x8d, 0x0a, 0xdb, 0x79, 0x81, 0x4f, 0x13, 0xb8, 0x97, 0xf0, 0x68, 0x5c, 0xc8, 0xce, 0x03, 0x7c, 0x02, 0x8d, 0xfc, 0x7a, 0x4a, 0xf9,
0xa0, 0x9e, 0x2f, 0x40, 0x39, 0x3f, 0xb4, 0xa4, 0xed, 0x19, 0xf7, 0x2d, 0x9c, 0x7c, 0x08, 0xb2, 0xa1, 0x15, 0xec, 0x72, 0xdc, 0xb7, 0x70, 0xfc, 0x21, 0xc8, 0xc2, 0x2f, 0x25, 0x3d, 0x3d, 0x68,
0xf0, 0x4b, 0xc9, 0x4f, 0x17, 0x1a, 0xdf, 0x36, 0xd0, 0x88, 0x4a, 0x8b, 0x38, 0xba, 0xd7, 0xf2, 0x7e, 0xdb, 0x42, 0x63, 0x2a, 0x2d, 0xe2, 0xe8, 0x5e, 0xdb, 0xdf, 0xc7, 0x68, 0x03, 0x2c, 0xd3,
0x77, 0x35, 0xda, 0x00, 0x8b, 0x74, 0xc7, 0x6a, 0x8a, 0x2d, 0x21, 0xee, 0x14, 0xda, 0xc5, 0xb8, 0x3d, 0xab, 0x29, 0xb6, 0x84, 0xb8, 0x33, 0xe8, 0x14, 0xed, 0x46, 0x97, 0x2c, 0x3d, 0xa4, 0xf1,
0xe1, 0x15, 0x4b, 0x0f, 0x79, 0xfc, 0xcf, 0x24, 0x1f, 0x7f, 0x82, 0xc6, 0x50, 0x88, 0x01, 0xa7, 0x8e, 0x3e, 0x3d, 0xfe, 0x04, 0xcd, 0x91, 0x10, 0x43, 0x4e, 0x99, 0xc4, 0x2e, 0xc0, 0x2c, 0x65,
0x4c, 0x62, 0x07, 0x60, 0x9a, 0xb2, 0xe5, 0x9c, 0x85, 0x19, 0xa3, 0x66, 0x0d, 0xdb, 0xd0, 0xdc, 0xab, 0x05, 0x0b, 0x33, 0x46, 0xcd, 0x1a, 0x76, 0xa0, 0xb5, 0x9d, 0xb6, 0x8a, 0x65, 0x26, 0x4d,
0xa8, 0x2d, 0x63, 0x99, 0x49, 0x93, 0xe0, 0x09, 0x18, 0x63, 0x1e, 0xbd, 0xe3, 0xd9, 0x6b, 0xbe, 0x82, 0xc7, 0x60, 0x4c, 0x78, 0xf4, 0x8e, 0x67, 0xaf, 0xf9, 0x32, 0xa5, 0xa6, 0x86, 0x08, 0xdd,
0x48, 0xa9, 0xa9, 0x21, 0x42, 0x27, 0x1f, 0x37, 0xe0, 0xe9, 0x2c, 0x89, 0xc3, 0xcc, 0xd4, 0xd1, 0xbc, 0xdd, 0x90, 0xa7, 0xf3, 0x24, 0x0e, 0x33, 0x53, 0x47, 0x13, 0x8c, 0x91, 0x10, 0x5c, 0x4c,
0x04, 0x63, 0x28, 0x04, 0x17, 0x93, 0xd9, 0x4c, 0xb2, 0xcc, 0xfc, 0xa1, 0xf5, 0x7f, 0x11, 0x68, 0xe7, 0x73, 0xc9, 0x32, 0xf3, 0x87, 0x36, 0xf8, 0x45, 0xa0, 0xb5, 0x9f, 0x8f, 0x2f, 0xa0, 0x91,
0xee, 0xf4, 0xf1, 0x05, 0xd4, 0xf3, 0x8c, 0xf0, 0xac, 0x6a, 0xac, 0x92, 0x5c, 0xd7, 0xac, 0x92, 0x7b, 0x84, 0xa7, 0x55, 0x61, 0x15, 0xe7, 0x7a, 0x66, 0x95, 0x9c, 0x5e, 0xe0, 0x4b, 0x68, 0xed,
0x93, 0x4b, 0x7c, 0x09, 0xcd, 0x5d, 0x4c, 0x68, 0xef, 0xf5, 0x56, 0xf2, 0xbb, 0xa3, 0xfd, 0x0d, 0x6d, 0x42, 0xfb, 0x46, 0x6d, 0xc5, 0xbf, 0x5b, 0xca, 0xdf, 0x40, 0xb3, 0x58, 0x1f, 0x3e, 0xac,
0x34, 0x8a, 0xf5, 0xe1, 0xc3, 0x2a, 0x7b, 0x2b, 0xa5, 0xee, 0xd9, 0xdd, 0xb4, 0xda, 0xba, 0x47, 0xb2, 0xff, 0xb9, 0xd4, 0x3b, 0xbd, 0x9d, 0x56, 0x5b, 0xf7, 0xc8, 0x53, 0xf2, 0x6a, 0xf0, 0x73,
0x9e, 0x92, 0x57, 0xfd, 0x9f, 0x2b, 0x9b, 0xdc, 0xac, 0x6c, 0xf2, 0x67, 0x65, 0x93, 0xef, 0x6b, 0x6d, 0x93, 0xeb, 0xb5, 0x4d, 0xfe, 0xac, 0x6d, 0xf2, 0x7d, 0x63, 0xd7, 0xae, 0x37, 0x76, 0xed,
0xbb, 0x76, 0xb3, 0xb6, 0x6b, 0xbf, 0xd7, 0x76, 0xed, 0xa3, 0x75, 0xe8, 0xef, 0xfc, 0x5c, 0x57, 0xf7, 0xc6, 0xae, 0x7d, 0xb4, 0x0e, 0xbd, 0xbd, 0xcf, 0x0d, 0xf5, 0x7b, 0xf6, 0x37, 0x00, 0x00,
0xaf, 0x67, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0xf0, 0xc9, 0xa1, 0x1f, 0xc0, 0x03, 0x00, 0x00, 0xff, 0xff, 0x9f, 0x6e, 0xb2, 0xf8, 0x9e, 0x03, 0x00, 0x00,
} }
func (m *Log) Marshal() (dAtA []byte, err error) { func (m *Log) Marshal() (dAtA []byte, err error) {
@ -489,11 +481,6 @@ func (m *Log) MarshalToSizedBuffer(dAtA []byte) (int, error) {
_ = i _ = i
var l int var l int
_ = l _ = l
if m.CreatedUnix != 0 {
i = encodeVarintConsensus(dAtA, i, uint64(m.CreatedUnix))
i--
dAtA[i] = 0x18
}
if len(m.Records) > 0 { if len(m.Records) > 0 {
for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- { for iNdEx := len(m.Records) - 1; iNdEx >= 0; iNdEx-- {
{ {
@ -779,9 +766,6 @@ func (m *Log) Size() (n int) {
n += 1 + l + sovConsensus(uint64(l)) n += 1 + l + sovConsensus(uint64(l))
} }
} }
if m.CreatedUnix != 0 {
n += 1 + sovConsensus(uint64(m.CreatedUnix))
}
return n return n
} }
@ -991,25 +975,6 @@ func (m *Log) Unmarshal(dAtA []byte) error {
return err return err
} }
iNdEx = postIndex iNdEx = postIndex
case 3:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field CreatedUnix", wireType)
}
m.CreatedUnix = 0
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowConsensus
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
m.CreatedUnix |= uint64(b&0x7F) << shift
if b < 0x80 {
break
}
}
default: default:
iNdEx = preIndex iNdEx = preIndex
skippy, err := skipConsensus(dAtA[iNdEx:]) skippy, err := skipConsensus(dAtA[iNdEx:])

View File

@ -1,4 +1,4 @@
package consensuserrs package consensuserr
import ( import (
"fmt" "fmt"

View File

@ -15,7 +15,6 @@ enum ErrCodes {
message Log { message Log {
bytes id = 1; bytes id = 1;
repeated Record records = 2; repeated Record records = 2;
uint64 createdUnix = 3;
} }
message Record { message Record {

View File

@ -17,6 +17,7 @@ func New() app.Component {
return &consensusRpc{} return &consensusRpc{}
} }
// consensusRpc implements consensus rpc server
type consensusRpc struct { type consensusRpc struct {
db db.Service db db.Service
stream stream.Service stream stream.Service

View File

@ -7,7 +7,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserrs" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr"
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
"go.uber.org/zap" "go.uber.org/zap"
@ -24,9 +24,14 @@ func New() Service {
type ChangeReceiver func(logId []byte, records []consensus.Record) type ChangeReceiver func(logId []byte, records []consensus.Record)
type Service interface { type Service interface {
// AddLog adds new log db
AddLog(ctx context.Context, log consensus.Log) (err error) AddLog(ctx context.Context, log consensus.Log) (err error)
// AddRecord adds new record to existing log
// returns consensuserr.ErrConflict if record didn't match or log not found
AddRecord(ctx context.Context, logId []byte, record consensus.Record) (err error) AddRecord(ctx context.Context, logId []byte, record consensus.Record) (err error)
// FetchLog gets log by id
FetchLog(ctx context.Context, logId []byte) (log consensus.Log, err error) FetchLog(ctx context.Context, logId []byte) (log consensus.Log, err error)
// SetChangeReceiver sets the receiver for updates, it must be called before app.Run stage
SetChangeReceiver(receiver ChangeReceiver) (err error) SetChangeReceiver(receiver ChangeReceiver) (err error)
app.ComponentRunnable app.ComponentRunnable
} }
@ -69,7 +74,7 @@ func (s *service) Run(ctx context.Context) (err error) {
func (s *service) AddLog(ctx context.Context, l consensus.Log) (err error) { func (s *service) AddLog(ctx context.Context, l consensus.Log) (err error) {
_, err = s.logColl.InsertOne(ctx, l) _, err = s.logColl.InsertOne(ctx, l)
if mongo.IsDuplicateKeyError(err) { if mongo.IsDuplicateKeyError(err) {
return consensuserrs.ErrLogExists return consensuserr.ErrLogExists
} }
return return
} }
@ -101,10 +106,10 @@ func (s *service) AddRecord(ctx context.Context, logId []byte, record consensus.
}, upd) }, upd)
if err != nil { if err != nil {
log.Error("addRecord update error", zap.Error(err)) log.Error("addRecord update error", zap.Error(err))
return consensuserrs.ErrUnexpected return consensuserr.ErrUnexpected
} }
if result.ModifiedCount == 0 { if result.ModifiedCount == 0 {
return consensuserrs.ErrConflict return consensuserr.ErrConflict
} }
return return
} }
@ -112,7 +117,7 @@ func (s *service) AddRecord(ctx context.Context, logId []byte, record consensus.
func (s *service) FetchLog(ctx context.Context, logId []byte) (l consensus.Log, err error) { func (s *service) FetchLog(ctx context.Context, logId []byte) (l consensus.Log, err error) {
if err = s.logColl.FindOne(ctx, findLogQuery{Id: logId}).Decode(&l); err != nil { if err = s.logColl.FindOne(ctx, findLogQuery{Id: logId}).Decode(&l); err != nil {
if err == mongo.ErrNoDocuments { if err == mongo.ErrNoDocuments {
err = consensuserrs.ErrLogNotFound err = consensuserr.ErrLogNotFound
} }
return return
} }
@ -162,7 +167,9 @@ func (s *service) streamListener(stream *mongo.ChangeStream) {
for stream.Next(s.streamCtx) { for stream.Next(s.streamCtx) {
var res streamResult var res streamResult
if err := stream.Decode(&res); err != nil { if err := stream.Decode(&res); err != nil {
log.Error("stream decode error:", zap.Error(err)) // mongo driver maintains connections and handles reconnects so that the stream will work as usual in these cases
// here we have an unexpected error and should stop any operations to avoid an inconsistent state between db and cache
log.Fatal("stream decode error:", zap.Error(err))
} }
s.changeReceiver(res.DocumentKey.Id, res.UpdateDescription.UpdateFields.Records) s.changeReceiver(res.DocumentKey.Id, res.UpdateDescription.UpdateFields.Records)
} }

View File

@ -5,7 +5,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/app" "github.com/anytypeio/go-anytype-infrastructure-experiments/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserrs" "github.com/anytypeio/go-anytype-infrastructure-experiments/consensus/consensusproto/consensuserr"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"testing" "testing"
@ -100,7 +100,7 @@ func TestService_FetchLog(t *testing.T) {
defer fx.Finish(t) defer fx.Finish(t)
l, err := fx.FetchLog(ctx, []byte("not exists")) l, err := fx.FetchLog(ctx, []byte("not exists"))
assert.Empty(t, l) assert.Empty(t, l)
assert.ErrorIs(t, err, consensuserrs.ErrLogNotFound) assert.ErrorIs(t, err, consensuserr.ErrLogNotFound)
}) })
} }

View File

@ -5,6 +5,7 @@ import (
"sync" "sync"
) )
// object is a cache entry that holds the actual log state and maintains added streams
type object struct { type object struct {
logId []byte logId []byte
records []consensus.Record records []consensus.Record
@ -14,6 +15,8 @@ type object struct {
mu sync.Mutex mu sync.Mutex
} }
// AddRecords adds new records to the log and sends new records to streams
// The records source is db and called via stream.Service
func (o *object) AddRecords(recs []consensus.Record) { func (o *object) AddRecords(recs []consensus.Record) {
o.mu.Lock() o.mu.Lock()
defer o.mu.Unlock() defer o.mu.Unlock()
@ -28,12 +31,14 @@ func (o *object) AddRecords(recs []consensus.Record) {
} }
} }
// Records returns all log records
func (o *object) Records() []consensus.Record { func (o *object) Records() []consensus.Record {
o.mu.Lock() o.mu.Lock()
defer o.mu.Unlock() defer o.mu.Unlock()
return o.records return o.records
} }
// AddStream adds stream to the object
func (o *object) AddStream(s *Stream) { func (o *object) AddStream(s *Stream) {
o.mu.Lock() o.mu.Lock()
defer o.mu.Unlock() defer o.mu.Unlock()
@ -42,18 +47,20 @@ func (o *object) AddStream(s *Stream) {
return return
} }
func (o *object) Locked() bool { // RemoveStream remove stream from object
o.mu.Lock()
defer o.mu.Unlock()
return len(o.streams) > 0
}
func (o *object) RemoveStream(id uint64) { func (o *object) RemoveStream(id uint64) {
o.mu.Lock() o.mu.Lock()
defer o.mu.Unlock() defer o.mu.Unlock()
delete(o.streams, id) delete(o.streams, id)
} }
// Locked indicates that object can be garbage collected
func (o *object) Locked() bool {
o.mu.Lock()
defer o.mu.Unlock()
return len(o.streams) > 0
}
func (o *object) Close() (err error) { func (o *object) Close() (err error) {
return nil return nil
} }

View File

@ -32,7 +32,9 @@ func New() Service {
return &service{} return &service{}
} }
// Service maintains a cache for logs (receive updates from db) and creates new stream objects with able to subscribe/unsubscribe to log ids
type Service interface { type Service interface {
// NewStream creates new stream with able to watch and unwatch log ids
NewStream() *Stream NewStream() *Stream
app.ComponentRunnable app.ComponentRunnable
} }
@ -71,6 +73,7 @@ func (s *service) NewStream() *Stream {
} }
} }
// AddStream to object with given logId
func (s *service) AddStream(ctx context.Context, logId []byte, stream *Stream) (err error) { func (s *service) AddStream(ctx context.Context, logId []byte, stream *Stream) (err error) {
obj, err := s.getObject(ctx, logId) obj, err := s.getObject(ctx, logId)
if err != nil { if err != nil {
@ -80,6 +83,7 @@ func (s *service) AddStream(ctx context.Context, logId []byte, stream *Stream) (
return return
} }
// RemoveStream from object with five logId
func (s *service) RemoveStream(ctx context.Context, logId []byte, streamId uint64) (err error) { func (s *service) RemoveStream(ctx context.Context, logId []byte, streamId uint64) (err error) {
obj, err := s.getObject(ctx, logId) obj, err := s.getObject(ctx, logId)
if err != nil { if err != nil {

View File

@ -8,6 +8,7 @@ import (
"sync" "sync"
) )
// Stream is a buffer that receives updates from object and gives back to a client
type Stream struct { type Stream struct {
id uint64 id uint64
logIds map[string]struct{} logIds map[string]struct{}
@ -16,6 +17,7 @@ type Stream struct {
s *service s *service
} }
// LogIds returns watched log ids
func (s *Stream) LogIds() [][]byte { func (s *Stream) LogIds() [][]byte {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
@ -26,14 +28,18 @@ func (s *Stream) LogIds() [][]byte {
return logIds return logIds
} }
// AddRecords adds new records to stream, called by objects
func (s *Stream) AddRecords(logId []byte, records []consensus.Record) (err error) { func (s *Stream) AddRecords(logId []byte, records []consensus.Record) (err error) {
return s.mb.Add(consensus.Log{Id: logId, Records: records}) return s.mb.Add(consensus.Log{Id: logId, Records: records})
} }
// WaitLogs wait for new log records
// empty returned slice means that stream is closed
func (s *Stream) WaitLogs() []consensus.Log { func (s *Stream) WaitLogs() []consensus.Log {
return s.mb.Wait() return s.mb.Wait()
} }
// WatchIds adds given ids to subscription
func (s *Stream) WatchIds(ctx context.Context, logIds [][]byte) { func (s *Stream) WatchIds(ctx context.Context, logIds [][]byte) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
@ -49,6 +55,7 @@ func (s *Stream) WatchIds(ctx context.Context, logIds [][]byte) {
return return
} }
// UnwatchIds removes given ids from subscription
func (s *Stream) UnwatchIds(ctx context.Context, logIds [][]byte) { func (s *Stream) UnwatchIds(ctx context.Context, logIds [][]byte) {
s.mu.Lock() s.mu.Lock()
defer s.mu.Unlock() defer s.mu.Unlock()
@ -64,6 +71,7 @@ func (s *Stream) UnwatchIds(ctx context.Context, logIds [][]byte) {
return return
} }
// Close closes stream and unsubscribes all ids
func (s *Stream) Close() { func (s *Stream) Close() {
_ = s.mb.Close() _ = s.mb.Close()
s.mu.Lock() s.mu.Lock()