2016-11-02 1 views
7

나는 상인 라이브러리를 사용하여, 다중 스레드 Clojure의 응용 프로그램에서 MongoDB를 사용하고, 내 생산자 스레드 중 하나가방지 MongoDB를 '상태가되어야합니다 : 열린'

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) 

으로 죽어 가고 나는했습니다 이 문제에 대한 다른 히트 곡을 발견했으며 어딘가에 conn.close() 콜을 제거하여 모두 해결했습니다.

내가 시작시 생성하는 단일 연결이 있으며 종료시에만 close이라고합니다. 자바 드라이버는 쓰레드 풀을 관리하기 때문에 우리가 어떤 연결에 대해서 이야기하고 있는지 확실하지 않다. 쿼리에서 반환 된 DbObject가 자체 전용 연결을 가지고 있으며이 연결이 끊어지고 있습니까?

을 지정하여이 문제를 해결하고 :socket-timeout을 0 (기본값이며 무제한을 의미)으로 명시 적으로 설정하면 아무런 문제가 없습니다.

monger에는 내가 가지고있는 문제를 일으킬 수 있다고 생각한 with-open의 사용법이 있습니다. db 객체와 관련된 몇 가지 연결이있을 때, 여기에 전달되어 닫히고, db 객체의 모든 재사용을 제거하려고 시도했지만 효과가 없습니다.

또 다른 생각은 with-open이 게으른 것들과 나쁘게 상호 작용할 수도 있지만 doall의 모든 것을 래핑하여 열망하게 만들지도 않았다는 것입니다.

복제본 세트에 대해 실행 중이며 ReadPreference/secondary으로 슬레이브 mongodb에서 로컬로 실행 중입니다.

무엇이 잘못 되었습니까?

+0

스택 추적이 도움이 될 수 있습니다. – evanchooly

답변

0

내 응용 프로그램에서 게으름의 레이어를 벗겨 내고 예외가 "DB 커서를 찾을 수 없습니다"와 같은 것으로 변경되었습니다. 그 시점에서 무엇이 잘못되었고 notimeout으로 자신의 커서를 관리하여 monger을 사용하는 대신 임의의 오류가 사라졌습니다.