cat / 012
clone

a spreadsheet for the terminal: lotus 1-2-3 looks, google sheets keys and formulas, one go binary

main
012 / internal / headless / jev.go
jev.go 1.7K
1package headless23import (4 "context"5 "sync"6 "time"78 "src.rest/cat/012/internal/jev"9 "src.rest/cat/012/internal/sheet"10)1112// jevParallel is how many questions are asked at once, as on the13// screen.14const jevParallel = 81516// maxJEVRounds bounds the rounds of questions: answers can make new17// questions (a JEV function reading another's answer), and each round18// asks those the last one made.19const maxJEVRounds = 162021// AnswerJEV answers w's JEV functions with client, asking what the22// workbook's formulas ask, a few questions at a time, until none is23// waiting, each within timeout. It returns how many were asked.24func AnswerJEV(ctx context.Context, w *sheet.Workbook, client jev.Client, timeout time.Duration) int {25 return AnswerJEVFrom(ctx, w, client, jev.NewCache(), timeout)26}2728// AnswerJEVFrom is AnswerJEV with the answers kept in cache, which a29// caller opening the workbook again and again (012 mcp) keeps, so each30// question is asked once.31func AnswerJEVFrom(ctx context.Context, w *sheet.Workbook, client jev.Client, cache *jev.Cache, timeout time.Duration) int {32 w.SetRemote(cache)33 asked := 034 for range maxJEVRounds {35 calls := cache.Take(1 << 30)36 if len(calls) == 0 {37 break38 }39 asked += len(calls)40 answers := make([]sheet.RemoteAnswer, len(calls))41 var wg sync.WaitGroup42 sem := make(chan struct{}, jevParallel)43 for i, c := range calls {44 wg.Add(1)45 sem <- struct{}{}46 go func() {47 defer func() { <-sem; wg.Done() }()48 ctx, cancel := context.WithTimeout(ctx, timeout)49 defer cancel()50 answers[i] = jev.Ask(ctx, client, c)51 }()52 }53 wg.Wait()54 for i, c := range calls {55 cache.Store(c, answers[i])56 }57 w.RecalcAnswered(calls)58 }59 return asked60}