Create generic items without Info() (#4365)
Create generic Item implementations that don't implement the ItemInfo interface. These implementations can be used for things like metadata files. --- #### Does this PR need a docs update or release note? - [ ] ✅ Yes, it's included - [ ] 🕐 Yes, but in a later PR - [x] ⛔ No #### Type of change - [ ] 🌻 Feature - [ ] 🐛 Bugfix - [ ] 🗺️ Documentation - [ ] 🤖 Supportability/Tests - [ ] 💻 CI/Deployment - [x] 🧹 Tech Debt/Cleanup #### Issue(s) * #4191 #### Test Plan - [ ] 💪 Manual - [x] ⚡ Unit test - [ ] 💚 E2E
This commit is contained in:
parent
d5cdf37369
commit
5521177aee
@ -16,16 +16,23 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
_ Item = &unindexedPrefetchedItem{}
|
||||
_ ItemModTime = &unindexedPrefetchedItem{}
|
||||
|
||||
_ Item = &prefetchedItem{}
|
||||
_ ItemInfo = &prefetchedItem{}
|
||||
_ ItemModTime = &prefetchedItem{}
|
||||
|
||||
_ Item = &unindexedLazyItem{}
|
||||
_ ItemModTime = &unindexedLazyItem{}
|
||||
|
||||
_ Item = &lazyItem{}
|
||||
_ ItemInfo = &lazyItem{}
|
||||
_ ItemModTime = &lazyItem{}
|
||||
)
|
||||
|
||||
func NewDeletedItem(itemID string) Item {
|
||||
return &prefetchedItem{
|
||||
return &unindexedPrefetchedItem{
|
||||
id: itemID,
|
||||
deleted: true,
|
||||
// TODO(ashmrtn): This really doesn't need to be set since deleted items are
|
||||
@ -35,24 +42,26 @@ func NewDeletedItem(itemID string) Item {
|
||||
}
|
||||
}
|
||||
|
||||
func NewPrefetchedItem(
|
||||
func NewUnindexedPrefetchedItem(
|
||||
reader io.ReadCloser,
|
||||
itemID string,
|
||||
info details.ItemInfo,
|
||||
modTime time.Time,
|
||||
) Item {
|
||||
return &prefetchedItem{
|
||||
return &unindexedPrefetchedItem{
|
||||
id: itemID,
|
||||
reader: reader,
|
||||
info: info,
|
||||
modTime: info.Modified(),
|
||||
modTime: modTime,
|
||||
}
|
||||
}
|
||||
|
||||
// prefetchedItem represents a single item retrieved from the remote service.
|
||||
type prefetchedItem struct {
|
||||
// unindexedPrefetchedItem represents a single item retrieved from the remote
|
||||
// service.
|
||||
//
|
||||
// This item doesn't implement ItemInfo so it's safe to use for items like
|
||||
// metadata that shouldn't appear in backup details.
|
||||
type unindexedPrefetchedItem struct {
|
||||
id string
|
||||
reader io.ReadCloser
|
||||
info details.ItemInfo
|
||||
// modTime is the modified time of the item. It should match the modTime in
|
||||
// info if info is present. Here as a separate field so that deleted items
|
||||
// don't error out by trying to source it from info.
|
||||
@ -63,26 +72,50 @@ type prefetchedItem struct {
|
||||
deleted bool
|
||||
}
|
||||
|
||||
func (i prefetchedItem) ID() string {
|
||||
func (i unindexedPrefetchedItem) ID() string {
|
||||
return i.id
|
||||
}
|
||||
|
||||
func (i *prefetchedItem) ToReader() io.ReadCloser {
|
||||
func (i *unindexedPrefetchedItem) ToReader() io.ReadCloser {
|
||||
return i.reader
|
||||
}
|
||||
|
||||
func (i prefetchedItem) Deleted() bool {
|
||||
func (i unindexedPrefetchedItem) Deleted() bool {
|
||||
return i.deleted
|
||||
}
|
||||
|
||||
func (i unindexedPrefetchedItem) ModTime() time.Time {
|
||||
return i.modTime
|
||||
}
|
||||
|
||||
func NewPrefetchedItem(
|
||||
reader io.ReadCloser,
|
||||
itemID string,
|
||||
info details.ItemInfo,
|
||||
) Item {
|
||||
return &prefetchedItem{
|
||||
unindexedPrefetchedItem: unindexedPrefetchedItem{
|
||||
id: itemID,
|
||||
reader: reader,
|
||||
modTime: info.Modified(),
|
||||
},
|
||||
info: info,
|
||||
}
|
||||
}
|
||||
|
||||
// prefetchedItem represents a single item retrieved from the remote service.
|
||||
//
|
||||
// This item implements ItemInfo so it should be used for things that need to
|
||||
// appear in backup details.
|
||||
type prefetchedItem struct {
|
||||
unindexedPrefetchedItem
|
||||
info details.ItemInfo
|
||||
}
|
||||
|
||||
func (i prefetchedItem) Info() (details.ItemInfo, error) {
|
||||
return i.info, nil
|
||||
}
|
||||
|
||||
func (i prefetchedItem) ModTime() time.Time {
|
||||
return i.modTime
|
||||
}
|
||||
|
||||
type ItemDataGetter interface {
|
||||
GetData(
|
||||
context.Context,
|
||||
@ -90,14 +123,14 @@ type ItemDataGetter interface {
|
||||
) (io.ReadCloser, *details.ItemInfo, bool, error)
|
||||
}
|
||||
|
||||
func NewLazyItem(
|
||||
func NewUnindexedLazyItem(
|
||||
ctx context.Context,
|
||||
itemGetter ItemDataGetter,
|
||||
itemID string,
|
||||
modTime time.Time,
|
||||
errs *fault.Bus,
|
||||
) Item {
|
||||
return &lazyItem{
|
||||
return &unindexedLazyItem{
|
||||
ctx: ctx,
|
||||
id: itemID,
|
||||
itemGetter: itemGetter,
|
||||
@ -106,10 +139,13 @@ func NewLazyItem(
|
||||
}
|
||||
}
|
||||
|
||||
// lazyItem represents a single item retrieved from the remote service. It
|
||||
// lazily fetches the item's data when the first call to ToReader().Read() is
|
||||
// unindexedLazyItem represents a single item retrieved from the remote service.
|
||||
// It lazily fetches the item's data when the first call to ToReader().Read() is
|
||||
// made.
|
||||
type lazyItem struct {
|
||||
//
|
||||
// This item doesn't implement ItemInfo so it's safe to use for items like
|
||||
// metadata that shouldn't appear in backup details.
|
||||
type unindexedLazyItem struct {
|
||||
ctx context.Context
|
||||
mu sync.Mutex
|
||||
id string
|
||||
@ -129,11 +165,11 @@ type lazyItem struct {
|
||||
delInFlight bool
|
||||
}
|
||||
|
||||
func (i *lazyItem) ID() string {
|
||||
func (i *unindexedLazyItem) ID() string {
|
||||
return i.id
|
||||
}
|
||||
|
||||
func (i *lazyItem) ToReader() io.ReadCloser {
|
||||
func (i *unindexedLazyItem) ToReader() io.ReadCloser {
|
||||
return lazy.NewLazyReadCloser(func() (io.ReadCloser, error) {
|
||||
// Don't allow getting Item info while trying to initialize said info.
|
||||
// GetData could be a long running call, but in theory nothing should happen
|
||||
@ -167,10 +203,42 @@ func (i *lazyItem) ToReader() io.ReadCloser {
|
||||
})
|
||||
}
|
||||
|
||||
func (i *lazyItem) Deleted() bool {
|
||||
func (i *unindexedLazyItem) Deleted() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (i *unindexedLazyItem) ModTime() time.Time {
|
||||
return i.modTime
|
||||
}
|
||||
|
||||
func NewLazyItem(
|
||||
ctx context.Context,
|
||||
itemGetter ItemDataGetter,
|
||||
itemID string,
|
||||
modTime time.Time,
|
||||
errs *fault.Bus,
|
||||
) Item {
|
||||
return &lazyItem{
|
||||
unindexedLazyItem: unindexedLazyItem{
|
||||
ctx: ctx,
|
||||
id: itemID,
|
||||
itemGetter: itemGetter,
|
||||
modTime: modTime,
|
||||
errs: errs,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// lazyItem represents a single item retrieved from the remote service. It
|
||||
// lazily fetches the item's data when the first call to ToReader().Read() is
|
||||
// made.
|
||||
//
|
||||
// This item implements ItemInfo so it should be used for things that need to
|
||||
// appear in backup details.
|
||||
type lazyItem struct {
|
||||
unindexedLazyItem
|
||||
}
|
||||
|
||||
func (i *lazyItem) Info() (details.ItemInfo, error) {
|
||||
i.mu.Lock()
|
||||
defer i.mu.Unlock()
|
||||
@ -184,7 +252,3 @@ func (i *lazyItem) Info() (details.ItemInfo, error) {
|
||||
|
||||
return *i.info, nil
|
||||
}
|
||||
|
||||
func (i *lazyItem) ModTime() time.Time {
|
||||
return i.modTime
|
||||
}
|
||||
|
||||
@ -49,6 +49,31 @@ func TestItemUnitSuite(t *testing.T) {
|
||||
suite.Run(t, &ItemUnitSuite{Suite: tester.NewUnitSuite(t)})
|
||||
}
|
||||
|
||||
func (suite *ItemUnitSuite) TestUnindexedPrefetchedItem() {
|
||||
prefetch := data.NewUnindexedPrefetchedItem(
|
||||
io.NopCloser(bytes.NewReader([]byte{})),
|
||||
"foo",
|
||||
time.Time{})
|
||||
_, ok := prefetch.(data.ItemInfo)
|
||||
assert.False(suite.T(), ok, "unindexedPrefetchedItem implements Info()")
|
||||
}
|
||||
|
||||
func (suite *ItemUnitSuite) TestUnindexedLazyItem() {
|
||||
t := suite.T()
|
||||
|
||||
ctx, flush := tester.NewContext(t)
|
||||
defer flush()
|
||||
|
||||
lazy := data.NewUnindexedLazyItem(
|
||||
ctx,
|
||||
nil,
|
||||
"foo",
|
||||
time.Time{},
|
||||
fault.New(true))
|
||||
_, ok := lazy.(data.ItemInfo)
|
||||
assert.False(t, ok, "unindexedLazyItem implements Info()")
|
||||
}
|
||||
|
||||
func (suite *ItemUnitSuite) TestDeletedItem() {
|
||||
var (
|
||||
t = suite.T()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user