[ 
https://issues.apache.org/jira/browse/TINKERPOP3-972?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15011206#comment-15011206
 ] 

ASF GitHub Bot commented on TINKERPOP3-972:
-------------------------------------------

Github user spmallette commented on the pull request:

    
https://github.com/apache/incubator-tinkerpop/pull/146#issuecomment-157750708
  
    Ok - so just to be clear, for your cases 2 and 3, the executor that you 
called `shutdown()` on might still be active when the `CompletableFuture` 
finishes to say the "cluster is closed"?  In other words, all resources haven't 
been really shutdown at the point the future returns because the executor might 
still be working on that since you aren't blocking.  Is that a problem or am I 
not thinking of that right?
    
    actually, I'm trying to think of what weird things might happen if there is 
something long running in the executor and then we call closeAsync()? If there 
was such a situation, that will schedule a job to close the transport which 
might somehow be in use by that long run job.  It seems like it is wrong to try 
to use the executor in shutdown.  Maybe it would be better if it was just a 
standalone "shutdown" thread?  in that way it could call `executor.shutdown()` 
and `awaitTermination()` and then call `factory.shutdown()` and then complete 
the future.  wdyt?  am i thinking too much?


> Cluster::close does not shut down its executor
> ----------------------------------------------
>
>                 Key: TINKERPOP3-972
>                 URL: https://issues.apache.org/jira/browse/TINKERPOP3-972
>             Project: TinkerPop 3
>          Issue Type: Bug
>          Components: driver
>    Affects Versions: 3.0.2-incubating
>            Reporter: Pierre Laporte
>            Assignee: stephen mallette
>
> *Context*
> Using the Gremlin driver in a Java application, I can create a {{Cluster}} 
> and a {{Client}} to send some queries to my Gremlin server.
> However, my application never finishes because some Gremlin worker threads 
> stay alive, even though I call {{cluster.close()}}.
> *Cause*
> Those threads are never terminated:
> {code}
> "gremlin-driver-worker-4" #25 prio=5 os_prio=31 tid=0x00007f824ca4a800 
> nid=0x6a07 waiting on condition [0x0000700001df0000]
>    java.lang.Thread.State: WAITING (parking)
>       at sun.misc.Unsafe.park(Native Method)
>       - parking to wait for  <0x000000076edb9158> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
>       at 
> java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
>       at 
> java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
>       at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
>       at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>       at java.lang.Thread.run(Thread.java:745)
> "gremlin-driver-worker-3" #23 prio=5 os_prio=31 tid=0x00007f824ca46800 
> nid=0x6803 waiting on condition [0x0000700001ced000]
>    java.lang.Thread.State: WAITING (parking)
>       at sun.misc.Unsafe.park(Native Method)
>       - parking to wait for  <0x000000076edb9158> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
>       at 
> java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
>       at 
> java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
>       at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
>       at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>       at java.lang.Thread.run(Thread.java:745)
> "gremlin-driver-worker-2" #22 prio=5 os_prio=31 tid=0x00007f824e22f800 
> nid=0x6603 waiting on condition [0x0000700001bea000]
>    java.lang.Thread.State: WAITING (parking)
>       at sun.misc.Unsafe.park(Native Method)
>       - parking to wait for  <0x000000076edb9158> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
>       at 
> java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
>       at 
> java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
>       at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
>       at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>       at java.lang.Thread.run(Thread.java:745)
> "gremlin-driver-worker-1" #21 prio=5 os_prio=31 tid=0x00007f824e21f000 
> nid=0x6403 waiting on condition [0x0000700001ae7000]
>    java.lang.Thread.State: WAITING (parking)
>       at sun.misc.Unsafe.park(Native Method)
>       - parking to wait for  <0x000000076edb9158> (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.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
>       at 
> java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
>       at 
> java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
>       at 
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
>       at 
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
>       at java.lang.Thread.run(Thread.java:745)
> {code}
> *Workaround*
> This code block can solve the issue on the caller side, but relies on 
> reflection and might break any time the implementation changes:
> {code:java}
>     private void fixThreadLeakInGremlinCluster(Cluster cluster) {
>         try {
>             Method executorAccessor = 
> Cluster.class.getDeclaredMethod("executor");
>             executorAccessor.setAccessible(true);
>             ScheduledExecutorService executor = (ScheduledExecutorService) 
> executorAccessor.invoke(cluster);
>             executor.shutdownNow();
>         } catch (Exception e) {
>             e.printStackTrace();
>         }
>     }
> {code}



--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to