mirror of
https://github.com/v2fly/v2ray-core.git
synced 2025-06-26 21:29:58 +00:00

* update protogen to strip unused part * add persistent storage support * fix coding style * update linter setting * update github integration
112 lines
2.7 KiB
Go
112 lines
2.7 KiB
Go
package deferredpersistentstorage
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/v2fly/v2ray-core/v5/app/persistentstorage"
|
|
"github.com/v2fly/v2ray-core/v5/common/errors"
|
|
"github.com/v2fly/v2ray-core/v5/features/extension/storage"
|
|
)
|
|
|
|
type DeferredPersistentStorage interface {
|
|
storage.ScopedPersistentStorage
|
|
ProvideInner(ctx context.Context, inner persistentstorage.ScopedPersistentStorage)
|
|
}
|
|
|
|
var errNotExist = errors.New("persistent storage does not exist")
|
|
|
|
type deferredPersistentStorage struct {
|
|
ready context.Context
|
|
done context.CancelFunc
|
|
inner persistentstorage.ScopedPersistentStorage
|
|
|
|
awaitingChildren []*deferredPersistentStorage
|
|
|
|
intoScopes []string
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) ScopedPersistentStorageEngine() {
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) Put(ctx context.Context, key []byte, value []byte) error {
|
|
<-d.ready.Done()
|
|
if d.inner == nil {
|
|
return errNotExist
|
|
}
|
|
return d.inner.Put(ctx, key, value)
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) Get(ctx context.Context, key []byte) ([]byte, error) {
|
|
<-d.ready.Done()
|
|
if d.inner == nil {
|
|
return nil, errNotExist
|
|
}
|
|
return d.inner.Get(ctx, key)
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) List(ctx context.Context, keyPrefix []byte) ([][]byte, error) {
|
|
<-d.ready.Done()
|
|
if d.inner == nil {
|
|
return nil, errNotExist
|
|
}
|
|
return d.inner.List(ctx, keyPrefix)
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) Clear(ctx context.Context) {
|
|
<-d.ready.Done()
|
|
if d.inner == nil {
|
|
return
|
|
}
|
|
d.inner.Clear(ctx)
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) NarrowScope(ctx context.Context, key []byte) (storage.ScopedPersistentStorage, error) {
|
|
if d.ready.Err() != nil {
|
|
return d.inner.NarrowScope(ctx, key)
|
|
}
|
|
ready, done := context.WithCancel(ctx)
|
|
swallowCopyScopes := d.intoScopes
|
|
dps := &deferredPersistentStorage{
|
|
ready: ready,
|
|
done: done,
|
|
inner: nil,
|
|
intoScopes: append(swallowCopyScopes, string(key)),
|
|
}
|
|
d.awaitingChildren = append(d.awaitingChildren, dps)
|
|
return dps, nil
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) DropScope(ctx context.Context, key []byte) error {
|
|
<-d.ready.Done()
|
|
if d.inner == nil {
|
|
return errNotExist
|
|
}
|
|
return d.inner.DropScope(ctx, key)
|
|
}
|
|
|
|
func (d *deferredPersistentStorage) ProvideInner(ctx context.Context, inner persistentstorage.ScopedPersistentStorage) {
|
|
d.inner = inner
|
|
if inner != nil {
|
|
for _, scope := range d.intoScopes {
|
|
newScope, err := inner.NarrowScope(ctx, []byte(scope))
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
d.inner = newScope
|
|
}
|
|
}
|
|
for _, child := range d.awaitingChildren {
|
|
child.ProvideInner(ctx, d.inner)
|
|
}
|
|
d.done()
|
|
}
|
|
|
|
func NewDeferredPersistentStorage(ctx context.Context) DeferredPersistentStorage {
|
|
ready, done := context.WithCancel(ctx)
|
|
return &deferredPersistentStorage{
|
|
ready: ready,
|
|
done: done,
|
|
inner: nil,
|
|
}
|
|
}
|