make method invocation resilient to errors trying to load all files from server (#74)

This commit is contained in:
Joshua Humphries 2018-12-13 11:44:43 -05:00 committed by GitHub
parent 70e9bba1b8
commit 9fa2fce63b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 32 additions and 25 deletions

View File

@ -189,10 +189,14 @@ const (
) )
func anyResolver(source DescriptorSource) (jsonpb.AnyResolver, error) { func anyResolver(source DescriptorSource) (jsonpb.AnyResolver, error) {
files, err := GetAllFiles(source) // TODO: instead of pro-actively downloading file descriptors to
if err != nil { // build a dynamic resolver, it would be better if the resolver
return nil, err // impl was lazy, and simply downloaded the descriptors as needed
} // when asked to resolve a particular type URL
// best effort: build resolver with whatever files we can
// load, ignoring any errors
files, _ := GetAllFiles(source)
var er dynamic.ExtensionRegistry var er dynamic.ExtensionRegistry
for _, fd := range files { for _, fd := range files {

View File

@ -14,7 +14,7 @@ import (
"google.golang.org/grpc/metadata" "google.golang.org/grpc/metadata"
) )
func TestRequestFactory(t *testing.T) { func TestRequestParser(t *testing.T) {
source, err := DescriptorSourceFromProtoSets("testing/example.protoset") source, err := DescriptorSourceFromProtoSets("testing/example.protoset")
if err != nil { if err != nil {
t.Fatalf("failed to create descriptor source: %v", err) t.Fatalf("failed to create descriptor source: %v", err)

View File

@ -55,27 +55,29 @@ func GetAllFiles(source DescriptorSource) ([]*desc.FileDescriptor, error) {
var files []*desc.FileDescriptor var files []*desc.FileDescriptor
srcFiles, ok := source.(sourceWithFiles) srcFiles, ok := source.(sourceWithFiles)
// If an error occurs, we still try to load as many files as we can, so that
// caller can decide whether to ignore error or not.
var firstError error
if ok { if ok {
var err error files, firstError = srcFiles.GetAllFiles()
files, err = srcFiles.GetAllFiles()
if err != nil {
return nil, err
}
} else { } else {
// Source does not implement GetAllFiles method, so use ListServices // Source does not implement GetAllFiles method, so use ListServices
// and grab files from there. // and grab files from there.
allFiles := map[string]*desc.FileDescriptor{}
svcNames, err := source.ListServices() svcNames, err := source.ListServices()
if err != nil { if err != nil {
return nil, err firstError = err
} } else {
allFiles := map[string]*desc.FileDescriptor{}
for _, name := range svcNames { for _, name := range svcNames {
d, err := source.FindSymbol(name) d, err := source.FindSymbol(name)
if err != nil { if err != nil {
return nil, err if firstError == nil {
firstError = err
} }
} else {
addAllFilesToSet(d.GetFile(), allFiles) addAllFilesToSet(d.GetFile(), allFiles)
} }
}
files = make([]*desc.FileDescriptor, len(allFiles)) files = make([]*desc.FileDescriptor, len(allFiles))
i := 0 i := 0
for _, fd := range allFiles { for _, fd := range allFiles {
@ -83,9 +85,10 @@ func GetAllFiles(source DescriptorSource) ([]*desc.FileDescriptor, error) {
i++ i++
} }
} }
}
sort.Sort(filesByName(files)) sort.Sort(filesByName(files))
return files, nil return files, firstError
} }
type filesByName []*desc.FileDescriptor type filesByName []*desc.FileDescriptor