lobsterism
lobsterism

Reputation: 3509

Using twitter4j asynchronously from Scala

I'm wanting to use AsyncTwitter from my Scala app. Is there a way to wrap it in futures so it looks more like idiomatic Scala? Or are futures really there to convert synchronous things to asynchronous (i.e., not useful for functions that are already async)?

Either way, what's the most idiomatic way of doing an async twitter status update in Scala

  1. Wrap the AsyncTwitter code in futures?
  2. Wrap the synchronous code in a future?
  3. Forget futures and just rewrite the code below in Scala.

and (especially if #1 is the answer) what would the final code look like?

Here's the code I'm wondering about: http://twitter4j.org/en/code-examples.html#asyncAPI

TwitterListener listener = new TwitterAdapter() {
    @Override public void updatedStatus(Status status) {
      System.out.println("Successfully updated the status to [" +
               status.getText() + "].");
    }

    @Override public void onException(TwitterException e, int method) {
      if (method == TwitterMethods.UPDATE_STATUS) {
        e.printStackTrace();
      } else {
        throw new AssertionError("Should not happen");
      }
    }
}
// The factory instance is re-useable and thread safe.
AsyncTwitterFactory factory = new AsyncTwitterFactory(listenrer);
AsyncTwitter asyncTwitter = factory.getInstance();
asyncTwitter.updateStatus(args[0]);

I'm guessing #2 isn't the answer because then you're still stuck with the overhead of a synchronous thread hanging out suspended, right?

Upvotes: 0

Views: 387

Answers (1)

Marius Danila
Marius Danila

Reputation: 10411

An implementation using Scala's Futures would look like this (the example is for getDirectMessages):

class DirectMessageListener extends TwitterAdapter {

  val promise = Promise[Seq[DirectMessage]]()


  override def gotDirectMessages(messages: ResponseList[DirectMessage]) {
    promise.success(messages)
  }

  override def onException(te: TwitterException, method: TwitterMethod) {
    promise.failure(te)
  }
}

class TwitterClient(twitter: Twitter) {

  val factory = new AsyncTwitterFactory()

  def getDirectMessage(): Future[Seq[DirectMessage]] = {
    val listener = new DirectMessageListener
    val asyncTwitter = factory.getInstance(twitter)
    asyncTwitter.addListener(listener)
    asyncTwitter.getDirectMessages()
    listener.promise.future
  }

}

Usage:

val client = new TwitterClient(???)  
client.getDirectMessage() onComplete (_.foreach(println))

Upvotes: 1

Related Questions