Params[:file] attributes lost within Scheduler::Defer

AI-generated summary

A user, williamherry, is experiencing an issue with file uploads in a production environment on a CentOS host. The problem occurs when using the Scheduler::Defer block, where the file object loses some attributes. After debugging, williamherry found that the issue only occurs in the production environment on CentOS and not in the development environment on Ubuntu or Mac.

Further investigation revealed that the issue is related to the use of Unicorn and instance variables within the Scheduler::Defer block. williamherry found that when using Unicorn, the instance variables are lost, while switching to Thin resolves the issue.

Falco pointed out a duplicate issue, where a similar problem was reported with Tempfile being nil on deferred uploads. A possible solution can be found in the linked discussion, specifically in the 13th post.

I deployed a instance manually on a centos host, image upload does not work, after several hours of debug, I find file in Scheduler::Defer block lost some attribites, see debug code below

def create
    type = params.require(:type)
    file = params[:file] || params[:files].try(:first)
    url = params[:url]
    client_id = params[:client_id]
    synchronous = is_api? && params[:synchronous]

    if type == "avatar"
      if SiteSetting.sso_overrides_avatar || !SiteSetting.allow_uploaded_avatars
        return render json: failed_json, status: 422
      end
    end

    Rails.logger.error(file.tempfile.path)    # =>url

    if true #synchronous
      data = create_upload(type, file, url)
      render json: data.as_json
    else
      Scheduler::Defer.later("Create Upload") do
        Rails.logger.error(file.tempfile.path)  # => nil
        data = create_upload(type, file, url)
        MessageBus.publish("/uploads/#{type}", data.as_json, client_ids: [client_id])
      end
      render json: success_json
    end
  end

any one know what’s going on here?

Let me have a look and try to repro locally.

I think it’s not easy to repro, I run development environment on ubuntu and mac all works, this problem only occur on a centos host with production environment, and I am not using docker to install that

Yeah I can’t repro locally :frowning: I’m afraid you’re on your own here (CentOS + non-docker install).

I will post the info I get so far in case some one interested

Now I can narrow down the problem to: when use unicorn, object within Scheduler::Defer.later block will lost their instance_variables

a = "1"
a.instance_variable_set('@a', 1)
Rails.logger.error(a.instance_values)    # => {"a"=>1}
Scheduler::Defer.later("Create Upload") do
  Rails.logger.error(a.instance_values)  # => nothing
end

If I start a console by rails c and run above code, the result is as expected,

after switch to thin, image upload works

unicorn also not work on my development machine, which is ubuntu, but the result is a little bit different: the instance_varialbes remains, but the tempfile is show closed, call path on that return nil

{"tempfile"=>#<Tempfile: (closed)>, "original_filename"=>"favicons.png", "content_type"=>"image/png", "headers"=>"Content-Disposition: form-data; name=\"files[]\"; filename=\"favicons.png\"\r\nContent-Type: image/png\r\n"}

Duplicate:

https://meta.discourse.org/t/tempfile-is-nil-on-defered-uploads/34513?u=falco

https://meta.discourse.org/t/tempfile-is-nil-on-defered-uploads/34513/13?u=falco