Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bad file descriptor error at file:close() #3

Open
alexandrlevashov opened this issue Apr 10, 2019 · 3 comments
Open

Bad file descriptor error at file:close() #3

alexandrlevashov opened this issue Apr 10, 2019 · 3 comments

Comments

@alexandrlevashov
Copy link

alexandrlevashov commented Apr 10, 2019

Hi!

The following error occurs very often:
close() failed (9: Bad file descriptor)

This is produced at the end of the complex PUT workflow (described below) after main data already written and re-sended and a small piece of data should be placed in a separate file (it is point 5 of the PUT workflow). The exact code:

local io = require "ngx.io"

local file,err = io.open( filename, "w+" )
if err then return nil, err end

for name, value in pairs(headers) do
  if value ~= nil then
    local res,err = file:write(name:lower()..": "..value.."\n")
    if not res then return nil,err end
  end
end

return file:close()

The last file:close is the problem that returns the error "close() failed (9: Bad file descriptor)" .

Requesting model is the following. There are many PUT/HEAD/GET/DELETE requests at 1Gbps speed. Most PUT requests write file data locally and send it to other service using this library:
https://github.com/ledgetech/lua-resty-http

so chunks are read, written to local file and forwarded to other service.

GET requests read file and "print" data to output.

Chunk size is 65536 bytes.

PUT is most interested since http request to forward data is sent to local "proxy_pass" location that passes query to an external service.

So PUT sequence is:

  1. Get PUT request
  2. Open local file to write
  3. Connect to local (127.0.0.1:80/local_proxy_pass) location with proxy_pass using resty.http library
    3.1. for body reader an iterator function is passed where
    3.1.1. receive a chunk data with socket:receive(current_chunk_size)
    3.1.2. write data to local file
    3.1.3. return data
  4. When all data is read - close the file
  5. At very end of the request create and write a small file.

Input and external requests are secured with https.

@tokers
Copy link
Owner

tokers commented Apr 10, 2019

Hello!
OK, I will try to reproduce it firstly :)

@tokers
Copy link
Owner

tokers commented Apr 13, 2019

@alexandrlevashov
Have you observed any error log messages in your error.log?

@alexandrlevashov
Copy link
Author

alexandrlevashov commented Jul 12, 2020

Hello!

Sorry for over a year of silence.

There is no any additional errors except "Bad file descriptor".

After some new play with this issue, I found that this error occurs if I return file:close() directly from a function that opened a file.

For instance, this will produce some times the error at close():

function test() 
   local file, err = ngx_io.open("name", "w+")
   file:write("something to write")
   return file:close()
end

But the following will not produce the error:

function test() 
   local file, err = ngx_io.open("name", "w+")
   file:write("something to write")
   local res, err = file:close()
   return res, err
end

I still cannot reproduce it on demand from a test, but on high loaded server it is reproduced all the time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants