func (c *Context) Purge() {
	c.ContextCancel()
}
Purge cancels the context.
package resolver
import (
	"context"
	"sync"
	"github.com/rgraphql/magellan/varstore"
	"github.com/rgraphql/magellan/qtree"
	proto "github.com/rgraphql/rgraphql"
)
type Context struct {
	Context context.Context
	ContextCancel context.CancelFunc
	QNode *qtree.QueryTreeNode
	PathParent *Context
	PathComponent *proto.RGQLValue
	PathMtx sync.Mutex
	IsFinal bool
	ActiveChildren int
	writer ValueWriter
}
type ValueWriter interface {
	WriteValue(value *Value)
}
func NewContext(ctx context.Context, qnode *qtree.QueryTreeNode, writer ValueWriter) *Context {
	rctx, rctxCancel := context.WithCancel(ctx)
	return &Context{
		Context:       rctx,
		ContextCancel: rctxCancel,
		QNode: qnode,
		writer: writer,
	}
}
func (c *Context) WriteValue(val *Value, isFinal bool) {
	if c.PathComponent == nil {
		c.PathParent.WriteValue(val, isFinal)
		return
	}
	if isFinal {
		c.MarkFinal()
	}
	val.Context = c
	c.writer.WriteValue(val)
}
func (c *Context) MarkFinal() {
	c.PathMtx.Lock()
	defer c.PathMtx.Unlock()
	if c.IsFinal {
		return
	}
	c.IsFinal = true
	if c.PathParent != nil {
		c.PathParent.markChildFinal()
	}
}
func (c *Context) markChildFinal() {
	c.PathMtx.Lock()
	defer c.PathMtx.Unlock()
	if c.ActiveChildren > 0 {
		c.ActiveChildren--
	}
	if c.ActiveChildren == 0 {
		c.IsFinal = true
		if c.PathParent != nil {
			c.PathParent.markChildFinal()
		}
	}
}
func (c *Context) SetError(err error) {
	c.WriteValue(BuildErrorValue(err), true)
}
func (c *Context) baseChild(pathComponent *proto.RGQLValue) *Context {
	result := &Context{
		PathComponent: pathComponent,
		QNode:         c.QNode,
		writer: c.writer,
	}
	result.Context, result.ContextCancel = context.WithCancel(c.Context)
	if c.PathComponent != nil {
		result.PathParent = c
	} else {
		result.PathParent = c.PathParent
	}
	result.PathMtx.Lock()
	result.ActiveChildren++
	result.IsFinal = false
	result.PathMtx.Unlock()
	return result
}
func (c *Context) FieldChild(qnode *qtree.QueryTreeNode) *Context {
	child := c.baseChild(&proto.RGQLValue{QueryNodeId: qnode.Id})
	child.QNode = qnode
	return child
}
func (c *Context) ArrayChild(index int) *Context {
	return c.baseChild(&proto.RGQLValue{ArrayIndex: uint32(index + 1)})
}
func (c *Context) GetQueryArgument(argName string) *varstore.VariableReference {
	if c.QNode == nil || c.QNode.Arguments == nil {
		return nil
	}
	return c.QNode.Arguments[argName]
}
func (c *Context) VirtualChild() *Context {
	return c.baseChild(nil)
}