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

Transfer-Encoding header lost with EventSource #47

Open
zhongsheng opened this issue Oct 25, 2024 · 4 comments
Open

Transfer-Encoding header lost with EventSource #47

zhongsheng opened this issue Oct 25, 2024 · 4 comments

Comments

@zhongsheng
Copy link

bin/rails s works

image

But with thruster bin/thrust bin/rails s, transfer-encoding is missing. This cause a problem, messages returned as a whole text.

Rails 8.0.0.beta1
ruby 3.3.1 (2024-04-23 revision c56cd86388) [arm64-darwin23]

class SseController < ApplicationController
  include ActionController::Live
  def index
  end

  def events
    response.headers['Content-Type'] = 'text/event-stream'

    sse = SSE.new(response.stream, event: "message")

    5.times {
      sse.write({ message: "hello world" })
      sleep 1
    }
  ensure
    response.stream.close
  end

end
@zhongsheng zhongsheng changed the title transfer-encoding header lost with EventSource Transfer-Encoding header lost with EventSource Oct 25, 2024
@3v0k4
Copy link
Contributor

3v0k4 commented Nov 11, 2024

I cannot reproduce with:

  • rails 8.0.0
  • thruster 0.1.8
  • ruby 3.3.5

I see Transfer-Encoding: chunked with and without thruster.

Could you please double check? 🙏

@zhongsheng
Copy link
Author

zhongsheng commented Nov 11, 2024

I cannot reproduce with:

  • rails 8.0.0
  • thruster 0.1.8
  • ruby 3.3.5

I see Transfer-Encoding: chunked with and without thruster.

Could you please double check? 🙏

rails new myapp
cd myapp
rails g controller sse index events
# put some code in events method
HTTP_PORT=8088 bin/thrust rails server

Then access http://localhost:8088/sse/events

@3v0k4
Copy link
Contributor

3v0k4 commented Nov 12, 2024

My bad, I was curling the wrong port 🤦

I think there's some buffering involved with the GzipHandler.

If you change your Rails controller code as follows then it should work:

class SseController < ApplicationController
  include ActionController::Live
  def index
  end

  def events
    response.headers['Content-Type'] = 'text/event-stream'

    sse = SSE.new(response.stream, event: "message")

    5.times {
-    sse.write({ message: "hello world" })
+    sse.write({ message: "hello world" * 1000 })
      sleep 1
    }
  ensure
    response.stream.close
  end
end

@mjason
Copy link

mjason commented Dec 12, 2024

I also encountered this problem, debugged for a long time, initially thought it was a kamal proxy issue, because there is a issues over there. Then I switched to caddy and it still occurred, so I'm sure it's not this problem.

Then I debugged rack and found no anomalies, later I reviewed the dockerfile code and found this part, and discovered that someone else had the same issue as me. I disabled thruster and found that my program was working normally.

class ChatsController < ApplicationController
  include ActionController::Live

  def index
    @prompts = Prompt.all
    @default_prompt = @prompts.first
    @fields = @default_prompt&.fields
  end


  def create
    response.headers["Content-Type"] = "text/event-stream"
    response.headers["Last-Modified"] = Time.now.httpdate

    sse = SSE.new(response.stream, retry: 300, event: "chat-output")

    prompt = Prompt.find(params[:prompt_id])

    prompt.chat(fields: params.require(:fields).permit!) do |message, html_content, accumulated, done|
      if done
        [
          turbo_stream.update("chat_output", html_content),
          turbo_stream.update("submit_button", partial: "shared/normal_button"),
          turbo_stream.update("chat-output-bottom", partial: "chats/copy", locals: { markdown_content: accumulated })
        ].join("\n").then { sse.write({ template: _1 }) }
      else
        turbo_stream.append("chat_output", message.gsub("\n", "<br>")).then {
          sse.write({ template: _1 })
        }
      end

      logger.info "message: #{message}"
    end
  ensure
    sse.close
  end
end

Dockerfile:

EXPOSE 80
# CMD ["./bin/thrust", "./bin/rails", "server"]
CMD ["bundle", "exec", "falcon", "host"]

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

3 participants