Chris Lu
5 years ago
3 changed files with 102 additions and 9 deletions
-
91weed/filer2/meta_aggregator.go
-
12weed/server/filer_grpc_server_sub_meta.go
-
8weed/server/filer_server.go
@ -0,0 +1,91 @@ |
|||||
|
package filer2 |
||||
|
|
||||
|
import ( |
||||
|
"context" |
||||
|
"fmt" |
||||
|
"io" |
||||
|
"sync" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/golang/protobuf/proto" |
||||
|
"google.golang.org/grpc" |
||||
|
|
||||
|
"github.com/chrislusf/seaweedfs/weed/glog" |
||||
|
"github.com/chrislusf/seaweedfs/weed/pb" |
||||
|
"github.com/chrislusf/seaweedfs/weed/pb/filer_pb" |
||||
|
"github.com/chrislusf/seaweedfs/weed/util/log_buffer" |
||||
|
) |
||||
|
|
||||
|
type MetaAggregator struct { |
||||
|
filers []string |
||||
|
grpcDialOption grpc.DialOption |
||||
|
MetaLogBuffer *log_buffer.LogBuffer |
||||
|
// notifying clients
|
||||
|
ListenersLock sync.Mutex |
||||
|
ListenersCond *sync.Cond |
||||
|
} |
||||
|
|
||||
|
func NewMetaAggregator(filers []string, grpcDialOption grpc.DialOption) *MetaAggregator { |
||||
|
t := &MetaAggregator{ |
||||
|
filers: filers, |
||||
|
grpcDialOption: grpcDialOption, |
||||
|
} |
||||
|
t.ListenersCond = sync.NewCond(&t.ListenersLock) |
||||
|
t.MetaLogBuffer = log_buffer.NewLogBuffer(time.Minute, nil, func() { |
||||
|
t.ListenersCond.Broadcast() |
||||
|
}) |
||||
|
return t |
||||
|
} |
||||
|
|
||||
|
func (ma *MetaAggregator) StartLoopSubscribe(lastTsNs int64) { |
||||
|
for _, filer := range ma.filers { |
||||
|
go ma.subscribeToOneFiler(filer, lastTsNs) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
func (ma *MetaAggregator) subscribeToOneFiler(filer string, lastTsNs int64) { |
||||
|
|
||||
|
processEventFn := func(event *filer_pb.SubscribeMetadataResponse) error { |
||||
|
data, err := proto.Marshal(event) |
||||
|
if err != nil { |
||||
|
glog.Errorf("failed to marshal subscribed filer_pb.SubscribeMetadataResponse %+v: %v", event, err) |
||||
|
return err |
||||
|
} |
||||
|
dir := event.Directory |
||||
|
println("received meta change", dir, "size", len(data)) |
||||
|
ma.MetaLogBuffer.AddToBuffer([]byte(dir), data) |
||||
|
return nil |
||||
|
} |
||||
|
|
||||
|
for { |
||||
|
err := pb.WithFilerClient(filer, ma.grpcDialOption, func(client filer_pb.SeaweedFilerClient) error { |
||||
|
stream, err := client.SubscribeLocalMetadata(context.Background(), &filer_pb.SubscribeMetadataRequest{ |
||||
|
ClientName: "filer", |
||||
|
PathPrefix: "/", |
||||
|
SinceNs: lastTsNs, |
||||
|
}) |
||||
|
if err != nil { |
||||
|
return fmt.Errorf("subscribe: %v", err) |
||||
|
} |
||||
|
|
||||
|
for { |
||||
|
resp, listenErr := stream.Recv() |
||||
|
if listenErr == io.EOF { |
||||
|
return nil |
||||
|
} |
||||
|
if listenErr != nil { |
||||
|
return listenErr |
||||
|
} |
||||
|
|
||||
|
if err := processEventFn(resp); err != nil { |
||||
|
return fmt.Errorf("process %v: %v", resp, err) |
||||
|
} |
||||
|
lastTsNs = resp.TsNs |
||||
|
} |
||||
|
}) |
||||
|
if err != nil { |
||||
|
glog.V(0).Infof("subscribing remote %s meta change: %v", filer, err) |
||||
|
time.Sleep(1733 * time.Millisecond) |
||||
|
} |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue