@@ -14,6 +14,7 @@ import (
1414
1515 "github.com/wundergraph/astjson"
1616 "github.com/wundergraph/graphql-go-tools/v2/pkg/engine/resolve"
17+ "go.uber.org/zap"
1718)
1819
1920const (
@@ -37,6 +38,7 @@ type withFlushWriter interface {
3738type SubscriptionResponseWriterOptions struct {
3839 ApolloSubscriptionMultipartPrintBoundary bool
3940 SSEWriteTimeout time.Duration
41+ Logger * zap.Logger
4042}
4143
4244type HttpFlushWriter struct {
@@ -51,6 +53,7 @@ type HttpFlushWriter struct {
5153 buf * bytes.Buffer
5254 firstMessage bool
5355 sseWriteTimeout time.Duration
56+ logger * zap.Logger
5457 // apolloSubscriptionMultipartPrintBoundary if set to true will send the multipart boundary at the end of the message to allow
5558 // misbehaving client (like apollo client) to read the message just sent before the next one or the heartbeat
5659 apolloSubscriptionMultipartPrintBoundary bool
@@ -189,16 +192,25 @@ func (f *HttpFlushWriter) Flush() (err error) {
189192
190193func (f * HttpFlushWriter ) writeAndFlushSSE (write func () error ) (err error ) {
191194 if f .sseWriteTimeout > 0 {
192- if err := f .responseControl .SetWriteDeadline (time .Now ().Add (f .sseWriteTimeout )); err != nil {
193- // Failing closed prevents a response writer without deadline support from
194- // reintroducing an unbounded shared-trigger stall.
195- return fmt .Errorf ("set SSE write deadline: %w" , err )
196- }
197- defer func () {
198- if clearErr := f .responseControl .SetWriteDeadline (time.Time {}); clearErr != nil {
199- err = errors .Join (err , fmt .Errorf ("clear SSE write deadline: %w" , clearErr ))
195+ if deadlineErr := f .responseControl .SetWriteDeadline (time .Now ().Add (f .sseWriteTimeout )); deadlineErr != nil {
196+ if ! errors .Is (deadlineErr , http .ErrNotSupported ) {
197+ return fmt .Errorf ("set SSE write deadline: %w" , deadlineErr )
198+ }
199+
200+ f .sseWriteTimeout = 0
201+ if f .logger != nil {
202+ f .logger .Warn (
203+ "SSE write timeout disabled because response writer does not support write deadlines" ,
204+ zap .Error (deadlineErr ),
205+ )
200206 }
201- }()
207+ } else {
208+ defer func () {
209+ if clearErr := f .responseControl .SetWriteDeadline (time.Time {}); clearErr != nil {
210+ err = errors .Join (err , fmt .Errorf ("clear SSE write deadline: %w" , clearErr ))
211+ }
212+ }()
213+ }
202214 }
203215
204216 if err := write (); err != nil {
@@ -231,6 +243,7 @@ func GetSubscriptionResponseWriter(ctx *resolve.Context, r *http.Request, w http
231243 buf : & bytes.Buffer {},
232244 firstMessage : true ,
233245 sseWriteTimeout : opts .SSEWriteTimeout ,
246+ logger : opts .Logger ,
234247 apolloSubscriptionMultipartPrintBoundary : opts .ApolloSubscriptionMultipartPrintBoundary ,
235248 }
236249
0 commit comments