forked from TrueCloudLab/frostfs-s3-gw
[#644] Support keepalive during listing
Send whitespaces every time as new object in list is ready to prevent client from context cancelling. Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
776fd042ef
commit
07b60b15b3
13 changed files with 309 additions and 17 deletions
|
@ -1,7 +1,9 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -841,6 +843,101 @@ func TestListingsWithInvalidEncodingType(t *testing.T) {
|
|||
listObjectsV1Err(hc, bktName, "invalid", apierr.GetAPIError(apierr.ErrInvalidEncodingMethod))
|
||||
}
|
||||
|
||||
func TestPeriodicWriter(t *testing.T) {
|
||||
const dur = 100 * time.Millisecond
|
||||
const whitespaces = 8
|
||||
expected := []byte(xml.Header)
|
||||
for i := 0; i < whitespaces; i++ {
|
||||
expected = append(expected, []byte(" ")...)
|
||||
}
|
||||
|
||||
t.Run("writes data", func(t *testing.T) {
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
|
||||
for range whitespaces {
|
||||
ch <- struct{}{}
|
||||
time.Sleep(dur)
|
||||
}
|
||||
}()
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
stop := periodicXMLWriter(buf, time.Nanosecond, ch)
|
||||
|
||||
// N number of whitespaces + half durations to guarantee at least N writes in buffer
|
||||
time.Sleep(whitespaces*dur + dur/2)
|
||||
require.True(t, stop())
|
||||
require.Equal(t, string(expected), buf.String())
|
||||
|
||||
t.Run("no additional data after stop", func(t *testing.T) {
|
||||
time.Sleep(2 * dur)
|
||||
require.Equal(t, string(expected), buf.String())
|
||||
})
|
||||
})
|
||||
|
||||
t.Run("does not write data", func(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
|
||||
for range whitespaces {
|
||||
time.Sleep(2 * dur)
|
||||
ch <- struct{}{}
|
||||
}
|
||||
}()
|
||||
|
||||
stop := periodicXMLWriter(buf, time.Nanosecond, ch)
|
||||
require.False(t, stop())
|
||||
require.Empty(t, buf.Bytes())
|
||||
})
|
||||
|
||||
t.Run("throttling works", func(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
|
||||
for range whitespaces {
|
||||
ch <- struct{}{}
|
||||
time.Sleep(dur / 2)
|
||||
}
|
||||
}()
|
||||
|
||||
stop := periodicXMLWriter(buf, dur, ch)
|
||||
// N number of whitespaces + half durations to guarantee at least N writes in buffer
|
||||
time.Sleep(whitespaces*dur + dur/2)
|
||||
require.True(t, stop())
|
||||
require.Equal(t, string(expected[:len(expected)-4]), buf.String())
|
||||
})
|
||||
|
||||
t.Run("disabled", func(t *testing.T) {
|
||||
buf := bytes.NewBuffer(nil)
|
||||
|
||||
ch := make(chan struct{})
|
||||
go func() {
|
||||
defer close(ch)
|
||||
|
||||
for range whitespaces {
|
||||
select {
|
||||
case ch <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
time.Sleep(dur / 2)
|
||||
}
|
||||
}()
|
||||
|
||||
stop := periodicXMLWriter(buf, 0, ch)
|
||||
// N number of whitespaces + half durations to guarantee at least N writes in buffer
|
||||
time.Sleep(whitespaces*dur + dur/2)
|
||||
require.False(t, stop())
|
||||
require.Empty(t, buf.String())
|
||||
})
|
||||
}
|
||||
|
||||
func checkVersionsNames(t *testing.T, versions *ListObjectsVersionsResponse, names []string) {
|
||||
for i, v := range versions.Version {
|
||||
require.Equal(t, names[i], v.Key)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue