2016-05-06 15 views
0

Im Grunde alles, was ich tun möchte, ist für alle Benutzer aus meiner Datenbank bekommen, was in Ordnung, bis zum Moment arbeitete ich deadbolt dafür verwenden wollte:Deadlocks mit Play 2.5 scala, deadbolt 2.5 und MongoDB/Morphia

Ich denke, Die 4 Threads (Anzahl der Prozessoren) des Fork-Join-Executors werden bereits alle verwendet, und dann gibt es eine Art Deadlock. Dinge, die ich versucht:

  • die Anzahl der Threads Heben der Vollstrecker hat aber so spielen/akka ignoriert meine Einstellungen
  • weiteren Ausführungskontext in der Steuerung für die Zukunft definieren, aber das verhindert nicht, dass Deadlocks seit mehr

einen gemischten scala/Java-Code an jeder anderen

  • Verwendung einen Thread-Pool-Vollstrecker, aber meine Einstellungen ignoriert wartet immer noch als vier Threads von hier:

    Das Benutzermodell ist im Wesentlichen nichts anderes als:

    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; 
        } 
    } 
    

    Authorization Handler:

    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 
          } 
         } 
         } 
        } 
    

    einen separaten deadbolt Kontext definieren nicht hilft:

    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] 
    ) 
    } 
    

    Benutzerdefinierte Kontextanbieter :

    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)) 
    } 
    

    Wenn ich dies versuchen, einige zufällige Ausnahme zu werfen, wird es nie geworfen:

    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

    Was passiert, wenn Sie Deadbolt seinen eigenen Ausführungskontext geben? Einzelheiten finden Sie unter https://deadbolt-scala.readme.io/docs/execution-context. –

    +0

    Vielen Dank für Ihre Antwort, ich habe die Frage aktualisiert. Es scheint nicht zu helfen. Die HTTP-Anfrage wird manchmal immer noch nicht beendet, was ich tun würde, wenn ich die Sicherheitsprüfung des Riegels entferne. Vielleicht habe ich den Context Provider falsch deklariert? Übrigens: das Standard-Deadbolt-Modul bindet das: bind [ExecutionContextProvider] .to [DefaultExecutionContextProvider], Nicht DeadboltExecutionContextProvider. –

    +0

    Ich weiß - es bietet einen Standard DeadboltExecutionContextProvider für den Fall, dass eine benutzerdefinierte nicht gebunden ist. Seltsam, dass Ihre Ausnahme nicht ausgelöst wird; Versuchen Sie, https://github.com/schaloner/deadbolt-2-scala/blob/master/code/app/be/objectify/deadbolt/scala/ExecutionContextProvider.scala#L42 einen Haltepunkt hinzuzufügen und sehen Sie, was passiert. –

    Antwort

    0

    Es ist nicht Schuld deadbolts wurde, dafür aber der MongoClient einen neuen Thread eröffnet, als es war instantiated.Which geschah in unserem Projekt ziemlich oft, wurde aber nicht richtig geschlossen und blockierte den Threadpool. Wir haben ein Singleton benutzt und alles hat gut funktioniert.

    Verwandte Themen