MCPcopy Create free account
hub / github.com/devld/go-drive / wrapVmRun

Function wrapVmRun

script/utils.go:347–388  ·  view source on GitHub ↗
(ctx context.Context, vm *VM, fn func() (otto.Value, error))

Source from the content-addressed store, hash-verified

345}
346
347func wrapVmRun(ctx context.Context, vm *VM, fn func() (otto.Value, error)) (value *Value, e error) {
348 defer func() {
349 if r := recover(); r != nil {
350 if ee, ok := r.(error); ok {
351 e = ee
352 return
353 }
354 e = fmt.Errorf("%s", r)
355 }
356
357 e = mapError(e)
358 }()
359
360 // Drain any interrupt left over from a previous run. The interrupt sender
361 // below can lose a race with fn() finishing, leaving a stale interrupt in
362 // the buffered channel. Since a VM is never run concurrently, it is safe to
363 // clear it here before running, preventing an unrelated request (this VM is
364 // reused from a pool) from being wrongly interrupted.
365 select {
366 case <-vm.o.Interrupt:
367 default:
368 }
369
370 finished := make(chan struct{})
371 go func() {
372 select {
373 case <-ctx.Done():
374 // If fn() already finished, prefer that branch so we don't leave a
375 // stale interrupt behind.
376 select {
377 case vm.o.Interrupt <- func() { panic(ctx.Err()) }:
378 case <-finished:
379 }
380 case <-finished:
381 }
382 }()
383 var ottoValue otto.Value
384 defer close(finished)
385 ottoValue, e = fn()
386 value = newValue(vm, ottoValue)
387 return
388}
389
390func mapError(e error) error {
391 if e == nil {

Callers 2

RunMethod · 0.85
CallMethod · 0.85

Calls 4

closeFunction · 0.85
newValueFunction · 0.85
mapErrorFunction · 0.70
ErrMethod · 0.65

Tested by

no test coverage detected