2016-05-06 41 views
0

基本上所有我想要做的就是让所有用户都从我的数据库,它工作得很好,直到那一刻,我想利用拨销吧:死锁的Play 2.5阶,门栓2.5和MongoDB /吗啡

我想fork-join-executor的4个线程(处理器数量)已经全部被使用,然后有一些死锁。 事情我想:

  • 提高线程的执行具有数量,所以不过播放/阿卡忽略我的设置
  • 定义控制器期货另一个执行上下文,但是这并不妨碍死锁,因为更多比四个线程仍然等待对方
  • 使用线程池执行人,但我的设置将被忽略

混合斯卡拉/ 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)) 
} 
+0

如果你给Deadbolt自己的执行上下文会发生什么?有关详细信息,请参阅https://deadbolt-scala.readme.io/docs/execution-context。 –

+0

谢谢您的回复,我更新了问题。它似乎没有帮助。 http请求有时仍然没有完成,如果我删除deadbolt安全检查,它会这样做。也许我以错误的方式宣布Context Provider? 顺便说一下:标准deadbolt modul绑定这个: 绑定[ExecutionContextProvider]。到[DefaultExecutionContextProvider], Not DeadboltExecutionContextProvider。 –

+0

我知道 - 它提供了一个默认的DeadboltExecutionContextProvider来防止自定义的绑定。奇怪你的异常不被抛出;尝试添加一个断点到https://github.com/schaloner/deadbolt-2-scala/blob/master/code/app/be/objectify/deadbolt/scala/ExecutionContextProvider.scala#L42,看看会发生什么。 –

回答

0

这不是门栓的错,而是然而MongoClient打开一个新的线程时,它是instantiated.Which发生在我们的项目相当频繁,但没有正确关闭,从而阻塞了线程池。我们使用了一个Singleton,一切正常。