twitter4s: как вернуть будущее из Action.asyn c в игровые рамки - PullRequest
0 голосов
/ 15 февраля 2020

я использую twitter4s и play-framework-2.4.3

Я получаю твиты, отправленные актеру для выполнения некоторой обработки над ним и актером необходимо отправить ответ обратно контроллеру. Вот мой код

def totalTweetCount = Action.async {
    log.debug("in the action tofaltweets")
            def getTweet: PartialFunction[StreamingMessage, Unit] = {
      case tweet: Tweet =>
        future = ask(myActor, TotalNumberOfTweets(tweet)).mapTo[Int]  
    }
    val streaming: Future[TwitterStream] = streamingClient.sampleStatuses(stall_warnings = true)(getTweet)
}


class MyActor extends Actor {
//sends back the response to the calling code
}

. Теперь проблема в том, что строка ниже строки работает непрерывно (это поток в твиттере), непрерывно вызывает метод getTweet и отправляет объект твита в актер

val streaming: Future[TwitterStream] = streamingClient.sampleStatuses(stall_warnings = true)(getTweet)

я хочу получить ответ актера и отобразить его в блоке Ok моего действия, когда я делаю что-то подобное, я получаю NullPointerException

def totalTweetCount = Action.async {
    log.debug("in the action tofaltweets")



      def getTweet: PartialFunction[StreamingMessage, Unit] = {
          case tweet: Tweet =>
            var future: Future[Int] = null
            future = ask(myActor, TotalNumberOfTweets(tweet)).mapTo[Int]

        }
        val streaming: Future[TwitterStream] = streamingClient.sampleStatuses(stall_warnings = true)(getTweet)
    future.map {
              result =>
                Ok("Total number of tweets" + result)
            }
      }

, если я делаю это def totalTweetCount = Action.asyn c {log.debug ("в действии tofaltweets")

def getTweet: PartialFunction[StreamingMessage, Unit] = {
  case tweet: Tweet =>
    var future: Future[Int] = null
    future = ask(actorManager, TotalNumberOfTweets(tweet)).mapTo[Int]
    future.map {
      result =>
        Ok("Total number of tweets" + result)
    }
}
val streaming: Future[TwitterStream] = streamingClient.sampleStatuses(stall_warnings = true)(getTweet)

} также неверно, так что подход должен быть правильным

1 Ответ

0 голосов
/ 17 февраля 2020

Я не уверен, что вы пытаетесь сделать здесь, но здесь это так:

Во всех решениях вы вызываете метод streamingClient.sampleStatuses внутри вашего контроллера, который не делает много смысла, так как это потоковый метод. Читая документы twitter4s, кажется, что они используют асинхронный подход к получению твитов.

Теперь, если вы пытаетесь получать твиты, сохраняйте их, а они получают общую сумму в отдельном методе, вы следует:

Вызвать streamingClient.sampleStatuses внутри вашего main метода и отправить входящий твит своему актеру

streamingClient.sampleStatuses(stall_warnings = true) {
  case t: Tweet => tweetsActor ! t    
}

, который отправит все данные твита вашему классу актера. Предположим, что реализации вашего актера будут выглядеть примерно так:

class Tweets extends Actor {
  var tweets = ListBuffer[Tweet]()

  def receive = {
    case t: Tweet => tweets += t
    case TotalTweetCount = sender() ! tweets.length
  }
}

Ваш метод контроллера будет выглядеть следующим образом:

import akka.pattern.ask_

def totalTweetCount = Action.async {
  (tweetActor ? TotalTweetCount).mapTo[Int]
}

Это должно сработать.

...