Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TimerTask#execute is not a blocking call #794

Closed
ajlai opened this issue Jan 24, 2019 · 7 comments · Fixed by #996
Closed

TimerTask#execute is not a blocking call #794

ajlai opened this issue Jan 24, 2019 · 7 comments · Fixed by #996
Labels
question An user question, does not change the library.

Comments

@ajlai
Copy link

ajlai commented Jan 24, 2019

Hi,

I was looking through the TimerTask examples and noticed that the one below isn't working as documented:

# timer_task_boom_test.rb

# from https://github.com/ruby-concurrency/concurrent-ruby/blob/master/lib/concurrent/timer_task.rb#L94-L111
timer_task = Concurrent::TimerTask.new(execution_interval: 1) do |task|
  task.execution_interval.to_i.times { print 'Boom! ' }
  print "\n"
  task.execution_interval += 1
  if task.execution_interval > 5
    puts 'Stopping...'
    task.shutdown
  end
end

timer_task.execute # blocking call - this task will stop itself
#=> Boom!
#=> Boom! Boom!
#=> Boom! Boom! Boom!
#=> Boom! Boom! Boom! Boom!
#=> Boom! Boom! Boom! Boom! Boom!
#=> Stopping...

If I put those contents into a file and run it via ruby timer_task_boom_test.rb, it exits immediately. If I add a sleep right after the timer_task.execute line then I see the Boom!s printed out.

Is timer_task.execute supposed to be a blocking call? Or has the behavior changed and this example is no longer valid?

more info

* Operating system:                mac
* Ruby implementation:             Ruby 2.2.3
* `concurrent-ruby` version:       1.1.4
* `concurrent-ruby-ext` installed: no
* `concurrent-ruby-edge` used:     no
@jdantonio
Copy link
Member

Did you run the example in IRB or as a stand-alone Ruby script?

When Ruby reaches the end of a script it immediately exits, killing all threads, destroying all objects, and releasing all its resources. None of the abstractions in this gem prevent this from happening. (This is by design. We don't want buggy code to ever prevent Ruby from exiting.) So if you ran this as a stand-alone script then Ruby would have exited immediately after your call to timer_task.execute, and that is expected behavior.

If you want to runs this as a stand-alone script and have Ruby not exit until the tasks are done, one option is to use an Event. Create the Event before the TimerTask, pass it into the TimerTask, wait on the Event immediately after calling timer_task.execute, and set the Event in the task just before calling task.shutdown. Or do something similar with a critical section or other similar tool.

@ajlai
Copy link
Author

ajlai commented Jan 24, 2019

Did you run the example in IRB or as a stand-alone Ruby script?

I ran this example as a stand-alone ruby script.
Yes, I understand what ruby does when it reaches the end of the script. My original question was pertaining to the line in example:

timer_task.execute # blocking call - this task will stop itself

which made it sound like the script would block on that line until the task was shutdown (from within the task itself).

I noticed that the script did not block on that line and was asking whether timer_task.execute was supposed to be non-blocking (example is incorrect) or whether it was supposed to be blocking (behavior is incorrect).

@ajlai
Copy link
Author

ajlai commented Jan 24, 2019

So if it is expected behavior that ruby exits right after timer_task.execute then it seems like timer_task.execute is nonblocking, which means the example needs to be updated?

@jdantonio
Copy link
Member

timer_task.execute is not blocking and the example is correct. The examples are all run in IRB unless specifically noted otherwise. If you copy/paste that code into IRB the example will work exactly as documented since IRB remains open until explicitly exited by the user.

@ajlai
Copy link
Author

ajlai commented Jan 24, 2019

timer_task.execute is not blocking and the example is correct.

timer_task.execute # blocking call ...

Maybe I'm getting confused but the two statements above don't seem to be saying the same thing...

How about changing that line in the example to:

timer_task.execute # this task will stop itself

Thoughts?

@pitr-ch pitr-ch added this to the Hackathon candidates milestone Aug 24, 2019
@pitr-ch pitr-ch added the question An user question, does not change the library. label Aug 24, 2019
@pitr-ch pitr-ch added the bug A bug in the library or documentation. label Aug 24, 2019
@pitr-ch pitr-ch modified the milestone: Hackathon candidates Aug 24, 2019
@pitr-ch
Copy link
Member

pitr-ch commented Aug 24, 2019

I cannot get the example to print anything, not sure what is going on. I'll revisit it.

@pitr-ch pitr-ch removed the bug A bug in the library or documentation. label Aug 24, 2019
@chrisseaton
Copy link
Member

@ajlai are you still interested in this issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question An user question, does not change the library.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants