Coder Social home page Coder Social logo

add support for async.callback api about puma HOT 12 CLOSED

puma avatar puma commented on April 28, 2024
add support for async.callback api

from puma.

Comments (12)

rkh avatar rkh commented on April 28, 2024 1

What needs to be done to fully support the async API currently used by Thin, Rainbows!, Zbatery and Ebb:

  • wrap the app.call in a catch(:async) and treat it like status -1 (status -1 is essentially not usable, as Rack::Lint and other middleware will go berserk if they see it)
  • add env['async.callback'] which is a proc (or anything responding to call) for setting status code, headers, and body object
  • if the body object responds to callback and errback, don't close the connection after being done with the each call, instead call those methods with a block for closing the connection (i.e. body.callback { connection.close })
  • add env['async.close'] which responds to callback and errback. these methods store the blocks passed to it and trigger them if the connection is being closed (for instance by the client)
  • make sure the block passed to each can be called at any later point in time (before the connection has been closed) and will still send out the message to the client

An example Rack application using this protocol could look like this:

class Body
  def <<(msg)
    @each[msg] if @each
  end

  # close is reserved by the rack spec
  def close!
    @callback.call
  end

  def each(&block)
    @each = block
  end

  def callback(&block)
    @callback = block
  end

  alias errback callback
end

require 'sinatra'
streams = []

get '/' do
  stream = Body.new
  streams << stream
  env['async.close'].callback { streams.delete(stream) }
  stream
end

post '/' do
  streams.each { |stream| stream << params[:message] }
  [201, 'message send']
end

delete '/' do
  streams.each(&:close!)
  streams.clear
  'closed all connections'
end

This is just for demo reasons (i.e. I didn't run the code, it's obviously not thread-safe, etc). A proper implementation can be found in this example or within Sinatra (used for instance in a real time chat example).

I'm super swamped with work at the moment, but might be able to implement this (if no one else takes care of it) once we've released pre-tested Pull Requests for Travis CI.

from puma.

Nerian avatar Nerian commented on April 28, 2024 1

@evanphx Is there an example somewhere I can read about how to do async calls with puma?

from puma.

jimsynz avatar jimsynz commented on April 28, 2024

Keen to help with this.

from puma.

evanphx avatar evanphx commented on April 28, 2024

Part of this has been added by having puma understand the async response pattern to abandon handling of the socket.

from puma.

evanphx avatar evanphx commented on April 28, 2024

@rkh So, I looked at what how sinatra used the API and was put off by this: https://github.com/sinatra/sinatra/blob/f2bc346a3c56d61d744fb4419623befc47a7bc65/lib/sinatra/base.rb#L342

Doesn't that imply that sinatra assumes that if async.callback is set, then EventMachine is being used?

from puma.

rkh avatar rkh commented on April 28, 2024

Yeah, I can "fix" that. But otherwise streaming doesn't work on EventMachine based servers (which all the servers supporting async.callback are atm).

from puma.

iostat avatar iostat commented on April 28, 2024

Hi! Has anybody been working on this? If not, I might be able to help out sometime in the future.

from puma.

evanphx avatar evanphx commented on April 28, 2024

None is currently working on it, no.

Evan Phoenix // [email protected]

On Wednesday, April 10, 2013 at 7:18 AM, Ilya Ostrovskiy wrote:

Hi! Has anybody been working on this? If not, I might be able to help out sometime in the future.


Reply to this email directly or view it on GitHub (#3 (comment)).

from puma.

maccman avatar maccman commented on April 28, 2024

Would definitely love to see this.

from puma.

lucaong avatar lucaong commented on April 28, 2024

Was this closed because the feature was discarded, or because a better strategy to support async request handling is/will be available?

from puma.

evanphx avatar evanphx commented on April 28, 2024

Mostly because Puma already has support and Sinatra needs to figure out how to manage async.callback when EventMachine isn't used.

from puma.

axos88 avatar axos88 commented on April 28, 2024

I'd love to see an example on usage as well

from puma.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.