forked from TrueCloudLab/frostfs-http-gw
[#198] Fix expiration epoch calculation
Previous implementation does not provide 'at least' lifetime guarantee. Signed-off-by: Alex Vanin <a.vanin@yadro.com>
This commit is contained in:
parent
4dcdb8ef02
commit
a1052c04db
2 changed files with 33 additions and 5 deletions
|
@ -3,6 +3,7 @@ package uploader
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -121,7 +122,18 @@ func prepareExpirationHeader(headers map[string]string, epochDurations *epochDur
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateExpirationHeader(headers map[string]string, durations *epochDurations, expDuration time.Duration) {
|
func updateExpirationHeader(headers map[string]string, durations *epochDurations, expDuration time.Duration) {
|
||||||
epochDuration := durations.msPerBlock * int64(durations.blockPerEpoch)
|
epochDuration := uint64(durations.msPerBlock) * durations.blockPerEpoch
|
||||||
numEpoch := expDuration.Milliseconds() / epochDuration
|
currentEpoch := durations.currentEpoch
|
||||||
headers[object.SysAttributeExpEpoch] = strconv.FormatInt(int64(durations.currentEpoch)+numEpoch, 10)
|
numEpoch := uint64(expDuration.Milliseconds()) / epochDuration
|
||||||
|
|
||||||
|
if uint64(expDuration.Milliseconds())%epochDuration != 0 {
|
||||||
|
numEpoch++
|
||||||
|
}
|
||||||
|
|
||||||
|
expirationEpoch := uint64(math.MaxUint64)
|
||||||
|
if numEpoch < math.MaxUint64-currentEpoch {
|
||||||
|
expirationEpoch = currentEpoch + numEpoch
|
||||||
|
}
|
||||||
|
|
||||||
|
headers[object.SysAttributeExpEpoch] = strconv.FormatUint(expirationEpoch, 10)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package uploader
|
package uploader
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -52,8 +53,13 @@ func TestPrepareExpirationHeader(t *testing.T) {
|
||||||
blockPerEpoch: 101,
|
blockPerEpoch: 101,
|
||||||
}
|
}
|
||||||
|
|
||||||
epochPerDay := (24 * time.Hour).Milliseconds() / int64(defaultDurations.blockPerEpoch) / defaultDurations.msPerBlock
|
msPerBlock := defaultDurations.blockPerEpoch * uint64(defaultDurations.msPerBlock)
|
||||||
defaultExpEpoch := strconv.FormatInt(int64(defaultDurations.currentEpoch)+epochPerDay, 10)
|
epochPerDay := uint64((24 * time.Hour).Milliseconds()) / msPerBlock
|
||||||
|
if uint64((24*time.Hour).Milliseconds())%msPerBlock != 0 {
|
||||||
|
epochPerDay++
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultExpEpoch := strconv.FormatUint(defaultDurations.currentEpoch+epochPerDay, 10)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -130,6 +136,16 @@ func TestPrepareExpirationHeader(t *testing.T) {
|
||||||
durations: defaultDurations,
|
durations: defaultDurations,
|
||||||
expected: map[string]string{object.SysAttributeExpEpoch: defaultExpEpoch},
|
expected: map[string]string{object.SysAttributeExpEpoch: defaultExpEpoch},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
name: "valid max uint 64",
|
||||||
|
headers: map[string]string{utils.ExpirationRFC3339Attr: tomorrow.Format(time.RFC3339)},
|
||||||
|
durations: &epochDurations{
|
||||||
|
currentEpoch: math.MaxUint64 - 1,
|
||||||
|
msPerBlock: defaultDurations.msPerBlock,
|
||||||
|
blockPerEpoch: defaultDurations.blockPerEpoch,
|
||||||
|
},
|
||||||
|
expected: map[string]string{object.SysAttributeExpEpoch: strconv.FormatUint(uint64(math.MaxUint64), 10)},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: "invalid timestamp sec",
|
name: "invalid timestamp sec",
|
||||||
headers: map[string]string{utils.ExpirationTimestampAttr: "abc"},
|
headers: map[string]string{utils.ExpirationTimestampAttr: "abc"},
|
||||||
|
|
Loading…
Reference in a new issue