2016-11-02 8 views
7

Używam MongoDB w aplikacjach wielowątkowych Clojure, korzystając z biblioteki Monger, a jeden z moich wątków producentów umierają zPrevent MongoDB przed śmiercią z „państwo powinno być: otwarte”

java.lang.IllegalStateException: state should be: open 
at com.mongodb.assertions.Assertions.isTrue (Assertions.java:70) 
    com.mongodb.connection.DefaultServer.getConnection (DefaultServer.java:84) 
    com.mongodb.binding.ClusterBinding$ClusterBindingConnectionSource.getConnection (ClusterBinding.java:86) 
    com.mongodb.operation.QueryBatchCursor.getMore (QueryBatchCursor.java:205) 
    com.mongodb.operation.QueryBatchCursor.hasNext (QueryBatchCursor.java:103) 
    com.mongodb.MongoBatchCursorAdapter.hasNext (MongoBatchCursorAdapter.java:46) 
    com.mongodb.DBCursor.hasNext (DBCursor.java:155) 
    clojure.lang.RT$4.invoke (RT.java:512) 
    clojure.lang.LazySeq.sval (LazySeq.java:40) 
    clojure.lang.LazySeq.seq (LazySeq.java:49) 
    clojure.lang.RT.seq (RT.java:525) 
    clojure.core$seq__6416.invokeStatic (core.clj:137) 
    clojure.core$map$fn__6875.invoke (core.clj:2719) 
    clojure.lang.LazySeq.sval (LazySeq.java:40) 
    clojure.lang.LazySeq.seq (LazySeq.java:49) 
    clojure.lang.RT.seq (RT.java:525) 
    clojure.core$seq__6416.invokeStatic (core.clj:137) 
    clojure.core$map$fn__6875.invoke (core.clj:2719) 
    clojure.lang.LazySeq.sval (LazySeq.java:40) 
    clojure.lang.LazySeq.seq (LazySeq.java:49) 
    clojure.lang.RT.seq (RT.java:525) 
    clojure.core$seq__6416.invokeStatic (core.clj:137) 
    clojure.core$filter$fn__6902.invoke (core.clj:2782) 
    clojure.lang.LazySeq.sval (LazySeq.java:40) 
    clojure.lang.LazySeq.seq (LazySeq.java:49) 
    clojure.lang.ChunkedCons.chunkedNext (ChunkedCons.java:59) 
    clojure.lang.ChunkedCons.next (ChunkedCons.java:43) 
    clojure.lang.RT.next (RT.java:703) 
    clojure.core$next__6400.invokeStatic (core.clj:64) 
    clojure.core$dorun.invokeStatic (core.clj:3115) 
    clojure.core$doall.invokeStatic (core.clj:3121) 
    clojure.core$doall.invoke (core.clj:3121) 
    myapp.ns1.$somefn.invokeStatic (ns1.clj:93) 
    myapp.ns1.$somefn.invoke (ns1.clj:90) 
    myapp.ns1$anotherfn.invokeStatic (ns1.clj:124) 
    myapp.ns1$anotherfn.invoke (ns1.clj:116) 
    myapp.ns2$doit.invokeStatic (ns2:21) 
    myapp.ns2$doit.invoke (ns2:17) 
    myapp.ns2$producer$fn__11200.invoke (ns2:45) 
    myapp.ns2$producer.invokeStatic (ns2:31) 
    myapp.ns2$producer.invoke (ns2:25) 
    myapp.ns2$_start$fn__11230.invoke (ns2:70) 
    clojure.core$binding_conveyor_fn$fn__6766.invoke (core.clj:2020) 
    clojure.lang.AFn.call (AFn.java:18) 
    java.util.concurrent.FutureTask.run (FutureTask.java:266) 
    java.util.concurrent.ThreadPoolExecutor.runWorker (ThreadPoolExecutor.java:1142) 
    java.util.concurrent.ThreadPoolExecutor$Worker.run (ThreadPoolExecutor.java:617) 
    java.lang.Thread.run (Thread.java:745) 

mam znaleziono kilka innych trafień dla tego problemu i wszystkie zostały rozwiązane przez usunięcie gdzieś jakiegoś połączenia conn.close().

Mam jedno połączenie, które utworzę podczas uruchamiania i jedynym miejscem, które nazywam close podczas wyłączania. Sterownik java zarządza wątkiem, więc nie jestem do końca pewien, o jakim połączeniu mówimy. Czy obiekt DbObject zwrócony z zapytań ma własne dedykowane połączenie i to jest to połączenie, które umiera?

Próbowałem naprawić, określając :socket-keep-alive true, i jawnie ustawienie :socket-timeout na 0 (co jest domyślne i oznacza nieograniczoną) bezskutecznie.

W przypadku niektórych istnieje pewne użycie with-open, które według mnie mogą spowodować problem, który mam. Gdyby nie było jakiegoś powiązania związanego z obiektem db, który zostałby tutaj przekazany, a który zostanie zamknięty, próbowałem usunąć wszystkie ponowne użycie obiektów db, ale to nie przyniosło efektu.

Inna myśl polegała na tym, że with-open może źle wchodzić w interakcje z leniwymi materiałami wewnątrz, ale owijając wszystko w doall, aby sprawić, że nie będzie on miał żadnego efektu.

Używam zestawu replik i uruchamiam lokalnie na mondzie slave z ReadPreference/secondary.

Jakieś inne pomysły na temat tego, co może być nie tak?

+0

może być pomocne śledzenie stosu – evanchooly

Odpowiedz

0

Po oderwaniu warstw lenistwa w mojej aplikacji wyjątek zmieniono na "Nie znaleziono kursora DB". W tym momencie było oczywiste, co było nie tak i zarządzając własnym kursorem za pomocą notimeout, zamiast używać monger, przypadkowe błędy zniknęły.

Powiązane problemy