diff --git a/lang/gapi/gapi.go b/lang/gapi/gapi.go index 56d22f06..b75fead9 100644 --- a/lang/gapi/gapi.go +++ b/lang/gapi/gapi.go @@ -503,6 +503,16 @@ func (obj *GAPI) Graph() (*pgraph.Graph, error) { // Next returns nil errors every time there could be a new graph. func (obj *GAPI) Next() chan gapi.Next { + // TODO: This ctx stuff is temporary until we improve the Next() API. + ctx, cancel := context.WithCancel(context.Background()) + obj.wg.Add(1) + go func() { + defer obj.wg.Done() + select { + case <-obj.closeChan: + cancel() // close the ctx to unblock type unification + } + }() ch := make(chan gapi.Next) obj.wg.Add(1) go func() { @@ -553,7 +563,7 @@ func (obj *GAPI) Next() chan gapi.Next { // run up to these three but fail on err if e := obj.LangClose(); e != nil { // close any old lang err = e // pass through the err - } else if e := obj.LangInit(context.TODO()); e != nil { // init the new one! + } else if e := obj.LangInit(ctx); e != nil { // init the new one! err = e // pass through the err // Always run LangClose after LangInit diff --git a/lang/lang.go b/lang/lang.go index 33a06436..3c9bd657 100644 --- a/lang/lang.go +++ b/lang/lang.go @@ -232,6 +232,7 @@ func (obj *Lang) Init(ctx context.Context) error { Debug: obj.Debug, Logf: logf, } + // NOTE: This is the "real" Unify that runs. (This is not for deploy.) unifyErr := unifier.Unify(ctx) obj.Logf("type unification took: %s", time.Since(timing)) if unifyErr != nil { diff --git a/lang/unification/simplesolver.go b/lang/unification/simplesolver.go index f14d17b0..6c3f0d0e 100644 --- a/lang/unification/simplesolver.go +++ b/lang/unification/simplesolver.go @@ -771,6 +771,13 @@ Loop: } // is there another EqualityWrapFuncInvariant with the same Expr1 pointer? for _, fn := range fnInvariants { + // XXX: I think we're busy in this loop a lot. + select { + case <-ctx.Done(): + return nil, ctx.Err() + default: + // pass + } // is this fn.Expr1 related by equivalency graph to eq.Expr1 ? if (eq.Expr1 != fn.Expr1) && !inEquiv(fn.Expr1) { if obj.Debug {