Reputation: 3509
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
AsyncTwitter
code in futures?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
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