在Play 2.4 for Scala中注入一个由Guice创建的actor的ActorSystem

时间:2015-10-21 09:27:45

标签: scala playframework akka playframework-2.4

我想做的是发送一堆电子邮件,其中每个用户的内容都会发生一些变化(他们的名字等)。

问题是,在等待前一个阻止之后,通过用户列表进行迭代并发送每个用户是非常慢的。

所以我以为我会使用Akka并行完成。

我用

  • 播放2.4.3
  • play-mailer 3.0.1

这是我的演员:

import javax.inject.Inject
import akka.actor._
import play.api.libs.mailer.{MailerClient, Email}

object EmailActor {
  def props = Props[EmailActor]
  case class SendEmail(email: Email)
}

class EmailActor @Inject()(mailerClient: MailerClient) extends Actor {
  import EmailActor._

  def receive = {
    case SendEmail(email: Email) =>
      // send mail
      mailerClient.send(email)
      sender() ! "Sent"
  }
}

我设法将我的演员直接注入我的控制器,但它仍然很慢,我猜它是为每条消息使用相同的演员。我想要一群演员在我的电子邮件上工作!

这是我的模块

class MyModule extends AbstractModule with AkkaGuiceSupport {
  override def configure = {
    bindActor[EmailActor]("email-actor")
  }
}

这是我的控制器

@Singleton
class Emails @Inject()(system: ActorSystem) extends Controller with InjectedActorSupport {
  ...

  def sendEmailToUsers(event : Event, request:RequestHeader) : Future[Seq[String]] = {
    implicit val timeout : akka.util.Timeout = 5.seconds

    val results = event.people
      .map(user => {
        val actor = system.actorOf(EmailActor.props, "email-actor")
        (actor ? SendEmail(createEmail(event, user, request))).mapTo[String]
      })

    Future.sequence(results)
  }

我得到了例外

IllegalArgumentException: no matching constructor found on class actors.EmailActor for arguments []

我对Akka中的ActorSystem不使用Plays依赖注入感到惊讶。那我该怎么办?

问题

我如何(使用Play中的最佳做法),并行发送电子邮件?

2 个答案:

答案 0 :(得分:0)

更改控制器

class Emails @Inject()(@Named("email-actor") emailActor:ActorRef)(implicit ec: ExecutionContext) extends Controller{

   def sendEmailToUsers(event : Event, request:RequestHeader) : Future[Seq[String]] = {
      implicit val timeout : akka.util.Timeout = 5.seconds

      val results = event.people.map(user => {
         (emailActor ? SendEmail(createEmail(event, user, request))).mapTo[String]
      })
      Future.sequence(results)
   }
}

答案 1 :(得分:0)

请先检查SMTP服务器是否不会限制您。 ; - )

看看Akka routing。将您的actor重构为网关,并通过路由器将发送的电子邮件委派给工作人员。您可以使用RoundRobinRoutingLogicSmallestMailboxRoutingLogic。但是不要创建太多的工作程序,否则SMTP服务器可能会限制/阻止你。