2023-07-21 15:16:35 -06:00
|
|
|
package graphvent
|
|
|
|
import (
|
2023-07-29 16:00:01 -06:00
|
|
|
"time"
|
2023-07-29 16:34:21 -06:00
|
|
|
"reflect"
|
2023-08-01 14:09:29 -06:00
|
|
|
"fmt"
|
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-29 19:16:33 -06:00
|
|
|
"github.com/google/uuid"
|
2023-07-21 15:16:35 -06:00
|
|
|
)
|
|
|
|
|
2023-07-29 16:34:21 -06:00
|
|
|
func GetFieldNames(ctx *Context, selection_set *ast.SelectionSet) []string {
|
2023-07-29 11:03:41 -06:00
|
|
|
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:
|
|
|
|
names = append(names, field.Name.Value)
|
|
|
|
case *ast.InlineFragment:
|
|
|
|
names = append(names, GetFieldNames(ctx, field.SelectionSet)...)
|
|
|
|
default:
|
|
|
|
ctx.Log.Logf("gql", "Unknown selection type: %s", reflect.TypeOf(field))
|
2023-07-29 11:03:41 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return names
|
|
|
|
}
|
|
|
|
|
2023-07-29 16:34:21 -06:00
|
|
|
func GetResolveFields(ctx *Context, p graphql.ResolveParams) []string {
|
|
|
|
names := []string{}
|
|
|
|
for _, field := range(p.Info.FieldASTs) {
|
|
|
|
names = append(names, GetFieldNames(ctx, field.SelectionSet)...)
|
|
|
|
}
|
|
|
|
|
|
|
|
return names
|
|
|
|
}
|
|
|
|
|
2023-07-29 19:16:33 -06:00
|
|
|
func ResolveNodes(ctx *ResolveContext, p graphql.ResolveParams, ids []NodeID) ([]NodeResult, error) {
|
2023-07-29 18:27:52 -06:00
|
|
|
fields := GetResolveFields(ctx.Context, p)
|
2023-07-29 19:16:33 -06:00
|
|
|
ctx.Context.Log.Logf("gql", "RESOLVE_NODES(%+v): %+v", ids, fields)
|
2023-07-29 18:27:52 -06:00
|
|
|
|
2023-07-31 20:53:56 -06:00
|
|
|
resp_channels := map[uuid.UUID]chan Signal{}
|
|
|
|
node_ids := map[uuid.UUID]NodeID{}
|
2023-07-29 19:16:33 -06:00
|
|
|
for _, id := range(ids) {
|
|
|
|
// Get a list of fields that will be written
|
|
|
|
ext_fields, err := ctx.GQLContext.GetACLFields(p.Info.FieldName, fields)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
// Create a read signal, send it to the specified node, and add the wait to the response map if the send returns no error
|
|
|
|
read_signal := NewReadSignal(ext_fields)
|
2023-08-01 20:55:15 -06:00
|
|
|
auth_signal, err := NewAuthorizedSignal(ctx.Key, &read_signal)
|
2023-08-01 14:09:29 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-29 16:00:01 -06:00
|
|
|
|
2023-07-29 19:16:33 -06:00
|
|
|
|
2023-07-31 21:03:48 -06:00
|
|
|
response_chan := ctx.Ext.GetResponseChannel(read_signal.ID())
|
2023-07-31 20:53:56 -06:00
|
|
|
resp_channels[read_signal.ID()] = response_chan
|
|
|
|
node_ids[read_signal.ID()] = id
|
|
|
|
|
2023-08-07 20:26:02 -06:00
|
|
|
err = ctx.Context.Send(ctx.Server.ID, []Message{Message{id, auth_signal}})
|
2023-07-29 19:16:33 -06:00
|
|
|
if err != nil {
|
2023-07-31 21:03:48 -06:00
|
|
|
ctx.Ext.FreeResponseChannel(read_signal.ID())
|
2023-07-29 19:16:33 -06:00
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-29 18:27:52 -06:00
|
|
|
}
|
2023-07-29 16:00:01 -06:00
|
|
|
|
2023-07-29 19:16:33 -06:00
|
|
|
responses := []NodeResult{}
|
2023-07-31 20:53:56 -06:00
|
|
|
for sig_id, response_chan := range(resp_channels) {
|
2023-07-29 19:16:33 -06:00
|
|
|
// Wait for the response, returning an error on timeout
|
2023-07-31 20:53:56 -06:00
|
|
|
response, err := WaitForResult(response_chan, time.Millisecond*100, sig_id)
|
2023-07-29 19:16:33 -06:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-08-01 14:09:29 -06:00
|
|
|
switch resp := response.(type) {
|
2023-08-01 20:55:15 -06:00
|
|
|
case *ReadResultSignal:
|
2023-08-01 14:09:29 -06:00
|
|
|
responses = append(responses, NodeResult{node_ids[sig_id], resp})
|
2023-08-01 20:55:15 -06:00
|
|
|
case *ErrorSignal:
|
2023-08-07 20:26:02 -06:00
|
|
|
return nil, fmt.Errorf(resp.Error)
|
2023-08-01 14:09:29 -06:00
|
|
|
default:
|
|
|
|
return nil, fmt.Errorf("BAD_TYPE: %s", reflect.TypeOf(resp))
|
|
|
|
}
|
2023-07-29 18:27:52 -06:00
|
|
|
}
|
2023-08-07 20:26:02 -06:00
|
|
|
ctx.Context.Log.Logf("gql", "RESOLVED_NODES")
|
2023-07-29 11:03:41 -06:00
|
|
|
|
2023-07-29 19:16:33 -06:00
|
|
|
return responses, nil
|
2023-07-21 15:16:35 -06:00
|
|
|
}
|