Skip to content

Commit d96c83e

Browse files
authored
enhance: stop trigger when tool reference not updated (#1867)
enhance: stop trigger when tool reference not updated The existing logic would update the tool reference every hour, even when there were no updates to the tool reference because we would track the last checked time on the object itself. This would cause a large storm of object processing because runs, threads, agents, workflows, and workflow executions would all be triggered in this case. This change ensures that tool references only trigger related objects when the tool reference itself changes. In addition to the changes that are explicitly added here, changes to nah were also required. This change bumps that dependency as well. Signed-off-by: Donnie Adams <[email protected]>
1 parent e0c8b86 commit d96c83e

File tree

7 files changed

+46
-27
lines changed

7 files changed

+46
-27
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ require (
2323
github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de
2424
github.com/mhale/smtpd v0.8.3
2525
github.com/obot-platform/kinm v0.0.0-20250116162656-270198b40c6d
26-
github.com/obot-platform/nah v0.0.0-20250226155418-3825a76fcc28
26+
github.com/obot-platform/nah v0.0.0-20250227230402-c8ac47e1add7
2727
github.com/obot-platform/namegenerator v0.0.0-20241217121223-fc58bdb7dca2
2828
github.com/obot-platform/obot/apiclient v0.0.0-00010101000000-000000000000
2929
github.com/obot-platform/obot/logger v0.0.0-20241217130503-4004a5c69f32

go.sum

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -460,8 +460,8 @@ github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349 h1:t05Ww3DxZutOqbMN+
460460
github.com/oasdiff/yaml3 v0.0.0-20241210130736-a94c01f36349/go.mod h1:y5+oSEHCPT/DGrS++Wc/479ERge0zTFxaF8PbGKcg2o=
461461
github.com/obot-platform/kinm v0.0.0-20250116162656-270198b40c6d h1:GzMvRkssr4jAa2YvQiv9eXhjuNpaZVab3GajE7+cQ3s=
462462
github.com/obot-platform/kinm v0.0.0-20250116162656-270198b40c6d/go.mod h1:RzrH0geIlbiTHDGZ8bpCk5k1hwdU9uu3l4zJn9n0pZU=
463-
github.com/obot-platform/nah v0.0.0-20250226155418-3825a76fcc28 h1:NrUAP4e9UHjEHCItaHt9ZDmuWqy0Wba7vFaAU6MGtZE=
464-
github.com/obot-platform/nah v0.0.0-20250226155418-3825a76fcc28/go.mod h1:KG1jLO9FeYvCPGI0iDqe5oqDqOFLd3/dt/iwuMianmI=
463+
github.com/obot-platform/nah v0.0.0-20250227230402-c8ac47e1add7 h1:IuG8TZqqxz5P1ZHj2aCxEEn6LGgHXeUVhkG/ELh2a8U=
464+
github.com/obot-platform/nah v0.0.0-20250227230402-c8ac47e1add7/go.mod h1:KG1jLO9FeYvCPGI0iDqe5oqDqOFLd3/dt/iwuMianmI=
465465
github.com/obot-platform/namegenerator v0.0.0-20241217121223-fc58bdb7dca2 h1:jiyBM/TYxU6UNVS9ff8Y8n55DOKDYohKkIZjfHpjfTY=
466466
github.com/obot-platform/namegenerator v0.0.0-20241217121223-fc58bdb7dca2/go.mod h1:isbKX6EfvvG/ojjFB2ZLyz27+2xoG3yRmpTSE+ytWEs=
467467
github.com/olekukonko/tablewriter v0.0.6-0.20230925090304-df64c4bbad77 h1:3bMMZ1f+GPXFQ1uNaYbO/uECWvSfqEA+ZEXn1rFAT88=

pkg/controller/handlers/toolreference/toolreference.go

Lines changed: 42 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"regexp"
1111
"strings"
12+
"sync"
1213
"time"
1314

1415
"github.com/gptscript-ai/go-gptscript"
@@ -30,9 +31,12 @@ import (
3031
"sigs.k8s.io/yaml"
3132
)
3233

33-
var log = logger.Package()
34+
var (
35+
log = logger.Package()
36+
jsonErrRegexp = regexp.MustCompile(`\{.*"error":.*}`)
37+
)
3438

35-
var jsonErrRegexp = regexp.MustCompile(`\{.*"error":.*}`)
39+
const toolRecheckPeriod = time.Hour
3640

3741
type indexEntry struct {
3842
Reference string `json:"reference,omitempty"`
@@ -49,10 +53,12 @@ type index struct {
4953
}
5054

5155
type Handler struct {
52-
gptClient *gptscript.GPTScript
53-
dispatcher *dispatcher.Dispatcher
54-
supportDocker bool
55-
registryURLs []string
56+
gptClient *gptscript.GPTScript
57+
dispatcher *dispatcher.Dispatcher
58+
supportDocker bool
59+
registryURLs []string
60+
lastChecksLock *sync.RWMutex
61+
lastChecks map[string]time.Time
5662
}
5763

5864
func New(gptClient *gptscript.GPTScript,
@@ -61,10 +67,12 @@ func New(gptClient *gptscript.GPTScript,
6167
supportDocker bool,
6268
) *Handler {
6369
return &Handler{
64-
gptClient: gptClient,
65-
dispatcher: dispatcher,
66-
registryURLs: registryURLs,
67-
supportDocker: supportDocker,
70+
gptClient: gptClient,
71+
dispatcher: dispatcher,
72+
registryURLs: registryURLs,
73+
supportDocker: supportDocker,
74+
lastChecks: make(map[string]time.Time),
75+
lastChecksLock: new(sync.RWMutex),
6876
}
6977
}
7078

@@ -167,22 +175,41 @@ func (h *Handler) PollRegistries(ctx context.Context, c client.Client) {
167175

168176
func (h *Handler) Populate(req router.Request, resp router.Response) error {
169177
toolRef := req.Object.(*v1.ToolReference)
170-
if retry := time.Until(toolRef.Status.LastReferenceCheck.Time); toolRef.Generation == toolRef.Status.ObservedGeneration && retry > -time.Hour {
171-
resp.RetryAfter(time.Hour + retry)
178+
h.lastChecksLock.RLock()
179+
lastCheck, ok := h.lastChecks[toolRef.Name]
180+
h.lastChecksLock.RUnlock()
181+
if !ok {
182+
// Tracking these times this way is not HA. However, we don't run this in an HA way right now.
183+
// When we are ready to start exploring HA as an option, this will have to be changed.
184+
lastCheck = time.Now()
185+
h.lastChecksLock.Lock()
186+
h.lastChecks[toolRef.Name] = time.Now()
187+
h.lastChecksLock.Unlock()
188+
}
189+
190+
var retry time.Duration
191+
defer func() {
192+
resp.RetryAfter(toolRecheckPeriod + retry)
193+
}()
194+
195+
if retry = time.Until(lastCheck); ok && toolRef.Generation == toolRef.Status.ObservedGeneration && retry > -toolRecheckPeriod {
172196
return nil
173197
}
198+
retry = 0
174199

175200
// Reset status
176-
lastCheck := toolRef.Status.LastReferenceCheck
177-
toolRef.Status.LastReferenceCheck = metav1.Now()
178201
toolRef.Status.ObservedGeneration = toolRef.Generation
179202
toolRef.Status.Reference = toolRef.Spec.Reference
180203
toolRef.Status.Commit = ""
181204
toolRef.Status.Tool = nil
182205
toolRef.Status.Error = ""
183206

207+
h.lastChecksLock.Lock()
208+
h.lastChecks[toolRef.Name] = time.Now()
209+
h.lastChecksLock.Unlock()
210+
184211
prg, err := h.gptClient.LoadFile(req.Ctx, toolRef.Spec.Reference, gptscript.LoadOptions{
185-
DisableCache: toolRef.Spec.ForceRefresh.After(lastCheck.Time),
212+
DisableCache: toolRef.Spec.ForceRefresh.After(lastCheck),
186213
})
187214
if err != nil {
188215
toolRef.Status.Error = err.Error()

pkg/controller/handlers/workflowstep/workflowstep.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,6 @@ func NewStep(namespace, workflowExecutionName, afterStepName string, generation
229229
stepName = strings.ReplaceAll(stepName, "--", "-")
230230

231231
return &v1.WorkflowStep{
232-
TypeMeta: metav1.TypeMeta{},
233232
ObjectMeta: metav1.ObjectMeta{
234233
Name: stepName,
235234
Namespace: namespace,

pkg/storage/apis/obot.obot.ai/v1/toolreference.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ type ToolReferenceStatus struct {
8080
Reference string `json:"reference,omitempty"`
8181
Commit string `json:"commit,omitempty"`
8282
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
83-
LastReferenceCheck metav1.Time `json:"lastReferenceCheck,omitempty"`
8483
Tool *ToolShortDescription `json:"tool,omitempty"`
8584
Error string `json:"error,omitempty"`
8685
}

pkg/storage/apis/obot.obot.ai/v1/zz_generated.deepcopy.go

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/storage/openapi/generated/openapi_generated.go

Lines changed: 1 addition & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)