Index: appengine/logdog/coordinator/service.go |
diff --git a/appengine/logdog/coordinator/service.go b/appengine/logdog/coordinator/service.go |
index 660293f369eabeb116da508156d0ac1247a5319f..226955d261f1db536ebebcd99299af1f20faec35 100644 |
--- a/appengine/logdog/coordinator/service.go |
+++ b/appengine/logdog/coordinator/service.go |
@@ -9,6 +9,7 @@ import ( |
"github.com/luci/luci-go/common/gcloud/gs" |
log "github.com/luci/luci-go/common/logging" |
"github.com/luci/luci-go/server/logdog/storage" |
+ "github.com/luci/luci-go/server/logdog/storage/archive" |
"golang.org/x/net/context" |
) |
@@ -16,12 +17,15 @@ import ( |
// is primarily usable as a means of consistently stubbing out various external |
// components. |
type Service struct { |
- // StorageFunc is a function that generates an intermediate Storage instance |
+ // IntermediateStorageFunc is a function that generates an intermediate Storage instance |
// for use by this service. If nil, the production intermediate Storage |
// instance will be used. |
// |
// This is provided for testing purposes. |
- StorageFunc func(context.Context) (storage.Storage, error) |
+ IntermediateStorageFunc func(context.Context) (storage.Storage, error) |
+ |
+ // ArchiveStorageFunc returns Archive storage for the specified log stream. |
+ ArchiveStorageFunc func(context.Context, *LogStream) (storage.Storage, error) |
// GSClientFunc is a function that generates a Google Storage client instance |
// for use by this service. If nil, the production Google Storage Client will |
@@ -29,32 +33,76 @@ type Service struct { |
GSClientFunc func(context.Context) (gs.Client, error) |
} |
-// Storage retrieves the configured Storage instance. |
-func (s *Service) Storage(c context.Context) (storage.Storage, error) { |
- sf := s.StorageFunc |
- if sf == nil { |
- // Production: use BigTable storage. |
- sf = config.GetStorage |
+// StorageForLogStream returns the Storage instance to use for a given |
+// LogStream. |
+// |
+// The caller is responsible for calling Close on the returned Storage instance |
+// when finished. |
+func (s *Service) StorageForLogStream(c context.Context, ls *LogStream) (storage.Storage, error) { |
+ if !ls.Archived() { |
+ log.Debugf(c, "Log is not archived. Fetching from intermediate storage.") |
+ |
+ // Logs are not archived. Fetch from intermediate storage. |
+ return s.IntermediateStorage(c) |
+ } |
+ |
+ log.Debugf(c, "Log is archived. Fetching from archive storage.") |
+ return s.ArchiveStorage(c, ls) |
+} |
+ |
+// IntermediateStorage retrieves the configured intermediate Storage instance. |
+// The caller is responsible for calling Close on the returned Storage instance |
+// when finished. |
+func (s *Service) IntermediateStorage(c context.Context) (storage.Storage, error) { |
+ if sf := s.IntermediateStorageFunc; sf != nil { |
+ return sf(c) |
+ } |
+ |
+ // Production: use BigTable storage. |
+ st, err := config.GetStorage(c) |
+ if err != nil { |
+ log.Errorf(log.SetError(c, err), "Failed to get BigTable Storage instance.") |
+ return nil, err |
+ } |
+ return st, nil |
+} |
+ |
+// ArchiveStorage retrieves the configured archive Storage instance. |
+// The caller is responsible for calling Close on the returned Storage instance |
+// when finished. |
+func (s *Service) ArchiveStorage(c context.Context, ls *LogStream) (storage.Storage, error) { |
+ if sf := s.ArchiveStorageFunc; sf != nil { |
+ return sf(c, ls) |
+ } |
+ |
+ gs, err := s.GSClient(c) |
+ if err != nil { |
+ log.WithError(err).Errorf(c, "Failed to create Google Storage client.") |
+ return nil, err |
} |
- st, err := sf(c) |
+ st, err := archive.New(c, archive.Options{ |
+ IndexURL: ls.ArchiveIndexURL, |
+ StreamURL: ls.ArchiveStreamURL, |
+ Client: gs, |
+ }) |
if err != nil { |
- log.Errorf(log.SetError(c, err), "Failed to get Storage instance.") |
+ log.WithError(err).Errorf(c, "Failed to create Google Storage storage instance.") |
return nil, err |
} |
return st, nil |
} |
-// GSClient instantiates a Google Storage client. |
+// GSClient instantiates a Google Storage client. The caller is responsible |
+// for closing the client. |
func (s *Service) GSClient(c context.Context) (gs.Client, error) { |
- f := s.GSClientFunc |
- if f == nil { |
- f = gs.NewProdClient |
+ if f := s.GSClientFunc; f != nil { |
+ return f(c) |
} |
- gsc, err := f(c) |
+ gsc, err := gs.NewProdClient(c) |
if err != nil { |
- log.Errorf(log.SetError(c, err), "Failed to get Google Storage client.") |
+ log.Errorf(log.SetError(c, err), "Failed to get production Google Storage client.") |
return nil, err |
} |
return gsc, nil |