Search code examples
ruby-on-railsrubynginxunicorn

send_data can't send large file - after 30 seconds, kills the request


I have a rails app on nginx/unicorn with this line of code:

    format.csv { send_data Test_Model.to_csv, stream: 'true', filename: "assets-#{DateTime.now.strftime('%Y%m%d%H%M%S')}.csv" }

The problem is - the file that is generated by my to_csv method is on the large side, 2.4 MB - it also takes a long time for my app to produce it via sql queries... and that longness is not something I can change.

So then, 90% of the time I invoke my functionality I get:

what I always get

Maybe 1 in 10 times, I do get the file to come out. But the point is... it would be of tremendous use to generate this and send it via send_data.

I know there is talk of send_file. However, send_file expects a filepath of an already-generated file. In this case, I want to dynamically create this data with send_data. I really want to push this file out of send_data if at all possible - even if it takes my app >30+ seconds to produce the file.

UPDATE

So my app sort of "times out" and bites the dust at 30 seconds. Sounds an awful lot like a timeout setting somewhere. I wonder - would send_data timeout be set in unicorn conf, or in generic rails conf? How can I manipulate the timeout associated with send_data?


Solution

  • Ngnix will terminate connections that take too long. Long connections mean your application potentially isn't able to serve other requests. Besides re-writing your request to use ActiveJob, or some other background generation, you could check the nginx confirmation parameter keepalive_timeout.