Ah…. an InterruptStrategy! … I'm liking that. Matt, can you say a bit more 
about such a design? If you can wrap an entire traversal in its own isolated 
thread and then be able to kill it when you want, that would be pretty sweet 
--- however, does that mess up threaded transactions and the 
one-thead-per-transaction-model that TP3 current supports?

Marko.

http://markorodriguez.com

On Oct 16, 2015, at 9:08 AM, Matt Frantz <matthew.h.fra...@gmail.com> wrote:

> Perhaps a strategy could insert interrupt checks in appropriate places,
> avoiding inner loops, or perhaps refactoring them into two-level loops
> where we check for interrupt on the outer level.
> 
> On Fri, Oct 16, 2015 at 6:58 AM, Marko Rodriguez <okramma...@gmail.com>
> wrote:
> 
>> Hi,
>> 
>> This is a scary body of work as processNextStarts() is not just in the
>> base steps MapStep/FlatMapStep/BranchStep/etc., but littered throughout
>> where extensions to the base steps are not easily done (e.g. barriers,
>> etc.). Next, benchmark --- for every next there is an interrupt check
>> (eek!).
>> 
>> The idea of being able to interrupt a Traversal is nice, but the
>> implementation and performance details are probably going to prove daunting.
>> 
>> Marko.
>> 
>> http://markorodriguez.com
>> 
>> On Oct 16, 2015, at 5:31 AM, Daniel Kuppitz <m...@gremlin.guru> wrote:
>> 
>>> This is a nice one. Once we have that in place, we can probably/hopefully
>>> also provide a hotkey to gracefully cancel queries in the REPL (w/o
>> having
>>> to exit the console itself).
>>> 
>>> Cheers,
>>> Daniel
>>> 
>>> 
>>> On Fri, Oct 16, 2015 at 1:05 PM, Stephen Mallette <spmalle...@gmail.com>
>>> wrote:
>>> 
>>>> I'm going to frame this in the context of Gremlin Server but I think
>> this
>>>> issue generally applies to any threaded application development done
>> with
>>>> TinkerPop.
>>>> 
>>>> Gremlin Server does a number of things to protect itself from crazy
>> scripts
>>>> (i.e. long run scripts that may have been accidentally or maliciously
>> sent
>>>> to it).  The one thing it doesn't do perfectly is properly kill running
>>>> scripts in the midst of a long run traversal.  It attempts to stop a
>>>> running script by interrupting the thread that is processing it, but if
>> the
>>>> thread is at a point in the script that doesn't respect
>> Thread.interrupt(),
>>>> it basically just chews up that thread until it reaches a spot that
>> does.
>>>> 
>>>> I think Traversal could do a better job respecting interrupts.  Put in
>> code
>>>> speak, we should look to get this test to pass for all steps:
>>>> 
>>>> @Test
>>>> public void shouldRespectThreadInterruption() throws Exception {
>>>>   final AtomicBoolean exceptionThrown = new AtomicBoolean(false);
>>>>   final CountDownLatch startedIterating = new CountDownLatch(1000);
>>>>   final List<Integer> l = IntStream.range(0,
>>>> 1000000).boxed().collect(Collectors.toList());
>>>> 
>>>>   final Thread t = new Thread(() -> {
>>>>       try {
>>>>           __.inject(l).unfold().sideEffect(i ->
>>>> startedIterating.countDown()).iterate();
>>>>           fail("Should have respected the thread interrupt");
>>>>       } catch (Exception ie) {
>>>>           exceptionThrown.set(ie instanceof RuntimeException);
>>>>       }
>>>>   });
>>>> 
>>>>   t.start();
>>>> 
>>>>   startedIterating.await();
>>>>   t.interrupt();
>>>> 
>>>>   t.join();
>>>>   assertThat(exceptionThrown.get(), CoreMatchers.is(true));
>>>> }
>>>> 
>>>> Two things to note...First, the changes to make this test pass
>> shouldn't be
>>>> "big".  I got this test to pass with the addition of this line of code
>> in
>>>> FlatMapStep.processNextStart() on the first line after the start of the
>>>> while(true).
>>>> 
>>>> if(Thread.interrupted) throw new RuntimeException();
>>>> 
>>>> That single line inserted in the right places should get interrupt
>> working
>>>> properly across Traversal.
>>>> 
>>>> Second, note that I'm throwing/asserting RuntimeException.  I probably
>>>> should be throwing a InterruptedException but that is a checked
>> exception
>>>> and that would really pollute up our Traversal code.  So, my suggestion
>> is
>>>> to create our own "InterruptedRuntimeException" that we can trap
>> separately
>>>> that would potentially wrap an actual InterruptedException.
>>>> 
>>>> I'd like to tack this issue in to 3.1.0 if possible - please let me know
>>>> your thoughts if you have any.
>>>> 
>> 
>> 

Reply via email to