Skip to content

Commit 5014f26

Browse files
Merge pull request #166 from fastly/awilliams/config-store-max-len
Handle config store values larger than 8k
2 parents 11fceb8 + 8e6b4dc commit 5014f26

File tree

1 file changed

+23
-43
lines changed

1 file changed

+23
-43
lines changed

internal/abi/fastly/configstore_guest.go

Lines changed: 23 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
package fastly
66

77
import (
8-
"sync"
9-
108
"github.com/fastly/compute-sdk-go/internal/abi/prim"
119
)
1210

@@ -28,26 +26,14 @@ func fastlyConfigStoreOpen(
2826
// ConfigStore represents a Fastly config store a collection of read-only
2927
// key/value pairs. For convenience, keys are modeled as Go strings, and values
3028
// as byte slices.
31-
//
32-
// NOTE: wasm, by definition, is a single-threaded execution environment. This
33-
// allows us to use valueBuf scratch space between the guest and host to avoid
34-
// allocations any larger than necessary, without locking.
3529
type ConfigStore struct {
3630
h configstoreHandle
37-
38-
mu sync.Mutex // protects valueBuf
39-
valueBuf [configstoreMaxValueLen]byte
4031
}
4132

42-
// Dictionaries are subject to very specific limitations: 255 character keys and 8000 character values, utf-8 encoded.
43-
// The current storage collation limits utf-8 representations to 3 bytes in length.
33+
// Config Stores are limited to keys of length 255 character. By default, values are limited to 8000 character values,
34+
// but this can be adjust on a per-customer basis.
4435
// https://docs.fastly.com/en/guides/about-edge-dictionaries#limitations-and-considerations
45-
// https://dev.mysql.com/doc/refman/8.4/en/charset-unicode-utf8mb3.html
46-
// https://en.wikipedia.org/wiki/UTF-8#Encoding
47-
const (
48-
configstoreMaxKeyLen = 255 * 3 // known maximum size for config store keys: 755 bytes, for 255 3-byte utf-8 encoded characters
49-
configstoreMaxValueLen = 8000 * 3 // known maximum size for config store values: 24,000 bytes, for 8000 3-byte utf-8 encoded characters
50-
)
36+
const configstoreMaxKeyLen = 255 * 3 // known maximum size for config store keys: 755 bytes, for 255 3-byte utf-8 encoded characters
5137

5238
// OpenConfigStore returns a reference to the named config store, if it exists.
5339
func OpenConfigStore(name string) (*ConfigStore, error) {
@@ -85,39 +71,33 @@ func fastlyConfigStoreGet(
8571
nWritten prim.Pointer[prim.Usize],
8672
) FastlyStatus
8773

88-
// Get the value for key, if it exists. The returned slice's backing array is
89-
// shared between multiple calls to getBytesUnlocked.
90-
func (c *ConfigStore) getBytesUnlocked(key string) ([]byte, error) {
74+
// GetBytes returns a slice of newly-allocated memory for the value
75+
// corresponding to key.
76+
func (c *ConfigStore) GetBytes(key string) ([]byte, error) {
9177
keyBuffer := prim.NewReadBufferFromString(key)
9278
if keyBuffer.Len() > configstoreMaxKeyLen {
9379
return nil, FastlyStatusInval.toError()
9480
}
95-
buf := prim.NewWriteBufferFromBytes(c.valueBuf[:]) // fresh slice of backing array
9681
keyStr := keyBuffer.Wstring()
97-
status := fastlyConfigStoreGet(
98-
c.h,
99-
keyStr.Data, keyStr.Len,
100-
prim.ToPointer(buf.Char8Pointer()), buf.Cap(),
101-
prim.ToPointer(buf.NPointer()),
102-
)
103-
if err := status.toError(); err != nil {
104-
return nil, err
105-
}
106-
return buf.AsBytes(), nil
107-
}
10882

109-
// GetBytes returns a slice of newly-allocated memory for the value
110-
// corresponding to key.
111-
func (c *ConfigStore) GetBytes(key string) ([]byte, error) {
112-
c.mu.Lock()
113-
defer c.mu.Unlock()
114-
v, err := c.getBytesUnlocked(key)
115-
if err != nil {
116-
return nil, err
83+
n := DefaultSmallBufLen
84+
for {
85+
buf := prim.NewWriteBuffer(n)
86+
status := fastlyConfigStoreGet(
87+
c.h,
88+
keyStr.Data, keyStr.Len,
89+
prim.ToPointer(buf.Char8Pointer()), buf.Cap(),
90+
prim.ToPointer(buf.NPointer()),
91+
)
92+
if status == FastlyStatusBufLen && buf.NValue() > 0 {
93+
n = int(buf.NValue())
94+
continue
95+
}
96+
if err := status.toError(); err != nil {
97+
return nil, err
98+
}
99+
return buf.AsBytes(), nil
117100
}
118-
p := make([]byte, len(v))
119-
copy(p, v)
120-
return p, nil
121101
}
122102

123103
// Has returns true if key is found.

0 commit comments

Comments
 (0)