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 (
|
var (
|
||||||
|
_ Item = &unindexedPrefetchedItem{}
|
||||||
|
_ ItemModTime = &unindexedPrefetchedItem{}
|
||||||
|
|
||||||
_ Item = &prefetchedItem{}
|
_ Item = &prefetchedItem{}
|
||||||
_ ItemInfo = &prefetchedItem{}
|
_ ItemInfo = &prefetchedItem{}
|
||||||
_ ItemModTime = &prefetchedItem{}
|
_ ItemModTime = &prefetchedItem{}
|
||||||
|
|
||||||
|
_ Item = &unindexedLazyItem{}
|
||||||
|
_ ItemModTime = &unindexedLazyItem{}
|
||||||
|
|
||||||
_ Item = &lazyItem{}
|
_ Item = &lazyItem{}
|
||||||
_ ItemInfo = &lazyItem{}
|
_ ItemInfo = &lazyItem{}
|
||||||
_ ItemModTime = &lazyItem{}
|
_ ItemModTime = &lazyItem{}
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewDeletedItem(itemID string) Item {
|
func NewDeletedItem(itemID string) Item {
|
||||||
return &prefetchedItem{
|
return &unindexedPrefetchedItem{
|
||||||
id: itemID,
|
id: itemID,
|
||||||
deleted: true,
|
deleted: true,
|
||||||
// TODO(ashmrtn): This really doesn't need to be set since deleted items are
|
// 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,
|
reader io.ReadCloser,
|
||||||
itemID string,
|
itemID string,
|
||||||
info details.ItemInfo,
|
modTime time.Time,
|
||||||
) Item {
|
) Item {
|
||||||
return &prefetchedItem{
|
return &unindexedPrefetchedItem{
|
||||||
id: itemID,
|
id: itemID,
|
||||||
reader: reader,
|
reader: reader,
|
||||||
info: info,
|
modTime: modTime,
|
||||||
modTime: info.Modified(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefetchedItem represents a single item retrieved from the remote service.
|
// unindexedPrefetchedItem represents a single item retrieved from the remote
|
||||||
type prefetchedItem struct {
|
// 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
|
id string
|
||||||
reader io.ReadCloser
|
reader io.ReadCloser
|
||||||
info details.ItemInfo
|
|
||||||
// modTime is the modified time of the item. It should match the modTime in
|
// 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
|
// 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.
|
// don't error out by trying to source it from info.
|
||||||
@ -63,26 +72,50 @@ type prefetchedItem struct {
|
|||||||
deleted bool
|
deleted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i prefetchedItem) ID() string {
|
func (i unindexedPrefetchedItem) ID() string {
|
||||||
return i.id
|
return i.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *prefetchedItem) ToReader() io.ReadCloser {
|
func (i *unindexedPrefetchedItem) ToReader() io.ReadCloser {
|
||||||
return i.reader
|
return i.reader
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i prefetchedItem) Deleted() bool {
|
func (i unindexedPrefetchedItem) Deleted() bool {
|
||||||
return i.deleted
|
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) {
|
func (i prefetchedItem) Info() (details.ItemInfo, error) {
|
||||||
return i.info, nil
|
return i.info, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i prefetchedItem) ModTime() time.Time {
|
|
||||||
return i.modTime
|
|
||||||
}
|
|
||||||
|
|
||||||
type ItemDataGetter interface {
|
type ItemDataGetter interface {
|
||||||
GetData(
|
GetData(
|
||||||
context.Context,
|
context.Context,
|
||||||
@ -90,14 +123,14 @@ type ItemDataGetter interface {
|
|||||||
) (io.ReadCloser, *details.ItemInfo, bool, error)
|
) (io.ReadCloser, *details.ItemInfo, bool, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewLazyItem(
|
func NewUnindexedLazyItem(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
itemGetter ItemDataGetter,
|
itemGetter ItemDataGetter,
|
||||||
itemID string,
|
itemID string,
|
||||||
modTime time.Time,
|
modTime time.Time,
|
||||||
errs *fault.Bus,
|
errs *fault.Bus,
|
||||||
) Item {
|
) Item {
|
||||||
return &lazyItem{
|
return &unindexedLazyItem{
|
||||||
ctx: ctx,
|
ctx: ctx,
|
||||||
id: itemID,
|
id: itemID,
|
||||||
itemGetter: itemGetter,
|
itemGetter: itemGetter,
|
||||||
@ -106,10 +139,13 @@ func NewLazyItem(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// lazyItem represents a single item retrieved from the remote service. It
|
// unindexedLazyItem represents a single item retrieved from the remote service.
|
||||||
// lazily fetches the item's data when the first call to ToReader().Read() is
|
// It lazily fetches the item's data when the first call to ToReader().Read() is
|
||||||
// made.
|
// 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
|
ctx context.Context
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
id string
|
id string
|
||||||
@ -129,11 +165,11 @@ type lazyItem struct {
|
|||||||
delInFlight bool
|
delInFlight bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *lazyItem) ID() string {
|
func (i *unindexedLazyItem) ID() string {
|
||||||
return i.id
|
return i.id
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *lazyItem) ToReader() io.ReadCloser {
|
func (i *unindexedLazyItem) ToReader() io.ReadCloser {
|
||||||
return lazy.NewLazyReadCloser(func() (io.ReadCloser, error) {
|
return lazy.NewLazyReadCloser(func() (io.ReadCloser, error) {
|
||||||
// Don't allow getting Item info while trying to initialize said info.
|
// 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
|
// 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
|
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) {
|
func (i *lazyItem) Info() (details.ItemInfo, error) {
|
||||||
i.mu.Lock()
|
i.mu.Lock()
|
||||||
defer i.mu.Unlock()
|
defer i.mu.Unlock()
|
||||||
@ -184,7 +252,3 @@ func (i *lazyItem) Info() (details.ItemInfo, error) {
|
|||||||
|
|
||||||
return *i.info, nil
|
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)})
|
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() {
|
func (suite *ItemUnitSuite) TestDeletedItem() {
|
||||||
var (
|
var (
|
||||||
t = suite.T()
|
t = suite.T()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user