はじめに
普段、業務でGo + GQLGenを使ってアプリケーションを構築しているものです。
https://gqlgen.com/
その中で3MBぐらいのファイルをアップロードした時にエラーが出る事象が発生しました。その時の解決まで至る過程を記します。
不具合発生
ある日、ビジネス側から不具合の報告が
「ファイル(画像)を50枚ぐらい一度にアップロードしようとするとエラーになる」
すぐにローカルで確認しましたが、再現。コンソールを見ると、
net::ERR_CONNECTION_RESET
が出ていました。
調査
エラーメッセージが汎用的なものだったので、全く原因がわからず非常に苦戦しました。
ログを見てみると、バックエンドにリクエスト自体は来ているみたいなので、バックエンドのどこかで落ちていると仮定して、調べてみました。
解決法
どうやらGQLGenではデフォルトでファイルの最大が決められているらしく、それを変えたら正常に動くようになりました。
当初、このように初期化していました。
conf := graph.Config{}
srv := handler.NewDefaultServer(graph.NewExecutableSchema(conf))
ソースコードをみると、このNewDefaultServer
で、色々とデフォルトの設定がされているようでしたので、その設定を取っ払って、自分で設定し直せばいけるのではと踏みました。
まず、NewDefaultServer
を以下のように変更
srv := handler.New(graph.NewExecutableSchema(conf))
そして、AddTransport
を追加
srv.AddTransport(transport.MultipartForm{
MaxUploadSize: 3 << 30, // 3gb
MaxMemory: 3 << 30, // 3gb
})
そして、これだけだとNewDefaultServer
でやっていたデフォルトの設定が取っ払われてしまうので、自分で設定しました。
srv := handler.New(graph.NewExecutableSchema(conf))
srv.AddTransport(transport.MultipartForm{
MaxUploadSize: 3 << 30, // 3gb
MaxMemory: 3 << 30, // 3gb
})
srv.AddTransport(transport.Websocket{
KeepAlivePingInterval: 10 * time.Second,
})
srv.AddTransport(transport.Options{})
srv.AddTransport(transport.GET{})
srv.AddTransport(transport.POST{})
srv.SetQueryCache(lru.New(1000))
srv.Use(extension.Introspection{})
srv.Use(extension.AutomaticPersistedQuery{Cache: lru.New(100)})
以上で3GBまで耐えられるようになりました。
おわりに
StackOverflowはやはり神。
かなりニッチな内容ですが、同じようにエラーに苦しんでいる人の助けになれば幸いです。