| 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
|
|
|