Приложение консоли Scala не закрывается при использовании реактивного драйвера Mongo

Я использую ReactiveMongo 0.16.1 и MongoDB 4.0.

В основном классе я запускаю следующее:

  DataManager.processFeedbacks
  val future1 = DataManager.processNewEvaluations
  val future2 = DataManager.processPurchases
  val future3 = DataManager.processExpiredEvaluations
  val future4 = DataManager.processExpiredCommerialLicenses
  val futures = List(future1, future2, future3, future4).map(_.map(Try(_)))
  val complete = Future.sequence(futures).onComplete _
  complete(_ => {
    DatabaseConfigService.closeDriver
  })

Все работает нормально, за исключением того, что я не могу закрыть драйвер, а основной поток продолжает зависать, не позволяя приложению выйти.

В closeDriver() я попробовал driver.close, conn.askClose()(Duration.create(10, TimeUnit.SECONDS) и

futureConnection.map(conn => {
     conn.askClose()(Duration.create(10, TimeUnit.SECONDS))
       .onComplete(y => driver.close())
   })

И все безрезультатно, как вы могли догадаться.

Вот дамп темы:

2019-02-05 14:33:18
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.191-b12 mixed mode):

"Analytics" #68 prio=1 os_prio=31 tid=0x00007fc9fd92c800 nid=0x9f07 waiting on condition [0x000070000dc97000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076b960148> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at com.segment.analytics.Platform$1$1.run(Platform.java:45)
    at java.lang.Thread.run(Thread.java:748)

"DestroyJavaVM" #40 prio=5 os_prio=31 tid=0x00007fc9fc0ff000 nid=0x1903 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Analytics" #32 prio=1 os_prio=31 tid=0x00007fc9fe0b4800 nid=0x6203 waiting on condition [0x000070000eecd000]
   java.lang.Thread.State: TIMED_WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076ba51808> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at com.segment.analytics.Platform$1$1.run(Platform.java:45)
    at java.lang.Thread.run(Thread.java:748)

"Analytics" #31 prio=1 os_prio=31 tid=0x00007fc9fe0b2800 nid=0x6103 waiting on condition [0x000070000edca000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076ba3a870> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at com.segment.analytics.internal.AnalyticsClient$Looper.run(AnalyticsClient.java:106)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at com.segment.analytics.Platform$1$1.run(Platform.java:45)
    at java.lang.Thread.run(Thread.java:748)

"Service Thread" #10 daemon prio=9 os_prio=31 tid=0x00007fc9fe0dd000 nid=0x3e03 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread3" #9 daemon prio=9 os_prio=31 tid=0x00007fc9ff00b800 nid=0x4003 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread2" #8 daemon prio=9 os_prio=31 tid=0x00007fc9fc801000 nid=0x3c03 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=31 tid=0x00007fc9fc1b1800 nid=0x3b03 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=31 tid=0x00007fc9fe0dc800 nid=0x3903 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Monitor Ctrl-Break" #5 daemon prio=5 os_prio=31 tid=0x00007fc9fe0db000 nid=0x3703 runnable [0x000070000d582000]
   java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
    at java.net.SocketInputStream.read(SocketInputStream.java:171)
    at java.net.SocketInputStream.read(SocketInputStream.java:141)
    at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
    at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
    at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
    - locked <0x00000006c0015800> (a java.io.InputStreamReader)
    at java.io.InputStreamReader.read(InputStreamReader.java:184)
    at java.io.BufferedReader.fill(BufferedReader.java:161)
    at java.io.BufferedReader.readLine(BufferedReader.java:324)
    - locked <0x00000006c0015800> (a java.io.InputStreamReader)
    at java.io.BufferedReader.readLine(BufferedReader.java:389)
    at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:64)

"Signal Dispatcher" #4 daemon prio=9 os_prio=31 tid=0x00007fc9fb85d000 nid=0x4303 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=31 tid=0x00007fc9fd800000 nid=0x4703 in Object.wait() [0x000070000d37c000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000006c00170e0> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)
    - locked <0x00000006c00170e0> (a java.lang.ref.ReferenceQueue$Lock)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)

"Reference Handler" #2 daemon prio=10 os_prio=31 tid=0x00007fc9fb83f800 nid=0x4903 in Object.wait() [0x000070000d279000]
   java.lang.Thread.State: WAITING (on object monitor)
    at java.lang.Object.wait(Native Method)
    - waiting on <0x00000006c001e220> (a java.lang.ref.Reference$Lock)
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
    - locked <0x00000006c001e220> (a java.lang.ref.Reference$Lock)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

"VM Thread" os_prio=31 tid=0x00007fc9fb839000 nid=0x4b03 runnable 

"GC task thread#0 (ParallelGC)" os_prio=31 tid=0x00007fc9fe801800 nid=0x2507 runnable 

"GC task thread#1 (ParallelGC)" os_prio=31 tid=0x00007fc9fe802800 nid=0x2a03 runnable 

"GC task thread#2 (ParallelGC)" os_prio=31 tid=0x00007fc9fe803000 nid=0x2b03 runnable 

"GC task thread#3 (ParallelGC)" os_prio=31 tid=0x00007fc9ff000000 nid=0x5203 runnable 

"GC task thread#4 (ParallelGC)" os_prio=31 tid=0x00007fc9ff001000 nid=0x5003 runnable 

"GC task thread#5 (ParallelGC)" os_prio=31 tid=0x00007fc9ff800000 nid=0x4f03 runnable 

"GC task thread#6 (ParallelGC)" os_prio=31 tid=0x00007fc9fe00a000 nid=0x2d03 runnable 

"GC task thread#7 (ParallelGC)" os_prio=31 tid=0x00007fc9ff801000 nid=0x2e03 runnable 

"VM Periodic Task Thread" os_prio=31 tid=0x00007fc9fe800000 nid=0x5503 waiting on condition 

JNI global references: 2012

Heap
 PSYoungGen      total 116736K, used 58485K [0x000000076ab00000, 0x0000000772a80000, 0x00000007c0000000)
  eden space 105984K, 55% used [0x000000076ab00000,0x000000076e41d548,0x0000000771280000)
  from space 10752K, 0% used [0x0000000771d00000,0x0000000771d00000,0x0000000772780000)
  to   space 10752K, 0% used [0x0000000771280000,0x0000000771280000,0x0000000771d00000)
 ParOldGen       total 141312K, used 10517K [0x00000006c0000000, 0x00000006c8a00000, 0x000000076ab00000)
  object space 141312K, 7% used [0x00000006c0000000,0x00000006c0a45578,0x00000006c8a00000)
 Metaspace       used 38906K, capacity 42786K, committed 42968K, reserved 1087488K
  class space    used 5527K, capacity 5819K, committed 5888K, reserved 1048576K

P.S. Кажется, у меня та же проблема, что описана здесь< /а>. Однако этот пост был из 2015 года, и исправление должно было быть развернуто давным-давно ... Тем не менее, я все еще не могу закрыть драйвер.


person ClassNotFoundException    schedule 05.02.2019    source источник


Ответы (1)


Как это часто бывает, проблема была между компьютером и креслом... Публикую ответ здесь, в надежде, что когда-нибудь он кому-нибудь поможет.

Я упустил, что самая первая строчка в коде DataManager.processFeedbacks тоже создает будущее. Я не дождался его завершения и закрыл драйвер слишком рано.

Я понял это, снова проверив потоки дампа и найдя классы, которые использовал мой код. Один из классов использовался функцией processFeedbacks()

person ClassNotFoundException    schedule 05.02.2019