7
7
"strconv"
8
8
"strings"
9
9
"sync"
10
- "sync/atomic"
11
10
"time"
12
11
13
12
"github.com/gptscript-ai/gptscript/pkg/runner"
@@ -23,8 +22,10 @@ type Event struct {
23
22
}
24
23
25
24
type fileFactory struct {
25
+ fileName string
26
26
file * os.File
27
- runningCount atomic.Int32
27
+ lock sync.Mutex
28
+ runningCount int
28
29
}
29
30
30
31
// NewFileFactory creates a new monitor factory that writes events to the location specified.
@@ -33,33 +34,23 @@ type fileFactory struct {
33
34
// 2. a file name
34
35
// 3. a named pipe in the form "\\.\pipe\my-pipe"
35
36
func NewFileFactory (loc string ) (runner.MonitorFactory , error ) {
36
- var (
37
- file * os.File
38
- err error
39
- )
40
-
41
- if strings .HasPrefix (loc , "fd://" ) {
42
- fd , err := strconv .Atoi (strings .TrimPrefix (loc , "fd://" ))
43
- if err != nil {
44
- return nil , err
45
- }
46
-
47
- file = os .NewFile (uintptr (fd ), "events" )
48
- } else {
49
- file , err = os .OpenFile (loc , os .O_WRONLY | os .O_CREATE , 0644 )
50
- if err != nil {
51
- return nil , err
52
- }
53
- }
54
-
55
37
return & fileFactory {
56
- file : file ,
57
- runningCount : atomic.Int32 {},
38
+ fileName : loc ,
58
39
}, nil
59
40
}
60
41
61
42
func (s * fileFactory ) Start (_ context.Context , prg * types.Program , env []string , input string ) (runner.Monitor , error ) {
62
- s .runningCount .Add (1 )
43
+ s .lock .Lock ()
44
+ s .runningCount ++
45
+ if s .runningCount == 1 {
46
+ if err := s .openFile (); err != nil {
47
+ s .runningCount --
48
+ s .lock .Unlock ()
49
+ return nil , err
50
+ }
51
+ }
52
+ s .lock .Unlock ()
53
+
63
54
fd := & fd {
64
55
prj : prg ,
65
56
env : env ,
@@ -80,13 +71,40 @@ func (s *fileFactory) Start(_ context.Context, prg *types.Program, env []string,
80
71
}
81
72
82
73
func (s * fileFactory ) close () {
83
- if count := s .runningCount .Add (- 1 ); count == 0 {
74
+ s .lock .Lock ()
75
+ defer s .lock .Unlock ()
76
+
77
+ s .runningCount --
78
+ if s .runningCount == 0 {
84
79
if err := s .file .Close (); err != nil {
85
80
log .Errorf ("error closing monitor file: %v" , err )
86
81
}
87
82
}
88
83
}
89
84
85
+ func (s * fileFactory ) openFile () error {
86
+ var (
87
+ err error
88
+ file * os.File
89
+ )
90
+ if strings .HasPrefix (s .fileName , "fd://" ) {
91
+ fd , err := strconv .Atoi (strings .TrimPrefix (s .fileName , "fd://" ))
92
+ if err != nil {
93
+ return err
94
+ }
95
+
96
+ file = os .NewFile (uintptr (fd ), "events" )
97
+ } else {
98
+ file , err = os .OpenFile (s .fileName , os .O_APPEND | os .O_WRONLY | os .O_CREATE , 0644 )
99
+ if err != nil {
100
+ return err
101
+ }
102
+ }
103
+
104
+ s .file = file
105
+ return nil
106
+ }
107
+
90
108
type fd struct {
91
109
prj * types.Program
92
110
env []string
0 commit comments