edwinbs
edwinbs

Reputation: 525

put_connections() to Facebook graph in Koala fails after a very long delay

I am using Rails 3.2.5 and Koala 1.3.0 (not the latest, because the latest refuses to run even the sample Facebook app from Heroku). Web server is Unicorn.

When I try to POST to timeline using put_connections():

@fbgraph   = Koala::Facebook::API.new(session[:access_token])
logger.debug "put_connections(#{url_for @room}), start"
@fbgraph.put_connections("me", "myapp:view", :room => url_for(@room))
logger.debug "put_connections(), end"

The controller stalls for 12s before getting an exception:

Completed 500 Internal Server Error in 12075ms

Koala::Facebook::APIError (HTTP 500: Response body: {"error":{"type":"Exception","message":"Could not retrieve data from URL.","code":1660002}}):

I tested with the debug tool: http://developers.facebook.com/tools/debug and it found no error for the URL logged in line 2.

My web server logs a GET from Facebook IP and returns 200 OK. Facebook IP then makes some more requests to fetch images, which also gets 200 OK.

I am testing this on my app's test users FYI.

UPDATE

This seems to be an OpenGraph issue. This problem reproduces for me: https://developers.facebook.com/bugs/213733412077729

Basically the POST is successful only after I test it on the debugger once! Anyone experienced this before?

Upvotes: 5

Views: 2431

Answers (2)

damoiser
damoiser

Reputation: 6238

I have a similar problem as you, but with a get request that manage more than 600 calls to FB (with total time > 16s).

Explicitly declare the fields seems that works.

graph = @FBGraph.get_object("#{user.fb_user_id}?fields=id,name,username,picture,link")

For more info see my Q/A in stackoverflow HERE

Upvotes: 1

edwinbs
edwinbs

Reputation: 525

Figured it out. Of course the debugger thing doesn't make sense. It worked because Facebook then has my view on their cache.

This is a classic reentrancy problem (which I can't believe I have to deal with in Rails!) -- Facebook's POST API is synchronous and it only returns after it calls back to my show controller. But since I only have 1 worker thread, there is no one servicing the request, thus the hang.

The fix is to invoke the API asynchronously in a thread.

Thread.new {
    @fbgraph.put_connections("me", "myapp:view", :room => url_for(@room))
}

Upvotes: 12

Related Questions