graphvent/gql_node.go

148 lines
3.6 KiB
Go

2023-07-21 15:16:35 -06:00
package graphvent
import (
2023-07-29 16:34:21 -06:00
"reflect"
"fmt"
2024-03-09 22:09:40 -07:00
"time"
2023-07-21 15:16:35 -06:00
"github.com/graphql-go/graphql"
2023-07-29 11:03:41 -06:00
"github.com/graphql-go/graphql/language/ast"
2023-07-21 15:16:35 -06:00
)
func ResolveNodeID(p graphql.ResolveParams) (interface{}, error) {
node, ok := p.Source.(NodeResult)
if ok == false {
return nil, fmt.Errorf("Can't get NodeID from %+v", reflect.TypeOf(p.Source))
}
return node.NodeID, nil
}
2024-03-09 22:09:40 -07:00
func ResolveNodeType(p graphql.ResolveParams) (interface{}, error) {
node, ok := p.Source.(NodeResult)
if ok == false {
return nil, fmt.Errorf("Can't get TypeHash from %+v", reflect.TypeOf(p.Source))
}
return uint64(node.NodeType), nil
}
2024-03-17 14:25:34 -06:00
type FieldIndex struct {
Extension ExtType
Tag string
}
2024-03-28 20:28:07 -06:00
func GetFields(selection_set *ast.SelectionSet) []string {
names := []string{}
2023-07-29 16:34:21 -06:00
if selection_set == nil {
return names
}
2023-07-29 11:03:41 -06:00
2023-07-29 16:34:21 -06:00
for _, sel := range(selection_set.Selections) {
switch field := sel.(type) {
case *ast.Field:
2024-03-17 14:25:34 -06:00
if field.Name.Value == "ID" || field.Name.Value == "Type" {
continue
}
2024-03-28 20:28:07 -06:00
names = append(names, field.Name.Value)
2023-07-29 16:34:21 -06:00
case *ast.InlineFragment:
2024-03-28 20:28:07 -06:00
names = append(names, GetFields(field.SelectionSet)...)
2023-07-29 11:03:41 -06:00
}
}
return names
}
2024-03-09 22:09:40 -07:00
// Returns the fields that need to be resolved
2024-03-28 20:28:07 -06:00
func GetResolveFields(p graphql.ResolveParams) []string {
fields := []string{}
2023-07-29 16:34:21 -06:00
for _, field := range(p.Info.FieldASTs) {
2024-03-28 20:28:07 -06:00
fields = append(fields, GetFields(field.SelectionSet)...)
2023-07-29 16:34:21 -06:00
}
return fields
}
func ResolveNode(id NodeID, p graphql.ResolveParams) (NodeResult, error) {
ctx, err := PrepResolve(p)
if err != nil {
return NodeResult{}, err
}
switch source := p.Source.(type) {
case *StatusSignal:
cached_node, cached := ctx.NodeCache[source.Source]
if cached {
2024-03-28 20:28:07 -06:00
for _, field_name := range(source.Fields) {
_, cached := cached_node.Data[field_name]
if cached {
2024-03-28 20:28:07 -06:00
delete(cached_node.Data, field_name)
}
}
ctx.NodeCache[source.Source] = cached_node
}
}
2024-03-09 22:09:40 -07:00
cache, node_cached := ctx.NodeCache[id]
2024-03-28 20:28:07 -06:00
fields := GetResolveFields(p)
var not_cached []string
if node_cached {
not_cached = []string{}
for _, field := range(fields) {
if node_cached {
_, field_cached := cache.Data[field]
2024-03-09 22:09:40 -07:00
if field_cached {
continue
}
}
2024-03-28 20:28:07 -06:00
not_cached = append(not_cached, field)
}
} else {
not_cached = fields
2024-03-09 22:09:40 -07:00
}
if (len(not_cached) == 0) && (node_cached == true) {
ctx.Context.Log.Logf("gql", "No new fields to resolve for %s", id)
return cache, nil
} else {
ctx.Context.Log.Logf("gql", "Resolving fields %+v on node %s", not_cached, id)
signal := NewReadSignal(not_cached)
response_chan := ctx.Ext.GetResponseChannel(signal.ID())
// TODO: TIMEOUT DURATION
err = ctx.Context.Send(ctx.Server, []Message{{
Node: id,
Signal: signal,
}})
if err != nil {
ctx.Ext.FreeResponseChannel(signal.ID())
return NodeResult{}, err
}
2024-03-09 22:09:40 -07:00
response, _, err := WaitForResponse(response_chan, 100*time.Millisecond, signal.ID())
2024-03-09 22:09:40 -07:00
ctx.Ext.FreeResponseChannel(signal.ID())
if err != nil {
return NodeResult{}, err
}
2024-03-09 22:09:40 -07:00
switch response := response.(type) {
case *ReadResultSignal:
if node_cached == false {
cache = NodeResult{
NodeID: id,
NodeType: response.NodeType,
2024-03-28 20:28:07 -06:00
Data: response.Fields,
2024-03-09 22:09:40 -07:00
}
} else {
2024-03-28 20:28:07 -06:00
for field_name, field_value := range(response.Fields) {
cache.Data[field_name] = field_value
}
2024-03-09 22:09:40 -07:00
}
ctx.NodeCache[id] = cache
return ctx.NodeCache[id], nil
default:
return NodeResult{}, fmt.Errorf("Bad read response: %+v", response)
}
2024-03-09 22:09:40 -07:00
}
2023-07-29 16:34:21 -06:00
}