Skip to content

Commit 90e52e4

Browse files
committed
enhance: synchronize file manipulation for built-ins
Use named locks to prevent concurrent writes to files manipulated by built-in tools. Locks are named after the file they protect. Lock acquisition has no guaranteed order. A more complex solution should be considered if a guaranteed order is desired; e.g. FIFO. Signed-off-by: Nick Hale <[email protected]>
1 parent a2daea4 commit 90e52e4

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.22.0
55
replace github.com/sashabaranov/go-openai => github.com/gptscript-ai/go-openai v0.0.0-20240206232711-45b6e096246a
66

77
require (
8+
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69
89
github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d
910
github.com/acorn-io/cmd v0.0.0-20240203032901-e9e631185ddb
1011
github.com/adrg/xdg v0.4.0

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69 h1:+tu3HOoMXB7RXEINRVIpxJCT+KdYiI7LAEAUrOw3dIU=
2+
github.com/BurntSushi/locker v0.0.0-20171006230638-a6e239ea1c69/go.mod h1:L1AbZdiDllfyYH5l5OkAaZtk7VkWe89bPJFmnDBNHxg=
13
github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd h1:Zbau2J6sEPl1H4gqnEx4/TI55eZncQR5cjfPOcG2lxE=
24
github.com/acorn-io/baaah v0.0.0-20240119160309-2a58ee757bbd/go.mod h1:13nTO3svO8zTD3j9E5c86tCtK5YrKsK5sxca4Lwkbc0=
35
github.com/acorn-io/broadcaster v0.0.0-20240105011354-bfadd4a7b45d h1:hfpNQkJ4I2b8+DbMr8m97gG67ku0uPsMzUfskVu3cHU=

pkg/builtin/builtin.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
"sort"
1616
"strings"
1717

18+
"github.com/BurntSushi/locker"
1819
"github.com/gptscript-ai/gptscript/pkg/types"
1920
"github.com/jaytaylor/html2text"
2021
)
@@ -242,6 +243,10 @@ func SysRead(ctx context.Context, env []string, input string) (string, error) {
242243
return "", err
243244
}
244245

246+
// Lock the file to prevent concurrent writes from other tool calls.
247+
locker.RLock(params.Filename)
248+
defer locker.RUnlock(params.Filename)
249+
245250
log.Debugf("Reading file %s", params.Filename)
246251
data, err := os.ReadFile(params.Filename)
247252
if err != nil {
@@ -260,6 +265,10 @@ func SysWrite(ctx context.Context, env []string, input string) (string, error) {
260265
return "", err
261266
}
262267

268+
// Lock the file to prevent concurrent writes from other tool calls.
269+
locker.Lock(params.Filename)
270+
defer locker.Unlock(params.Filename)
271+
263272
data := []byte(params.Content)
264273
msg := fmt.Sprintf("Wrote %d bytes to file %s", len(data), params.Filename)
265274
log.Debugf(msg)
@@ -276,6 +285,10 @@ func SysAppend(ctx context.Context, env []string, input string) (string, error)
276285
return "", err
277286
}
278287

288+
// Lock the file to prevent concurrent writes from other tool calls.
289+
locker.Lock(params.Filename)
290+
defer locker.Unlock(params.Filename)
291+
279292
f, err := os.OpenFile(params.Filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0644)
280293
if err != nil {
281294
return "", err
@@ -410,6 +423,10 @@ func SysRemove(ctx context.Context, env []string, input string) (string, error)
410423
return "", err
411424
}
412425

426+
// Lock the file to prevent concurrent writes from other tool calls.
427+
locker.Lock(params.Location)
428+
defer locker.Unlock(params.Location)
429+
413430
return fmt.Sprintf("Removed file: %s", params.Location), os.Remove(params.Location)
414431
}
415432

0 commit comments

Comments
 (0)