轻松玩转SecureSocial:在单独的线程池中运行DB IO [英] Play-slick with SecureSocial: Running DB IO in a separate thread pool

查看:96
本文介绍了轻松玩转SecureSocial:在单独的线程池中运行DB IO的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Play 2.2.1应用,该应用使用 play-slick 0.5.0.8 将数据持久保存到Postgresql后端和 SecureSocial 2.1.2 处理用户授权.

I have a Play 2.2.1 app that uses play-slick 0.5.0.8 to persist data to a Postgresql backend and SecureSocial 2.1.2 to handle user authorisation.

由于play-slick交易被阻止,因此根据

Since play-slick transactions are blocking, I have created a separate slick-context execution context in my /conf/application.conf file, as per the instructions found in the plugin's Wiki:

play {
  akka {
    actor {
      slick-context = {
        fork-join-executor {
          parallelism-min = 300
          parallelism-max = 300
        }
      }
    }
  }
}

这允许我创建一个控制器Action,该Action在单独的执行上下文中运行,并且不阻止默认线程池中的线程.例如. /app/controllers/Application.scala:

This allows me to create a controller Action that runs in a separate execution context and does not block threads in the default thread pool. Eg. /app/controllers/Application.scala:

示例一-使用play-slick的DBAction:

import play.api.db.slick._
object Application extends Controller{ 

  // this controller Action won't block threads in the default pool since DBAction uses my separate slick-context execution context
  def recipes = DBAction { implicit rs =>
    val recipes  = Query(Recipes).list
    Ok(recipes.mkString)
  }

}

对于某些控制器动作,我希望能够结合使用play-slick的DBAction来使用SecureSocial的动作(SecuredActionUserAwareAction等).结合两者的最佳方法是什么?

For certain controller actions I want to be able to utilise SecureSocial's Actions (SecuredAction, UserAwareAction etc) in conjunction with play-slick's DBAction. What is the best way to combine the two?

我意识到我可以执行以下操作,但是我的理解是数据库调用不会使用我单独的slick-context,因此将阻止默认线程池:

I realise I can do something like the below, but my understanding is that the DB call won't use my separate slick-context and will therefore block the default thread pool:

示例二-使用SecureSocial的操作:

import play.api.db.slick._
import securesocial.core._
object Application extends Controller{ 

  // changing from a DBAction to a SecuredAction so that I can use SS's goodies
  def recipes = SecuredAction { implicit request =>
    val recipes  =  DB.withSession { implicit session:Session => Query(Recipes).list } // i'm guessing this WILL BLOCK the default thread pool since it isn't using my separate slick-context execution context??
    Ok(recipes.mkString)
  }

}

我正确地假设示例二将使用/阻止默认线程池而不是我单独的slick-context线程池吗?如果是这样,有没有办法改变这一点?

Am I correct in assuming that Example Two will use/block the default thread pool instead of my separate slick-context thread pool? If so, is there a way to change this?

我显然可以通过解决Play的默认线程池(default-dispatcher)来解决此问题,但理想情况下,我想保持默认线程池相当精简,并在单独的池中运行所有阻塞的数据库调用.

I could obviously get around this by bumping up Play's default thread pool (default-dispatcher), but ideally I want to keep the default thread pool quite lean, and run all blocking DB calls in a separate pool.

感谢您的帮助!

推荐答案

要回答您的问题,

我正确地假设示例二将使用/阻止默认值 线程池,而不是我单独的光滑上下文线程池?如果是这样,

Am I correct in assuming that Example Two will use/block the default thread pool instead of my separate slick-context thread pool? If so,

是的,这将耗尽/阻止默认池.

Yes, that would use up/block the default pool.

如果您想使用单独的slick-context线程池,那么您可以尝试这样的事情吗?

If you want to use the separate slick-context thread pool, then you could try something like this?

  import scala.concurrent.Future

  // Note the use of '.async' |
  //                          V
  def recipes = SecuredAction.async { implicit request =>
    Future { // your code that may block
      val recipes  =  DB.withSession { implicit s:Session => 
        Query(Recipes).list 
      } 
      Ok(recipes.mkString)
    } 
  }

Future期望为ExecutionContext(隐式将起作用);您需要传递的所有内容(隐式地)用于播放浮点数:

Future expects an ExecutionContext (an implicit will do); all you need to to pass in the one that play-slick uses (implicitly):

import play.api._
implicit val slickExecutionContext = 
  Akka.system.dispatchers.lookup("play.akka.actor.slick-context")

这篇关于轻松玩转SecureSocial:在单独的线程池中运行DB IO的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆