Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
client
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Terraform modules
Analyze
Contributor analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
GitLab community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
elixxir
client
Commits
770c3cb1
Commit
770c3cb1
authored
Dec 15, 2021
by
Josh Brooks
Browse files
Options
Downloads
Patches
Plain Diff
Fix stored bucket implementation
parent
0d9e4bda
Branches
Branches containing commit
Tags
Tags containing commit
2 merge requests
!117
Release
,
!83
Add EKV backed leaky bucket storage
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
storage/utility/bucket.go
+59
-58
59 additions, 58 deletions
storage/utility/bucket.go
storage/versioned/kv.go
+5
-0
5 additions, 0 deletions
storage/versioned/kv.go
with
64 additions
and
58 deletions
storage/utility/bucket.go
+
59
−
58
View file @
770c3cb1
...
@@ -8,11 +8,12 @@
...
@@ -8,11 +8,12 @@
package
utility
package
utility
import
(
import
(
"github.com/pkg/errors"
"encoding/json"
jww
"github.com/spf13/jwalterweatherman"
"gitlab.com/elixxir/client/storage/versioned"
"gitlab.com/elixxir/client/storage/versioned"
"gitlab.com/xx_network/primitives/netTime"
"gitlab.com/xx_network/primitives/netTime"
"gitlab.com/xx_network/primitives/rateLimiting"
"gitlab.com/xx_network/primitives/rateLimiting"
"
sync
"
"
time
"
)
)
const
(
const
(
...
@@ -24,92 +25,92 @@ const (
...
@@ -24,92 +25,92 @@ const (
// BucketStore stores a leaky bucket into storage. The bucket
// BucketStore stores a leaky bucket into storage. The bucket
// is saved in a JSON-able format.
// is saved in a JSON-able format.
type
BucketStore
struct
{
type
BucketStore
struct
{
bucket
*
rateLimiting
.
Bucket
kv
*
versioned
.
KV
kv
*
versioned
.
KV
mux
sync
.
Mutex
}
}
// NewBucketStore creates a new, empty BucketStore and saves it to storage.
// bucketDisk is a JSON-able structure used to store
// If the primary method of modifying your BucketStore.bucket is via the method
// a rateLimiting.Bucket parameters.
// BucketStore.AddWithExternalParams, then the params argument may be
type
bucketDisk
struct
{
// default or junk data.
capacity
uint32
func
NewBucketStore
(
params
*
rateLimiting
.
BucketParams
,
timestamp
int64
kv
*
versioned
.
KV
)
(
*
BucketStore
,
error
)
{
}
// NewStoredBucket creates a new, empty Bucket and saves it to storage.
func
NewStoredBucket
(
capacity
,
leaked
uint32
,
leakDuration
time
.
Duration
,
kv
*
versioned
.
KV
)
*
rateLimiting
.
Bucket
{
bs
:=
&
BucketStore
{
bs
:=
&
BucketStore
{
bucket
:
rateLimiting
.
CreateBucketFromParams
(
params
,
nil
),
kv
:
kv
.
Prefix
(
bucketStorePrefix
),
kv
:
kv
.
Prefix
(
bucketStorePrefix
),
mux
:
sync
.
Mutex
{},
}
}
return
bs
,
bs
.
save
()
bs
.
save
(
0
,
time
.
Now
()
.
UnixNano
())
return
rateLimiting
.
CreateBucket
(
capacity
,
leaked
,
leakDuration
,
bs
.
save
)
}
}
// AddWithExternalParams adds the specified number of tokens to the bucket
// save stores the buckets values into storage.
// given external bucket parameters rather than the params specified in
func
(
s
*
BucketStore
)
save
(
inBucket
uint32
,
timestamp
int64
)
{
// the bucket. If an add is unsuccessful, an error is returned.
// Else the bucket is saved to storage.
// Create
func
(
s
*
BucketStore
)
AddWithExternalParams
(
tokens
uint32
,
bd
:=
bucketDisk
{
params
*
rateLimiting
.
MapParams
)
error
{
capacity
:
inBucket
,
s
.
mux
.
Lock
()
timestamp
:
timestamp
,
defer
s
.
mux
.
Unlock
()
}
success
,
_
:=
s
.
bucket
.
AddWithExternalParams
(
tokens
,
data
,
err
:=
json
.
Marshal
(
&
bd
)
params
.
Capacity
,
params
.
LeakedTokens
,
if
err
!=
nil
{
params
.
LeakDuration
)
jww
.
ERROR
.
Printf
(
"Failed to marshal %s bucket data for"
+
if
err
:=
s
.
save
();
err
!=
nil
{
" storage: %v"
,
s
.
kv
.
GetPrefix
(),
err
)
return
errors
.
WithMessagef
(
err
,
"Failed to save"
)
}
}
if
!
success
{
obj
:=
versioned
.
Object
{
return
errors
.
Errorf
(
"Failed to add to bucket"
)
Version
:
bucketStoreVersion
,
Timestamp
:
netTime
.
Now
(),
Data
:
data
,
}
}
return
nil
err
=
s
.
kv
.
Set
(
bucketStoreKey
,
bucketStoreVersion
,
&
obj
)
if
err
!=
nil
{
jww
.
ERROR
.
Printf
(
"Failed to store %s bucket data: %v"
,
s
.
kv
.
GetPrefix
(),
err
)
}
}
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// Storage Functions //
// Storage Functions //
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// LoadBucket
Store
is a storage operation which loads a bucket from storage.
// LoadBucket is a storage operation which loads a bucket from storage.
func
LoadBucket
Store
(
params
*
rateLimiting
.
BucketParams
,
func
LoadBucket
(
capacity
,
leaked
uint32
,
leakDuration
time
.
Duration
,
kv
*
versioned
.
KV
)
(
*
Bucket
Store
,
error
)
{
kv
*
versioned
.
KV
)
(
*
rateLimiting
.
Bucket
,
error
)
{
bs
:=
&
BucketStore
{
bs
:=
&
BucketStore
{
bucket
:
rateLimiting
.
CreateBucketFromParams
(
params
,
nil
),
kv
:
kv
.
Prefix
(
bucketStorePrefix
),
kv
:
kv
.
Prefix
(
bucketStorePrefix
),
mux
:
sync
.
Mutex
{},
}
}
inBucket
,
ts
,
err
:=
bs
.
load
()
return
bs
,
bs
.
load
()
}
// save is a non-thread-safe method of saving the bucket to storage. It is
// the responsibility of the caller to hold the lock for BucketStore.
func
(
s
*
BucketStore
)
save
()
error
{
data
,
err
:=
s
.
bucket
.
MarshalJSON
()
if
err
!=
nil
{
if
err
!=
nil
{
return
errors
.
Errorf
(
"Failed to marshal bucket: %v"
,
err
)
return
nil
,
err
}
obj
:=
versioned
.
Object
{
Version
:
bucketStoreVersion
,
Timestamp
:
netTime
.
Now
(),
Data
:
data
,
}
}
return
s
.
kv
.
Set
(
bucketStoreKey
,
bucketStoreVersion
,
&
obj
)
return
rateLimiting
.
CreateBucketFromDB
(
capacity
,
leaked
,
leakDuration
,
inBucket
,
ts
,
bs
.
save
),
nil
}
}
// load is a helper function which extracts the bucket data from storage
// load is a helper function which extracts the bucket data from storage
// and loads it back into BucketStore.
// and loads it back into BucketStore.
func
(
s
*
BucketStore
)
load
()
error
{
func
(
s
*
BucketStore
)
load
()
(
uint32
,
int64
,
error
)
{
// Load the versioned object
// Load the versioned object
vo
,
err
:=
s
.
kv
.
Get
(
bucketStoreKey
,
bucketStoreVersion
)
vo
,
err
:=
s
.
kv
.
Get
(
bucketStoreKey
,
bucketStoreVersion
)
if
err
!=
nil
{
if
err
!=
nil
{
return
err
return
0
,
0
,
err
}
bd
:=
bucketDisk
{}
err
=
json
.
Unmarshal
(
vo
.
Data
,
&
bd
)
if
err
!=
nil
{
return
0
,
0
,
err
}
}
return
s
.
bucket
.
UnmarshalJSON
(
vo
.
Data
)
return
bd
.
capacity
,
bd
.
timestamp
,
err
}
}
This diff is collapsed.
Click to expand it.
storage/versioned/kv.go
+
5
−
0
View file @
770c3cb1
...
@@ -137,6 +137,11 @@ func (v *KV) Set(key string, version uint64, object *Object) error {
...
@@ -137,6 +137,11 @@ func (v *KV) Set(key string, version uint64, object *Object) error {
return
v
.
r
.
data
.
Set
(
key
,
object
)
return
v
.
r
.
data
.
Set
(
key
,
object
)
}
}
// GetPrefix returns the prefix of the KV.
func
(
v
*
KV
)
GetPrefix
()
string
{
return
v
.
prefix
}
//Returns a new KV with the new prefix
//Returns a new KV with the new prefix
func
(
v
*
KV
)
Prefix
(
prefix
string
)
*
KV
{
func
(
v
*
KV
)
Prefix
(
prefix
string
)
*
KV
{
kvPrefix
:=
KV
{
kvPrefix
:=
KV
{
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment