【发布时间】:2016-05-06 23:51:09
【问题描述】:
基本上,我想做的就是从我的数据库中获取所有用户,直到我想使用 deadbolt 的那一刻,它都运行良好:
我认为 fork-join-executor 的 4 个线程(处理器数量)已经全部使用,然后出现了某种死锁。 我尝试过的事情:
- 提高执行程序的线程数,因此 play/akka 会忽略我的设置
- 在控制器中为未来定义另一个执行上下文,但这并不能防止死锁,因为超过四个线程仍然在彼此等待
- 使用线程池执行器,但我的设置被忽略
来自此处的混合 scala/java 代码:
class UserController {
def getUserList = deadbolt.Restrict(List(Array("Admin")))(){ implicit request =>
Future {
val users = userModel.list
val json = Json.toJson(users)
Ok(json.toString)
}(
}
}
用户模型本质上无非是:
public class UserModel {
private MongoClient client = new MongoClient();
private Morphia morphia = new Morphia();
protected Datastore datastore = morphia.createDatastore(client, "timetracking");
public List<User> list(){
return datastore.find(User.class).asList();
}
public User findUserByName(String name){
User found = datastore.createQuery(User.class).field("username").equal(name).get();
return found;
}
}
授权处理程序:
class AuthorizationHandler extends DeadboltHandler {
val model = new UserModel
override def getSubject[A](request: AuthenticatedRequest[A]): Future[Option[Subject]] =
Future {
blocking {
request.subject match {
case Some(user) =>
request.subject
case None =>
val username = request.session.get("username")
if (username.isDefined) {
val user = model.findUserByName(username.get)
if (user == null) {
None
} else {
val subject = new ScalaSubject(user.getUsername, user.getRole)
Some(subject)
}
} else {
None
}
}
}
}
定义单独的锁栓上下文没有帮助:
package deadbolt.scala
import be.objectify.deadbolt.scala.DeadboltExecutionContextProvider
import be.objectify.deadbolt.scala.cache.HandlerCache
import play.api.inject.{Binding, Module}
import play.api.{Configuration, Environment}
class DeadBoldModule extends Module {
override def bindings(environment: Environment,
configuration: Configuration): Seq[Binding[_]] = Seq(
bind[HandlerCache].to[TimeTrackerHandelCache],
bind[DeadboltExecutionContextProvider].to[ThreadPoolProvider]
)
}
自定义上下文提供者:
package deadbolt.scala
import java.io.InvalidObjectException
import java.util.concurrent.Executors
import be.objectify.deadbolt.scala.DeadboltExecutionContextProvider
import scala.concurrent.ExecutionContext
class ThreadPoolProvider extends DeadboltExecutionContextProvider {
override def get(): ExecutionContext = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(100))
}
当我尝试这个时,抛出一些随机异常,它永远不会被抛出:
package deadbolt.scala
import java.io.InvalidObjectException
import java.util.concurrent.Executors
import be.objectify.deadbolt.scala.DeadboltExecutionContextProvider
import scala.concurrent.ExecutionContext
class ThreadPoolProvider extends DeadboltExecutionContextProvider {
override def get(): ExecutionContext = throw new IllegalAccessError("asd");ExecutionContext.fromExecutor(Executors.newFixedThreadPool(100))
}
【问题讨论】:
-
如果你给 Deadbolt 自己的执行上下文会发生什么?详情请见deadbolt-scala.readme.io/docs/execution-context。
-
感谢您的回复,我更新了问题。它似乎没有帮助。 http 请求有时仍然永远不会完成,如果我删除了锁舌安全检查,它就会完成。也许我以错误的方式声明了上下文提供者?顺便说一句:标准的死栓模块绑定了这个:bind[ExecutionContextProvider].to[DefaultExecutionContextProvider], Not DeadboltExecutionContextProvider.
-
我知道 - 它提供了一个默认的 DeadboltExecutionContextProvider 以防自定义的未绑定。奇怪的是你的异常没有被抛出;尝试向github.com/schaloner/deadbolt-2-scala/blob/master/code/app/be/… 添加断点,看看会发生什么。
标签: multithreading mongodb scala playframework