Added simple watcher and statusservice upgrades

This commit is contained in:
mcrakhman 2022-12-17 21:48:48 +01:00 committed by Mikhail Iudin
parent 1af3e764ec
commit b59e2c2593
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
17 changed files with 549 additions and 828 deletions

File diff suppressed because it is too large Load Diff

View File

@ -50,9 +50,8 @@ type DRPCClientApiClient interface {
AllTrees(ctx context.Context, in *AllTreesRequest) (*AllTreesResponse, error)
AllSpaces(ctx context.Context, in *AllSpacesRequest) (*AllSpacesResponse, error)
LoadSpace(ctx context.Context, in *LoadSpaceRequest) (*LoadSpaceResponse, error)
PutFile(ctx context.Context, in *PutFileRequest) (*PutFileResponse, error)
GetFile(ctx context.Context, in *GetFileRequest) (*GetFileResponse, error)
DeleteFile(ctx context.Context, in *DeleteFileRequest) (*DeleteFileResponse, error)
Watch(ctx context.Context, in *WatchRequest) (*WatchResponse, error)
Unwatch(ctx context.Context, in *UnwatchRequest) (*UnwatchResponse, error)
}
type drpcClientApiClient struct {
@ -155,27 +154,18 @@ func (c *drpcClientApiClient) LoadSpace(ctx context.Context, in *LoadSpaceReques
return out, nil
}
func (c *drpcClientApiClient) PutFile(ctx context.Context, in *PutFileRequest) (*PutFileResponse, error) {
out := new(PutFileResponse)
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/PutFile", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
func (c *drpcClientApiClient) Watch(ctx context.Context, in *WatchRequest) (*WatchResponse, error) {
out := new(WatchResponse)
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/Watch", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcClientApiClient) GetFile(ctx context.Context, in *GetFileRequest) (*GetFileResponse, error) {
out := new(GetFileResponse)
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/GetFile", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
if err != nil {
return nil, err
}
return out, nil
}
func (c *drpcClientApiClient) DeleteFile(ctx context.Context, in *DeleteFileRequest) (*DeleteFileResponse, error) {
out := new(DeleteFileResponse)
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/DeleteFile", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
func (c *drpcClientApiClient) Unwatch(ctx context.Context, in *UnwatchRequest) (*UnwatchResponse, error) {
out := new(UnwatchResponse)
err := c.cc.Invoke(ctx, "/clientapi.ClientApi/Unwatch", drpcEncoding_File_api_apiproto_protos_api_proto{}, in, out)
if err != nil {
return nil, err
}
@ -193,9 +183,8 @@ type DRPCClientApiServer interface {
AllTrees(context.Context, *AllTreesRequest) (*AllTreesResponse, error)
AllSpaces(context.Context, *AllSpacesRequest) (*AllSpacesResponse, error)
LoadSpace(context.Context, *LoadSpaceRequest) (*LoadSpaceResponse, error)
PutFile(context.Context, *PutFileRequest) (*PutFileResponse, error)
GetFile(context.Context, *GetFileRequest) (*GetFileResponse, error)
DeleteFile(context.Context, *DeleteFileRequest) (*DeleteFileResponse, error)
Watch(context.Context, *WatchRequest) (*WatchResponse, error)
Unwatch(context.Context, *UnwatchRequest) (*UnwatchResponse, error)
}
type DRPCClientApiUnimplementedServer struct{}
@ -240,21 +229,17 @@ func (s *DRPCClientApiUnimplementedServer) LoadSpace(context.Context, *LoadSpace
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCClientApiUnimplementedServer) PutFile(context.Context, *PutFileRequest) (*PutFileResponse, error) {
func (s *DRPCClientApiUnimplementedServer) Watch(context.Context, *WatchRequest) (*WatchResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCClientApiUnimplementedServer) GetFile(context.Context, *GetFileRequest) (*GetFileResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
func (s *DRPCClientApiUnimplementedServer) DeleteFile(context.Context, *DeleteFileRequest) (*DeleteFileResponse, error) {
func (s *DRPCClientApiUnimplementedServer) Unwatch(context.Context, *UnwatchRequest) (*UnwatchResponse, error) {
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
}
type DRPCClientApiDescription struct{}
func (DRPCClientApiDescription) NumMethods() int { return 13 }
func (DRPCClientApiDescription) NumMethods() int { return 12 }
func (DRPCClientApiDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
switch n {
@ -349,32 +334,23 @@ func (DRPCClientApiDescription) Method(n int) (string, drpc.Encoding, drpc.Recei
)
}, DRPCClientApiServer.LoadSpace, true
case 10:
return "/clientapi.ClientApi/PutFile", drpcEncoding_File_api_apiproto_protos_api_proto{},
return "/clientapi.ClientApi/Watch", drpcEncoding_File_api_apiproto_protos_api_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCClientApiServer).
PutFile(
Watch(
ctx,
in1.(*PutFileRequest),
in1.(*WatchRequest),
)
}, DRPCClientApiServer.PutFile, true
}, DRPCClientApiServer.Watch, true
case 11:
return "/clientapi.ClientApi/GetFile", drpcEncoding_File_api_apiproto_protos_api_proto{},
return "/clientapi.ClientApi/Unwatch", drpcEncoding_File_api_apiproto_protos_api_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCClientApiServer).
GetFile(
Unwatch(
ctx,
in1.(*GetFileRequest),
in1.(*UnwatchRequest),
)
}, DRPCClientApiServer.GetFile, true
case 12:
return "/clientapi.ClientApi/DeleteFile", drpcEncoding_File_api_apiproto_protos_api_proto{},
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
return srv.(DRPCClientApiServer).
DeleteFile(
ctx,
in1.(*DeleteFileRequest),
)
}, DRPCClientApiServer.DeleteFile, true
}, DRPCClientApiServer.Unwatch, true
default:
return "", nil, nil, nil, false
}
@ -544,48 +520,32 @@ func (x *drpcClientApi_LoadSpaceStream) SendAndClose(m *LoadSpaceResponse) error
return x.CloseSend()
}
type DRPCClientApi_PutFileStream interface {
type DRPCClientApi_WatchStream interface {
drpc.Stream
SendAndClose(*PutFileResponse) error
SendAndClose(*WatchResponse) error
}
type drpcClientApi_PutFileStream struct {
type drpcClientApi_WatchStream struct {
drpc.Stream
}
func (x *drpcClientApi_PutFileStream) SendAndClose(m *PutFileResponse) error {
func (x *drpcClientApi_WatchStream) SendAndClose(m *WatchResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCClientApi_GetFileStream interface {
type DRPCClientApi_UnwatchStream interface {
drpc.Stream
SendAndClose(*GetFileResponse) error
SendAndClose(*UnwatchResponse) error
}
type drpcClientApi_GetFileStream struct {
type drpcClientApi_UnwatchStream struct {
drpc.Stream
}
func (x *drpcClientApi_GetFileStream) SendAndClose(m *GetFileResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
return err
}
return x.CloseSend()
}
type DRPCClientApi_DeleteFileStream interface {
drpc.Stream
SendAndClose(*DeleteFileResponse) error
}
type drpcClientApi_DeleteFileStream struct {
drpc.Stream
}
func (x *drpcClientApi_DeleteFileStream) SendAndClose(m *DeleteFileResponse) error {
func (x *drpcClientApi_UnwatchStream) SendAndClose(m *UnwatchResponse) error {
if err := x.MsgSend(m, drpcEncoding_File_api_apiproto_protos_api_proto{}); err != nil {
return err
}

View File

@ -14,9 +14,8 @@ service ClientApi {
rpc AllTrees(AllTreesRequest) returns(AllTreesResponse);
rpc AllSpaces(AllSpacesRequest) returns(AllSpacesResponse);
rpc LoadSpace(LoadSpaceRequest) returns(LoadSpaceResponse);
rpc PutFile(PutFileRequest) returns(PutFileResponse);
rpc GetFile(GetFileRequest) returns(GetFileResponse);
rpc DeleteFile(DeleteFileRequest) returns(DeleteFileResponse);
rpc Watch(WatchRequest) returns(WatchResponse);
rpc Unwatch(UnwatchRequest) returns(UnwatchResponse);
}
message CreateSpaceRequest {
@ -108,26 +107,18 @@ message TreeParamsResponse {
repeated string headIds = 2;
}
message PutFileRequest {
string path = 1;
string spaceId = 2;
message WatchRequest {
string spaceId = 1;
string treeId = 2;
}
message PutFileResponse {
string hash = 1;
message WatchResponse {
}
message GetFileRequest {
string hash = 1;
string path = 2;
message UnwatchRequest {
string spaceId = 1;
string treeId = 2;
}
message GetFileResponse {
string path = 1;
}
message DeleteFileRequest {
string hash = 1;
}
message DeleteFileResponse {}
message UnwatchResponse {
}

View File

@ -7,14 +7,10 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/document"
"github.com/anytypeio/go-anytype-infrastructure-experiments/client/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonfile/fileservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/keys/symmetric"
"github.com/ipfs/go-cid"
"go.uber.org/zap"
"io"
"math/rand"
"os"
"sync"
)
type rpcHandler struct {
@ -22,7 +18,49 @@ type rpcHandler struct {
storageService storage.ClientStorage
docService document.Service
account account.Service
file fileservice.FileService
treeWatcher *watcher
sync.Mutex
}
func (r *rpcHandler) Watch(ctx context.Context, request *apiproto.WatchRequest) (resp *apiproto.WatchResponse, err error) {
space, err := r.spaceService.GetSpace(context.Background(), request.SpaceId)
if err != nil {
return
}
r.Lock()
defer r.Unlock()
ch := make(chan bool)
r.treeWatcher = newWatcher(request.SpaceId, request.TreeId, ch)
space.StatusService().Watch(request.TreeId, ch)
go r.treeWatcher.run()
resp = &apiproto.WatchResponse{}
return
}
func (r *rpcHandler) Unwatch(ctx context.Context, request *apiproto.UnwatchRequest) (resp *apiproto.UnwatchResponse, err error) {
space, err := r.spaceService.GetSpace(context.Background(), request.SpaceId)
if err != nil {
return
}
var treeWatcher *watcher
space.StatusService().Unwatch(request.TreeId)
r.Lock()
if r.treeWatcher != nil {
treeWatcher = r.treeWatcher
}
r.Unlock()
treeWatcher.close()
r.Lock()
if r.treeWatcher == treeWatcher {
r.treeWatcher = nil
}
r.Unlock()
resp = &apiproto.UnwatchResponse{}
return
}
func (r *rpcHandler) LoadSpace(ctx context.Context, request *apiproto.LoadSpaceRequest) (resp *apiproto.LoadSpaceResponse, err error) {
@ -150,50 +188,3 @@ func (r *rpcHandler) TreeParams(ctx context.Context, request *apiproto.TreeParam
}
return
}
func (r *rpcHandler) PutFile(ctx context.Context, request *apiproto.PutFileRequest) (*apiproto.PutFileResponse, error) {
f, err := os.Open(request.Path)
if err != nil {
return nil, err
}
defer f.Close()
n, err := r.file.AddFile(ctx, f)
if err != nil {
return nil, err
}
return &apiproto.PutFileResponse{
Hash: n.Cid().String(),
}, nil
}
func (r *rpcHandler) GetFile(ctx context.Context, request *apiproto.GetFileRequest) (*apiproto.GetFileResponse, error) {
c, err := cid.Parse(request.Hash)
if err != nil {
return nil, err
}
f, err := os.Create(request.Path)
if err != nil {
return nil, err
}
defer f.Close()
rd, err := r.file.GetFile(ctx, c)
if err != nil {
return nil, err
}
defer rd.Close()
wr, err := io.Copy(f, rd)
if err != nil && err != io.EOF {
return nil, err
}
log.Info("copied bytes", zap.Int64("size", wr))
return &apiproto.GetFileResponse{
Path: request.Path,
}, nil
}
func (r *rpcHandler) DeleteFile(ctx context.Context, request *apiproto.DeleteFileRequest) (*apiproto.DeleteFileResponse, error) {
//TODO implement me
panic("implement me")
}

View File

@ -9,7 +9,6 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/account"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonfile/fileservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/config"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/net/rpc/server"
@ -37,7 +36,6 @@ type service struct {
storageService clientstorage.ClientStorage
docService document.Service
account account.Service
file fileservice.FileService
*server.BaseDrpcServer
}
@ -48,7 +46,6 @@ func (s *service) Init(a *app.App) (err error) {
s.account = a.MustComponent(account.CName).(account.Service)
s.cfg = a.MustComponent(config.CName).(*config.Config)
s.transport = a.MustComponent(secure.CName).(secure.Service)
s.file = a.MustComponent(fileservice.CName).(fileservice.FileService)
return nil
}
@ -70,7 +67,12 @@ func (s *service) Run(ctx context.Context) (err error) {
if err != nil {
return
}
return apiproto.DRPCRegisterClientApi(s, &rpcHandler{s.spaceService, s.storageService, s.docService, s.account, s.file})
return apiproto.DRPCRegisterClientApi(s, &rpcHandler{
spaceService: s.spaceService,
storageService: s.storageService,
docService: s.docService,
account: s.account,
})
}
func (s *service) Close(ctx context.Context) (err error) {

37
client/api/watcher.go Normal file
View File

@ -0,0 +1,37 @@
package api
import "go.uber.org/zap"
type watcher struct {
spaceId string
treeId string
watcher chan bool
watcherDone chan struct{}
}
func newWatcher(spaceId, treeId string, ch chan bool) *watcher {
return &watcher{
spaceId: spaceId,
treeId: treeId,
watcher: ch,
watcherDone: make(chan struct{}),
}
}
func (w *watcher) run() {
log := log.With(zap.String("spaceId", w.spaceId), zap.String("treeId", w.treeId))
log.Debug("started watching")
defer close(w.watcherDone)
for {
synced, ok := <-w.watcher
if !ok {
log.Debug("stopped watching")
return
}
log.With(zap.Bool("synced", synced)).Debug("updated sync status")
}
}
func (w *watcher) close() {
<-w.watcherDone
}

View File

@ -2,10 +2,75 @@ module github.com/anytypeio/go-anytype-infrastructure-experiments/client
replace github.com/anytypeio/go-anytype-infrastructure-experiments/common => ../common
go 1.19
require (
github.com/anytypeio/go-anytype-infrastructure-experiments/common v0.0.0-00010101000000-000000000000
github.com/dgraph-io/badger/v3 v3.2103.3
github.com/gogo/protobuf v1.3.2
github.com/stretchr/testify v1.8.0
go.uber.org/zap v1.23.0
storj.io/drpc v0.0.32
)
require (
github.com/anytypeio/go-anytype-infrastructure-experiments/consensus v0.0.0-20221217135026-4eba413631b3 // indirect
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/cheggaaa/mb/v3 v3.0.0-20221122160120-e9034545510c // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.1.0 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/fogleman/gg v1.3.0 // indirect
github.com/goccy/go-graphviz v0.0.9 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/flatbuffers v1.12.1 // indirect
github.com/huandu/skiplist v1.2.0 // indirect
github.com/ipfs/go-cid v0.3.2 // indirect
github.com/ipfs/go-log/v2 v2.5.1 // indirect
github.com/klauspost/compress v1.15.10 // indirect
github.com/klauspost/cpuid/v2 v2.1.1 // indirect
github.com/libp2p/go-buffer-pool v0.1.0 // indirect
github.com/libp2p/go-libp2p v0.23.2 // indirect
github.com/libp2p/go-openssl v0.1.0 // indirect
github.com/mattn/go-isatty v0.0.16 // indirect
github.com/mattn/go-pointer v0.0.1 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/minio/sha256-simd v1.0.0 // indirect
github.com/mr-tron/base58 v1.2.0 // indirect
github.com/multiformats/go-base32 v0.1.0 // indirect
github.com/multiformats/go-base36 v0.1.0 // indirect
github.com/multiformats/go-multiaddr v0.7.0 // indirect
github.com/multiformats/go-multibase v0.1.1 // indirect
github.com/multiformats/go-multicodec v0.6.0 // indirect
github.com/multiformats/go-multihash v0.2.1 // indirect
github.com/multiformats/go-varint v0.0.6 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.13.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.37.0 // indirect
github.com/prometheus/procfs v0.8.0 // indirect
github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572 // indirect
github.com/spaolacci/murmur3 v1.1.0 // indirect
github.com/zeebo/blake3 v0.2.3 // indirect
github.com/zeebo/errs v1.3.0 // indirect
go.opencensus.io v0.23.0 // indirect
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b // indirect
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
golang.org/x/net v0.0.0-20220920183852-bf014ff85ad5 // indirect
golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect
google.golang.org/protobuf v1.28.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
lukechampine.com/blake3 v1.1.7 // indirect
)

View File

@ -40,6 +40,8 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/anytypeio/go-anytype-infrastructure-experiments/consensus v0.0.0-20221217135026-4eba413631b3 h1:yIyGIb7bRkEngKtQ0Ja5bome2SEnErwTaEvR8dA/WtU=
github.com/anytypeio/go-anytype-infrastructure-experiments/consensus v0.0.0-20221217135026-4eba413631b3/go.mod h1:w0i62cRB2jVpjFb2CpPNj5J+ihKqqmBBG9X2+Odekjw=
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232 h1:kMPPZYmJgbs4AJfodbg2OCXg5cp+9LPAJcLZJqmcghk=
github.com/anytypeio/go-chash v0.0.0-20220629194632-4ad1154fe232/go.mod h1:+PeHBAWp7gUh/yw6uAauKc5ku0w4cFNg6DUddGxoGq0=
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
@ -56,6 +58,8 @@ github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghf
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cheggaaa/mb/v3 v3.0.0-20221122160120-e9034545510c h1:+bD75daSbsxyTzkKpNplC4xls+7/tGwty+zruzOnOmk=
github.com/cheggaaa/mb/v3 v3.0.0-20221122160120-e9034545510c/go.mod h1:zCt2QeYukhd/g0bIdNqF+b/kKz1hnLFNDkP49qN5kqI=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@ -214,8 +218,6 @@ github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6
github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg=
github.com/libp2p/go-libp2p v0.23.2 h1:yqyTeKQJyofWXxEv/eEVUvOrGdt/9x+0PIQ4N1kaxmE=
github.com/libp2p/go-libp2p v0.23.2/go.mod h1:s9DEa5NLR4g+LZS+md5uGU4emjMWFiqkZr6hBTY8UxI=
github.com/libp2p/go-libp2p-core v0.20.1 h1:fQz4BJyIFmSZAiTbKV8qoYhEH5Dtv/cVhZbG3Ib/+Cw=
github.com/libp2p/go-libp2p-core v0.20.1/go.mod h1:6zR8H7CvQWgYLsbG4on6oLNSGcyKaYFSEYyDt51+bIY=
github.com/libp2p/go-openssl v0.1.0 h1:LBkKEcUv6vtZIQLVTegAil8jbNpJErQ9AnT+bWV+Ooo=
github.com/libp2p/go-openssl v0.1.0/go.mod h1:OiOxwPpL3n4xlenjx2h7AwSGaFSC/KZvf6gNdOBQMtc=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@ -305,12 +307,15 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
@ -353,8 +358,8 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200204104054-c9f3fb736b72/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM=
golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d h1:sK3txAijHtOK88l68nt020reeT1ZdKLIYetKl95FzVY=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -365,6 +370,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg=

View File

@ -7,6 +7,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/app/logger"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/diffservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/statusservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/treegetter"
@ -108,12 +109,20 @@ func (s *service) NewSpace(ctx context.Context, id string) (Space, error) {
lastConfiguration := s.configurationService.GetLast()
confConnector := nodeconf.NewConfConnector(lastConfiguration, s.pool)
var statusService statusservice.StatusService
// this will work only for clients, not the best solution, but...
if !lastConfiguration.IsResponsible(st.Id()) {
statusService = statusservice.NewStatusService(st.Id(), lastConfiguration)
}
diffService := diffservice.NewDiffService(id, s.config.SyncPeriod, st, confConnector, s.treeGetter, log)
syncService := syncservice.NewSyncService(id, confConnector, s.config.SyncPeriod)
sp := &space{
id: id,
syncService: syncService,
diffService: diffService,
statusService: statusService,
cache: s.treeGetter,
account: s.account,
configuration: lastConfiguration,

View File

@ -9,6 +9,7 @@ import (
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/settingsdocument/deletionstate"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/spacesyncproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/statusservice"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncacl"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/commonspace/syncservice"
@ -80,6 +81,8 @@ type Space interface {
BuildTree(ctx context.Context, id string, listener updatelistener.UpdateListener) (tree.ObjectTree, error)
DeleteTree(ctx context.Context, id string) (err error)
StatusService() statusservice.StatusService
Close() error
}
@ -92,6 +95,7 @@ type space struct {
syncService syncservice.SyncService
diffService diffservice.DiffService
statusService statusservice.StatusService
storage storage.SpaceStorage
cache treegetter.TreeGetter
account account.Service
@ -202,6 +206,10 @@ func (s *space) DiffService() diffservice.DiffService {
return s.diffService
}
func (s *space) StatusService() statusservice.StatusService {
return s.statusService
}
func (s *space) StoredIds() []string {
return s.diffService.AllIds()
}
@ -222,6 +230,7 @@ func (s *space) DeriveTree(ctx context.Context, payload tree.ObjectTreeCreatePay
Configuration: s.configuration,
AclList: s.aclList,
SpaceStorage: s.storage,
StatusService: s.statusService,
}
return synctree.DeriveSyncTree(ctx, deps)
}
@ -238,6 +247,7 @@ func (s *space) CreateTree(ctx context.Context, payload tree.ObjectTreeCreatePay
Configuration: s.configuration,
AclList: s.aclList,
SpaceStorage: s.storage,
StatusService: s.statusService,
}
return synctree.CreateSyncTree(ctx, deps)
}
@ -256,6 +266,7 @@ func (s *space) BuildTree(ctx context.Context, id string, listener updatelistene
AclList: s.aclList,
SpaceStorage: s.storage,
TreeUsage: &s.treesUsed,
StatusService: s.statusService,
}
return synctree.BuildSyncTreeOrGetRemote(ctx, id, deps)
}
@ -286,5 +297,10 @@ func (s *space) Close() error {
if err := s.storage.Close(); err != nil {
mError.Add(err)
}
if s.statusService != nil {
if err := s.statusService.Close(); err != nil {
mError.Add(err)
}
}
return mError.Err()
}

View File

@ -17,6 +17,7 @@ type StatusService interface {
Unwatch(treeId string)
StateCounter() uint64
RemoveAllExcept(senderId string, differentRemoteIds []string, stateCounter uint64)
Close() error
}
type statusEntry struct {
@ -31,6 +32,7 @@ type statusService struct {
watchers map[string]chan bool
configuration nodeconf.Configuration
stateCounter uint64
closed bool
}
func NewStatusService(spaceId string, configuration nodeconf.Configuration) StatusService {
@ -46,6 +48,10 @@ func NewStatusService(spaceId string, configuration nodeconf.Configuration) Stat
func (s *statusService) HeadsChange(treeId string, heads []string) {
s.Lock()
defer s.Unlock()
if s.closed {
return
}
s.treeHeads[treeId] = statusEntry{
head: heads[0],
stateCounter: s.stateCounter,
@ -62,6 +68,10 @@ func (s *statusService) HeadsChange(treeId string, heads []string) {
func (s *statusService) HeadsReceive(senderId, treeId string, heads []string) {
s.Lock()
defer s.Unlock()
if s.closed {
return
}
curHead, ok := s.treeHeads[treeId]
if !ok {
return
@ -84,13 +94,22 @@ func (s *statusService) HeadsReceive(senderId, treeId string, heads []string) {
func (s *statusService) Watch(treeId string, ch chan bool) {
s.Lock()
defer s.Unlock()
if s.closed {
return
}
s.watchers[treeId] = ch
}
func (s *statusService) Unwatch(treeId string) {
s.Lock()
defer s.Unlock()
delete(s.watchers, treeId)
if s.closed {
return
}
if ch, ok := s.watchers[treeId]; ok {
close(ch)
delete(s.watchers, treeId)
}
}
func (s *statusService) StateCounter() uint64 {
@ -99,6 +118,18 @@ func (s *statusService) StateCounter() uint64 {
return s.stateCounter
}
func (s *statusService) Close() (err error) {
s.Lock()
defer s.Unlock()
if s.closed {
return
}
for _, ch := range s.watchers {
close(ch)
}
return
}
func (s *statusService) RemoveAllExcept(senderId string, differentRemoteIds []string, stateCounter uint64) {
if !slices.Contains(s.configuration.NodeIds(s.spaceId), senderId) {
return

View File

@ -63,6 +63,7 @@ type CreateDeps struct {
SyncService syncservice.SyncService
AclList list.ACLList
SpaceStorage spacestorage.SpaceStorage
StatusService statusservice.StatusService
}
type BuildDeps struct {
@ -75,9 +76,14 @@ type BuildDeps struct {
SpaceStorage spacestorage.SpaceStorage
TreeStorage storage.TreeStorage
TreeUsage *atomic.Int32
StatusService statusservice.StatusService
}
func newWrappedSyncClient(spaceId string, factory RequestFactory, syncService syncservice.SyncService, configuration nodeconf.Configuration) SyncClient {
func newWrappedSyncClient(
spaceId string,
factory RequestFactory,
syncService syncservice.SyncService,
configuration nodeconf.Configuration) SyncClient {
syncClient := newSyncClient(spaceId, syncService.StreamPool(), factory, configuration, syncService.StreamChecker())
return newQueuedClient(syncClient, syncService.ActionQueue())
}
@ -95,6 +101,7 @@ func DeriveSyncTree(ctx context.Context, deps CreateDeps) (id string, err error)
deps.Configuration)
headUpdate := syncClient.CreateHeadUpdate(objTree, nil)
deps.StatusService.HeadsChange(objTree.ID(), objTree.Heads())
syncClient.BroadcastAsync(headUpdate)
id = objTree.ID()
return
@ -112,6 +119,7 @@ func CreateSyncTree(ctx context.Context, deps CreateDeps) (id string, err error)
deps.Configuration)
headUpdate := syncClient.CreateHeadUpdate(objTree, nil)
deps.StatusService.HeadsChange(objTree.ID(), objTree.Heads())
syncClient.BroadcastAsync(headUpdate)
id = objTree.ID()
return
@ -197,13 +205,14 @@ func buildSyncTree(ctx context.Context, isFirstBuild bool, deps BuildDeps) (t Sy
deps.SyncService,
deps.Configuration)
syncTree := &syncTree{
ObjectTree: objTree,
syncClient: syncClient,
notifiable: deps.HeadNotifiable,
treeUsage: deps.TreeUsage,
listener: deps.Listener,
ObjectTree: objTree,
syncClient: syncClient,
notifiable: deps.HeadNotifiable,
treeUsage: deps.TreeUsage,
listener: deps.Listener,
statusService: deps.StatusService,
}
syncHandler := newSyncTreeHandler(syncTree, syncClient)
syncHandler := newSyncTreeHandler(syncTree, syncClient, deps.StatusService)
syncTree.SyncHandler = syncHandler
t = syncTree
syncTree.Lock()

View File

@ -23,11 +23,12 @@ type syncTreeHandler struct {
const maxQueueSize = 5
func newSyncTreeHandler(objTree tree.ObjectTree, syncClient SyncClient) synchandler.SyncHandler {
func newSyncTreeHandler(objTree tree.ObjectTree, syncClient SyncClient, statusService statusservice.StatusService) synchandler.SyncHandler {
return &syncTreeHandler{
objTree: objTree,
syncClient: syncClient,
queue: newReceiveQueue(maxQueueSize),
objTree: objTree,
syncClient: syncClient,
statusService: statusService,
queue: newReceiveQueue(maxQueueSize),
}
}

View File

@ -57,6 +57,7 @@ require (
go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d // indirect
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b // indirect
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect
google.golang.org/protobuf v1.28.1 // indirect

View File

@ -326,6 +326,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0
golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4=
golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM=
golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b h1:SCE/18RnFsLrjydh/R/s5EVvHoZprqEQUuoxK8q2Pc4=
golang.org/x/exp v0.0.0-20220916125017-b168a2c6b86b/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 h1:5h3ngYt7+vXCDZCup/HkCQgW5XwmSvR/nA2JmJ0RErg=

View File

@ -24,9 +24,8 @@ type Service interface {
AllTrees(ctx context.Context, ip string, request *apiproto.AllTreesRequest) (resp *apiproto.AllTreesResponse, err error)
AllSpaces(ctx context.Context, ip string, request *apiproto.AllSpacesRequest) (resp *apiproto.AllSpacesResponse, err error)
LoadSpace(ctx context.Context, ip string, request *apiproto.LoadSpaceRequest) (res *apiproto.LoadSpaceResponse, err error)
PutFile(ctx context.Context, ip string, request *apiproto.PutFileRequest) (resp *apiproto.PutFileResponse, err error)
GetFile(ctx context.Context, ip string, request *apiproto.GetFileRequest) (resp *apiproto.GetFileResponse, err error)
DeleteFile(ctx context.Context, ip string, request *apiproto.DeleteFileRequest) (resp *apiproto.DeleteFileResponse, err error)
Watch(ctx context.Context, ip string, request *apiproto.WatchRequest) (res *apiproto.WatchResponse, err error)
Unwatch(ctx context.Context, ip string, request *apiproto.UnwatchRequest) (res *apiproto.UnwatchResponse, err error)
}
type service struct {
@ -126,26 +125,18 @@ func (s *service) LoadSpace(ctx context.Context, ip string, request *apiproto.Lo
return cl.LoadSpace(ctx, request)
}
func (s *service) PutFile(ctx context.Context, ip string, request *apiproto.PutFileRequest) (resp *apiproto.PutFileResponse, err error) {
func (s *service) Watch(ctx context.Context, ip string, request *apiproto.WatchRequest) (res *apiproto.WatchResponse, err error) {
cl, err := s.client.GetClient(ctx, ip)
if err != nil {
return
}
return cl.PutFile(ctx, request)
return cl.Watch(ctx, request)
}
func (s *service) GetFile(ctx context.Context, ip string, request *apiproto.GetFileRequest) (resp *apiproto.GetFileResponse, err error) {
func (s *service) Unwatch(ctx context.Context, ip string, request *apiproto.UnwatchRequest) (res *apiproto.UnwatchResponse, err error) {
cl, err := s.client.GetClient(ctx, ip)
if err != nil {
return
}
return cl.GetFile(ctx, request)
}
func (s *service) DeleteFile(ctx context.Context, ip string, request *apiproto.DeleteFileRequest) (resp *apiproto.DeleteFileResponse, err error) {
cl, err := s.client.GetClient(ctx, ip)
if err != nil {
return
}
return cl.DeleteFile(ctx, request)
return cl.Unwatch(ctx, request)
}

View File

@ -291,57 +291,59 @@ func (s *service) registerClientCommands() {
}
s.clientCommands = append(s.clientCommands, cmdAllSpaces)
cmdPutFile := &cobra.Command{
Use: "put-file",
Short: "put new file by path",
cmdTreeWatch := &cobra.Command{
Use: "tree-watch [document]",
Short: "start watching the tree (prints in logs the status on the client side)",
Args: cobra.RangeArgs(1, 1),
Run: func(cmd *cobra.Command, args []string) {
cli, _ := cmd.Flags().GetString("client")
space, _ := cmd.Flags().GetString("space")
addr, ok := s.peers[cli]
if !ok {
fmt.Println("no such client")
return
}
path, _ := cmd.Flags().GetString("path")
spaceId, _ := cmd.Flags().GetString("spaceId")
resp, err := s.client.PutFile(context.Background(), addr, &clientproto.PutFileRequest{
Path: path,
SpaceId: spaceId,
})
if err != nil {
fmt.Println("error:", err)
return
}
fmt.Println("hash:", resp.Hash)
},
}
cmdPutFile.Flags().String("path", "", "path to file")
cmdPutFile.Flags().String("spaceId", "", "spaceId")
s.clientCommands = append(s.clientCommands, cmdPutFile)
cmdGetFile := &cobra.Command{
Use: "get-file",
Short: "get file by hash and save",
_, err := s.client.Watch(context.Background(), addr, &clientproto.WatchRequest{
SpaceId: space,
TreeId: args[0],
})
if err != nil {
fmt.Println("couldn't start watching tree", err)
return
}
fmt.Println(args[0])
},
}
cmdTreeWatch.Flags().String("space", "", "the space where something is happening :-)")
cmdTreeWatch.MarkFlagRequired("space")
s.clientCommands = append(s.clientCommands, cmdTreeWatch)
cmdTreeUnwatch := &cobra.Command{
Use: "tree-unwatch [document]",
Short: "stop watching the tree (prints in logs the status on the client side)",
Args: cobra.RangeArgs(1, 1),
Run: func(cmd *cobra.Command, args []string) {
cli, _ := cmd.Flags().GetString("client")
space, _ := cmd.Flags().GetString("space")
addr, ok := s.peers[cli]
if !ok {
fmt.Println("no such client")
return
}
hash, _ := cmd.Flags().GetString("hash")
path, _ := cmd.Flags().GetString("path")
resp, err := s.client.GetFile(context.Background(), addr, &clientproto.GetFileRequest{
Hash: hash,
Path: path,
_, err := s.client.Unwatch(context.Background(), addr, &clientproto.UnwatchRequest{
SpaceId: space,
TreeId: args[0],
})
if err != nil {
fmt.Println("error:", err)
fmt.Println("couldn't stop watching tree", err)
return
}
fmt.Println("path:", resp.Path)
fmt.Println(args[0])
},
}
cmdGetFile.Flags().String("path", "", "path to file")
cmdGetFile.Flags().String("hash", "", "CID")
s.clientCommands = append(s.clientCommands, cmdGetFile)
cmdTreeUnwatch.Flags().String("space", "", "the space where something is happening :-)")
cmdTreeUnwatch.MarkFlagRequired("space")
s.clientCommands = append(s.clientCommands, cmdTreeUnwatch)
}