@@ -78,7 +78,24 @@ func (c *Client) GetLogs(ctx context.Context, workflowName string) (responses.Ge
78
78
}
79
79
80
80
// StreamLogs streams the logs of a workflow starting after loggedBytes.
81
- func (c * Client ) StreamLogs (ctx context.Context , w io.Writer , workflowName string , skippedLogBytes int64 ) error {
81
+ func (c * Client ) StreamLogs (ctx context.Context , w io.Writer , workflowName string ) error {
82
+ var loggingCursorByte int64
83
+ // When we receive a stream error we continue and retry processing up to 5 times keeping track of the byte we were logging.
84
+ for i := 0 ; i < 5 ; i ++ {
85
+ err := c .streamLogsToWriterAtCursor (ctx , w , workflowName , & loggingCursorByte )
86
+ if err != nil {
87
+ if strings .Contains (err .Error (), "stream error: stream ID 1; INTERNAL_ERROR" ) {
88
+ time .Sleep (time .Second * 10 )
89
+ continue
90
+ }
91
+ return err
92
+ }
93
+ break
94
+ }
95
+ return nil
96
+ }
97
+
98
+ func (c * Client ) streamLogsToWriterAtCursor (ctx context.Context , w io.Writer , workflowName string , loggingCursorByte * int64 ) error {
82
99
url := fmt .Sprintf ("%s/workflows/%s/logstream" , c .endpoint , workflowName )
83
100
84
101
req , err := http .NewRequestWithContext (ctx , http .MethodGet , url , nil )
@@ -96,26 +113,17 @@ func (c *Client) StreamLogs(ctx context.Context, w io.Writer, workflowName strin
96
113
return fmt .Errorf ("received unexpected status code: %d" , resp .StatusCode )
97
114
}
98
115
99
- // discard reader bytes already logged
100
- if _ , err := io .CopyN (ioutil .Discard , resp .Body , skippedLogBytes ); err != nil {
116
+ // discard reader bytes till cursor byte number
117
+ if _ , err := io .CopyN (ioutil .Discard , resp .Body , * loggingCursorByte ); err != nil {
101
118
return err
102
119
}
103
- skippedLogBytes , err = io .Copy (w , resp .Body )
120
+ writtenBytes , err : = io .Copy (w , resp .Body )
104
121
if err != nil {
105
- // retry call if we receive the stream error
106
- if strings .Contains (err .Error (), "INTERNAL_ERROR" ) {
107
- // temporary debug message
108
- _ , err := fmt .Fprintf (w , "internal error found while copying: '%v'\n " , err .Error ())
109
- if err != nil {
110
- return err
111
- }
112
- time .Sleep (time .Second * 10 )
113
- // Restart log streaming
114
- return c .StreamLogs (ctx , w , workflowName , skippedLogBytes )
115
- }
122
+ // retry call if we receive the stream error, increase the logging cursor byte by the amount we logged.
123
+ * loggingCursorByte += writtenBytes
124
+
116
125
return fmt .Errorf ("error reading response body. status code: %d, error: %w" , resp .StatusCode , err )
117
126
}
118
-
119
127
return nil
120
128
}
121
129
0 commit comments