Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

add closed? method on Stream object to inspect the object's open/close state #535

Merged
merged 1 commit into from

5 participants

@yeban

So I have a list of streaming connections accumulated in a connections variable.

get '/' do
  stream(:keep_open) { |out| connections << out }
end

Over time the list of connections can get huge, and I would like to trim the dead ones:

connections.select(&:closed?).each(&:close)

Inspecting @closed on a stream object doesn't seem like the best way to go about it.

@yeban yeban add closed? method on Stream object to inspect the object's open/clos…
…e state

Signed-off-by: Anurag Priyam <anurag08priyam@gmail.com>
cc8502f
@rkh
Owner

sinatra-contrib adds closed?. Not sure if and what we should move to sinatra proper.

@travisbot

This pull request passes (merged cc8502f into 8adecc0).

@yeban

To me, Stream#closed? seems too basic a functionality to be residing in a separate gem. In fact, I was so convinced it is there that I used it in my app without even consulting the docs or the source, only to get a NoMethodError :P.

@pirj

sinatra-contrib adds unexpected behavior :

sinatra-contrib-1.3.1/lib/sinatra/streaming.rb:119:in `<<': not opened for writing (IOError)

This is not the case if sinatra/streaming is not used.
Besides that it works like a charm.

@rkh rkh referenced this pull request in sinatra/sinatra-contrib
Closed

rethink sinatra-streaming, maybe #60

@troyk

I was cruising the code to figure out how to deal with closed connections and googled a bit to see what others were doing and landed here. Not saying "closed?" isn't needed, but the use case listed above doesn't make any sense based on the code:

connections.select(&:closed?).each(&:close)

doesn't do anything but return

def close
  return if @closed
  @closed = true
  @scheduler.schedule { @callbacks.each { |c| c.call }}
end

It seems the proper thing to do is to set a callback to delete "out" from connections which will be triggered by the close method, but I'm unfamiliar with how long the scheduler will take to invoke the callbacks and if another event (or thread) is iterating the connections to send data it probably makes sense to do something like below, as Stream::<< doesn't check if the connection is closed. I'm assuming writing to a closed connection is going to throw something somewhere:

connections.each do |out|
  out << some_data unless out.closed?
end

And if that makes sense, adding closed? seems like a great idea.

@yeban

@troyk writes:

Not saying "closed?" isn't needed, but the use case listed above doesn't make any sense based on the code:

connections.select(&:closed?).each(&:close)

My bad. I have no idea what I was thinking when I wrote that two months ago. I probably wanted to say:

connections.reject!(&:closed?)
@rkh rkh merged commit d2e8563 into sinatra:master
@rkh
Owner

@yeban Could you add some docs?

@yeban

@rkh Sure. Over the weekend.

@yeban yeban referenced this pull request
Merged

Update stream documentation #599

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jun 24, 2012
  1. @yeban

    add closed? method on Stream object to inspect the object's open/clos…

    yeban authored
    …e state
    
    Signed-off-by: Anurag Priyam <anurag08priyam@gmail.com>
This page is out of date. Refresh to see the latest.
Showing with 11 additions and 0 deletions.
  1. +4 −0 lib/sinatra/base.rb
  2. +7 −0 test/streaming_test.rb
View
4 lib/sinatra/base.rb
@@ -332,6 +332,10 @@ def callback(&block)
end
alias errback callback
+
+ def closed?
+ @closed
+ end
end
# Allows to start sending data to the client even though later parts of
View
7 test/streaming_test.rb
@@ -139,4 +139,11 @@ def close.errback; end
get '/'
assert ran
end
+
+ it 'has a public interface to inspect its open/closed state' do
+ stream = Stream.new(Stream) { |out| out << :foo }
+ assert !stream.closed?
+ stream.close
+ assert stream.closed?
+ end
end
Something went wrong with that request. Please try again.