pubnub / ruby

PubNub Ruby-based APIs
Other
121 stars 89 forks source link

Synchronous publish? #2

Closed ghostganz closed 11 years ago

ghostganz commented 11 years ago

Hi,

I need a way to make a synchronous publish() call, so that I can use the PubNub response in my own HTTP response.

I've tried this:

    q = Queue.new
    pn.publish(channel: channel,
               message: message,
               callback: lambda { |response| q << response },
               origin: origin_hostname)
    p q.pop

but pop() immediately raises a deadlock error, since there's only one thread(!?). Any ideas what I can do to block until the publish has finished? This is with pubnub 3.3.0.7.

stephenlb commented 11 years ago

Hi Anders,

Good question regarding Ruby and sync publish. We are talking here at PubNub and may respond with more questions for you shortly.

Cheers! Stephen Blum http://twitter.com/PubNub https://github.com/pubnub/pubnub-api - GitHub www.pubnub.com

On Apr 5, 2013, at 7:50 AM, Anders Bengtsson notifications@github.com wrote:

Hi,

I need a way to make a synchronous publish() call, so that I can use the PubNub response in my own HTTP response.

I've tried this:

q = Queue.new
pn.publish(channel: channel,
           message: message,
           callback: lambda { |response| q << response },
           origin: origin_hostname)
p q.pop

but pop() immediately raises a deadlock error, since there's only one thread(!?). Any ideas what I can do to block until the publish has finished? This is with pubnub 3.3.0.7.

— Reply to this email directly or view it on GitHub.

geremyCohen commented 11 years ago

@ghostganz which app server are you using?

ghostganz commented 11 years ago

This is on Rails with Thin, with Ruby 1.9.3.

blazeroot commented 11 years ago

Try to use Thread.join with Thread.list to identify which threat you want to join, if you want to join all threads it looks like:

def join_all
  main     = Thread.main       # The main thread
  current  = Thread.current    # The current thread
  all      = Thread.list       # All threads still running
  # Now call join on each thread
  all.each{|t| t.join unless t == current or t == main }
end
ghostganz commented 11 years ago

When I run Thread.main, Thread.current and Thread.list directly after calling publish() they all give me the same one thread, so that doesn't help me. I guess it uses some other mechanism than threads to do things asynchronously.

Ideally publish() would have a flag to make it blocking instead of asynchronous, but in place of that I need some way to do the blocking myself.

geremyCohen commented 11 years ago

Thanks @blazeroot! Since most often than not simple is the most elegant solution... let me see if I can get you a blocking synchronous publish version ASAP. Standby...

geremyCohen commented 11 years ago

@ghostganz I just pushed a candidate 3.3.0.8 which has an optional :sync_http initializer option:

pn = Pubnub.new(:publish_key => :demo, :subscribe_key => :demo, :sync_http => true)

This will push all publish requests through a blocking httparty request, instead of the default em-http.

Please let me know if this helps you. geremy

ghostganz commented 11 years ago

Thanks a lot @geremyCohen, that seems to work!

Minor detail: You could make "callback" a non-mandatory attribute to publish() when sync_http is true. I have to use a no-op lambda there now.

geremyCohen commented 11 years ago

@ghostganz awesome, and yes, great suggestion re: the no-op. Our 3.4 version is actually under development right now, so I will be sure to make the callback optional in this scenario.

I'll close this one out, please ping us here or via support at pubnub if you have any additional questions or issues.