MCPcopy Create free account
hub / github.com/cel-expr/cel-go / launch

Method launch

interpreter/async.go:326–378  ·  view source on GitHub ↗

launch returns a call's cached result, or starts the call (subject to the launch limiter) and returns an Unknown referencing its callID while the result is pending. Admission control: when a concurrency semaphore is configured, a launch slot is reserved with a non-blocking send. If no slot is free

(ctx context.Context, acs *asyncCallState, observer AsyncObserver)

Source from the content-addressed store, hash-verified

324// The slot is held by the launched goroutine and released when it exits, so the number of live
325// async goroutines is bounded by the semaphore capacity.
326func (t *asyncCallStateTracker) launch(ctx context.Context, acs *asyncCallState, observer AsyncObserver) ref.Val {
327 if res := acs.ResultOrUnknown(); res != nil {
328 return res
329 }
330 gate := acs.gate
331 if !gate.TryAcquire() {
332 return types.NewUnknown(acs.callID, nil)
333 }
334 acs.mu.Lock()
335 if acs.started || acs.result != nil {
336 // Defensive: the evaluator is single-threaded so this should not happen, but if it does,
337 // return the reserved slot rather than leak it.
338 acs.mu.Unlock()
339 gate.Release()
340 return types.NewUnknown(acs.callID, nil)
341 }
342 acs.started = true
343 acs.mu.Unlock()
344
345 if observer != nil {
346 observer.OnCallStarted(acs.callID, acs.function, acs.overload, acs.argVals)
347 }
348 go func() {
349 defer func() {
350 if observer != nil {
351 observer.OnCallFinished(acs.callID, acs.function, acs.overload, acs.ResultOrUnknown())
352 }
353 gate.Complete(ctx, acs.callID)
354 }()
355
356 ch := acs.impl(ctx, acs.argVals...)
357 // Early terminate with a CEL error when an implementation returns an empty channel.
358 if ch == nil {
359 acs.SetResult(types.NewErrFromString(
360 fmt.Sprintf("function %s returned an empty channel", acs.function)))
361 return
362 }
363 // Wait for the async computation to finish or for the context to be cancelled.
364 select {
365 case r, ok := <-ch:
366 if !ok {
367 acs.SetResult(types.NewErrFromString(
368 fmt.Sprintf("function %s returned an empty channel", acs.function)))
369 return
370 }
371 acs.SetResult(r)
372 case <-ctx.Done():
373 // Evaluation context cancelled before the async operation completed.
374 acs.SetResult(types.WrapErr(context.Cause(ctx)))
375 }
376 }()
377 return types.NewUnknown(acs.callID, nil)
378}
379
380// matches reports whether two call states refer to the same function, overload, and arguments.
381func (acs *asyncCallState) matches(id int64, function, overload string, args []ref.Val) bool {

Callers 1

Calls 10

NewUnknownFunction · 0.92
NewErrFromStringFunction · 0.92
WrapErrFunction · 0.92
ResultOrUnknownMethod · 0.80
TryAcquireMethod · 0.80
CompleteMethod · 0.80
SetResultMethod · 0.80
OnCallStartedMethod · 0.65
OnCallFinishedMethod · 0.65
ReleaseMethod · 0.45

Tested by

no test coverage detected