lang: gapi, unification: Shutdown unification quickly when asked

This is a bit of a hack until we improve the GAPI a bit, but will let us
shut down type unification a bit faster if we want to interrupt a long
running operation. Hopefully our future algorthmic performance
improvements will obliviate the need for this to be a common issue.
This commit is contained in:
James Shubin
2024-03-22 03:21:15 -04:00
parent c4b14ac40d
commit 89784e86bd
3 changed files with 19 additions and 1 deletions

View File

@@ -503,6 +503,16 @@ func (obj *GAPI) Graph() (*pgraph.Graph, error) {
// Next returns nil errors every time there could be a new graph. // Next returns nil errors every time there could be a new graph.
func (obj *GAPI) Next() chan gapi.Next { 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) ch := make(chan gapi.Next)
obj.wg.Add(1) obj.wg.Add(1)
go func() { go func() {
@@ -553,7 +563,7 @@ func (obj *GAPI) Next() chan gapi.Next {
// run up to these three but fail on err // run up to these three but fail on err
if e := obj.LangClose(); e != nil { // close any old lang if e := obj.LangClose(); e != nil { // close any old lang
err = e // pass through the err 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 err = e // pass through the err
// Always run LangClose after LangInit // Always run LangClose after LangInit

View File

@@ -232,6 +232,7 @@ func (obj *Lang) Init(ctx context.Context) error {
Debug: obj.Debug, Debug: obj.Debug,
Logf: logf, Logf: logf,
} }
// NOTE: This is the "real" Unify that runs. (This is not for deploy.)
unifyErr := unifier.Unify(ctx) unifyErr := unifier.Unify(ctx)
obj.Logf("type unification took: %s", time.Since(timing)) obj.Logf("type unification took: %s", time.Since(timing))
if unifyErr != nil { if unifyErr != nil {

View File

@@ -771,6 +771,13 @@ Loop:
} }
// is there another EqualityWrapFuncInvariant with the same Expr1 pointer? // is there another EqualityWrapFuncInvariant with the same Expr1 pointer?
for _, fn := range fnInvariants { 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 ? // is this fn.Expr1 related by equivalency graph to eq.Expr1 ?
if (eq.Expr1 != fn.Expr1) && !inEquiv(fn.Expr1) { if (eq.Expr1 != fn.Expr1) && !inEquiv(fn.Expr1) {
if obj.Debug { if obj.Debug {