Skip to content

Commit

Permalink
chore: assign arena to resolvable and use only one arena per response.
Browse files Browse the repository at this point in the history
  • Loading branch information
StarpTech committed Sep 12, 2024
1 parent ea96d2d commit 3f7d9f4
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 22 deletions.
33 changes: 14 additions & 19 deletions v2/pkg/engine/resolve/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,14 +76,12 @@ type Loader struct {
attachServiceNameToErrorExtension bool
allowedErrorExtensionFields map[string]struct{}
defaultErrorExtensionCode string
astjsonArenaPool *astjson.ArenaPool
}

func (l *Loader) Free() {
l.info = nil
l.ctx = nil
l.resolvable = nil
l.astjsonArenaPool = nil
}

func (l *Loader) LoadGraphQLResponseData(ctx *Context, response *GraphQLResponse, resolvable *Resolvable) (err error) {
Expand Down Expand Up @@ -673,14 +671,17 @@ func (l *Loader) mergeErrors(res *result, fetchItem *FetchItem, value *astjson.V

}

astjsonArena := l.resolvable.astjsonArenaPool.Get()
defer l.resolvable.astjsonArenaPool.Put(astjsonArena)

l.optionallyOmitErrorLocations(values)
l.optionallyRewriteErrorPaths(fetchItem, values)
l.optionallyAllowCustomExtensionProperties(values)
l.optionallyEnsureExtensionErrorCode(values)
l.optionallyEnsureExtensionErrorCode(astjsonArena, values)

if l.subgraphErrorPropagationMode == SubgraphErrorPropagationModePassThrough {
// Attach datasource information to all errors when we don't wrap them
l.optionallyAttachServiceNameToErrorExtension(values, res.ds.Name)
l.optionallyAttachServiceNameToErrorExtension(astjsonArena, values, res.ds.Name)
l.setSubgraphStatusCode(values, res.statusCode)

// Allow to delete extensions entirely
Expand All @@ -702,7 +703,7 @@ func (l *Loader) mergeErrors(res *result, fetchItem *FetchItem, value *astjson.V
v := []*astjson.Value{errorObject}

// Only datasource information are attached to the root error in wrap mode
l.optionallyAttachServiceNameToErrorExtension(v, res.ds.Name)
l.optionallyAttachServiceNameToErrorExtension(astjsonArena, v, res.ds.Name)
l.setSubgraphStatusCode(v, res.statusCode)

// Allow to delete extensions entirely
Expand Down Expand Up @@ -741,14 +742,11 @@ func (l *Loader) optionallyAllowCustomExtensionProperties(values []*astjson.Valu
}

// optionallyEnsureExtensionErrorCode ensures that all values have an error code in the extensions object
func (l *Loader) optionallyEnsureExtensionErrorCode(values []*astjson.Value) {
func (l *Loader) optionallyEnsureExtensionErrorCode(arena *astjson.Arena, values []*astjson.Value) {
if l.defaultErrorExtensionCode == "" {
return
}

apool := l.astjsonArenaPool.Get()
defer l.astjsonArenaPool.Put(apool)

for _, value := range values {
if value.Exists("extensions") {
extensions := value.Get("extensions")
Expand All @@ -757,36 +755,33 @@ func (l *Loader) optionallyEnsureExtensionErrorCode(values []*astjson.Value) {
}

if !extensions.Exists("code") {
extensions.Set("code", apool.NewString(l.defaultErrorExtensionCode))
extensions.Set("code", arena.NewString(l.defaultErrorExtensionCode))
}
} else {
extensionsObj := apool.NewObject()
extensionsObj.Set("code", apool.NewString(l.defaultErrorExtensionCode))
extensionsObj := arena.NewObject()
extensionsObj.Set("code", arena.NewString(l.defaultErrorExtensionCode))
value.Set("extensions", extensionsObj)
}
}
}

// optionallyAttachServiceNameToErrorExtension attaches the service name to the extensions object of all values
func (l *Loader) optionallyAttachServiceNameToErrorExtension(values []*astjson.Value, serviceName string) {
func (l *Loader) optionallyAttachServiceNameToErrorExtension(arena *astjson.Arena, values []*astjson.Value, serviceName string) {
if !l.attachServiceNameToErrorExtension {
return
}

apool := l.astjsonArenaPool.Get()
defer l.astjsonArenaPool.Put(apool)

for _, value := range values {
if value.Exists("extensions") {
extensions := value.Get("extensions")
if extensions.Type() != astjson.TypeObject {
continue
}

extensions.Set("serviceName", apool.NewString(serviceName))
extensions.Set("serviceName", arena.NewString(serviceName))
} else {
extensionsObj := apool.NewObject()
extensionsObj.Set("serviceName", apool.NewString(serviceName))
extensionsObj := arena.NewObject()
extensionsObj.Set("serviceName", arena.NewString(serviceName))
value.Set("extensions", extensionsObj)
}
}
Expand Down
5 changes: 4 additions & 1 deletion v2/pkg/engine/resolve/resolvable.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ type Resolvable struct {
variables *astjson.Value
skipAddingNullErrors bool

parsers []*astjson.Parser
astjsonArenaPool *astjson.ArenaPool
parsers []*astjson.Parser

print bool
out io.Writer
Expand Down Expand Up @@ -53,6 +54,7 @@ func NewResolvable() *Resolvable {
xxh: xxhash.New(),
authorizationAllow: make(map[uint64]struct{}),
authorizationDeny: make(map[uint64]string),
astjsonArenaPool: &astjson.ArenaPool{},
}
}

Expand Down Expand Up @@ -86,6 +88,7 @@ func (r *Resolvable) Reset(maxRecyclableParserSize int) {
r.operationType = ast.OperationTypeUnknown
r.renameTypeNames = r.renameTypeNames[:0]
r.authorizationError = nil
r.astjsonArenaPool = nil
r.xxh.Reset()
for k := range r.authorizationAllow {
delete(r.authorizationAllow, k)
Expand Down
2 changes: 0 additions & 2 deletions v2/pkg/engine/resolve/resolve.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"bytes"
"context"
"fmt"
"github.com/wundergraph/astjson"
"io"
"sync"
"time"
Expand Down Expand Up @@ -157,7 +156,6 @@ func New(ctx context.Context, options ResolverOptions) *Resolver {
allowedErrorExtensionFields: allowedExtensionFields,
attachServiceNameToErrorExtension: options.AttachServiceNameToErrorExtensions,
defaultErrorExtensionCode: options.DefaultErrorExtensionCode,
astjsonArenaPool: &astjson.ArenaPool{},
},
}
},
Expand Down

0 comments on commit 3f7d9f4

Please sign in to comment.