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

Make fetcher pause interval configurable #214

Conversation

darraghotoole
Copy link

@darraghotoole darraghotoole commented May 25, 2016

The fetcher currently pauses for one second when all processes are busy. When running in single-threaded mode this effectively means we can only process one job per second. This PR allows us to configure the pause interval (eg: 0.1 for 100ms) instead of using the hardcoded value.

expect { Shoryuken::Manager.new(nil) }
.to raise_error(ArgumentError, 'Dispatch interval value -1 is invalid, it needs to be a positive number')
end

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra empty line detected at block body end.

@darraghotoole darraghotoole force-pushed the dot/configurable_dispatch_interval branch from 86ce4b0 to b1c3d3d Compare May 25, 2016 14:14
end

unless @dispatch_interval > 0
raise(ArgumentError, "Dispatch interval value #{@dispatch_interval} is invalid, it needs to be a positive number")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [122/120]

@darraghotoole darraghotoole force-pushed the dot/configurable_dispatch_interval branch from b1c3d3d to a6df078 Compare May 26, 2016 10:04
end

unless @fetcher_pause_interval > 0
raise(ArgumentError, "Fetcher pause interval value #{@fetcher_pause_interval} is invalid, it needs to be a positive number")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [132/120]

@darraghotoole darraghotoole changed the title Make dispatch interval configurable Make fetcher pause interval configurable May 26, 2016
@darraghotoole darraghotoole force-pushed the dot/configurable_dispatch_interval branch from a6df078 to 5ad43ca Compare May 26, 2016 10:05
end

unless @fetcher_pause_interval > 0
error_message = "Fetcher pause interval value #{@fetcher_pause_interval} is invalid, it needs to be a positive number"

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [126/120]

@darraghotoole darraghotoole force-pushed the dot/configurable_dispatch_interval branch from 5ad43ca to 73bfced Compare May 26, 2016 10:09
raise(ArgumentError, "Concurrency value #{@count} is invalid, it needs to be a positive number")
end

unless @fetcher_pause_interval > 0
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I experimented with this value being set to 0 without any problems.
https://github.com/celluloid/timers/blob/fcb443006ed1770d3ba2ebf3db0e0d2e570c6672/lib/timers/group.rb#L37
So is perhaps instead if @fetcher_pause_interval < 0 is better?

@darraghotoole darraghotoole force-pushed the dot/configurable_dispatch_interval branch from 73bfced to f66b73d Compare May 26, 2016 10:11
@@ -131,7 +140,7 @@ def dispatch
if @ready.empty?
logger.debug { 'Pausing fetcher, because all processors are busy' }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add info in the message for how long is the fetcher being paused?

@darraghotoole
Copy link
Author

darraghotoole commented May 26, 2016

@bbaja42 @mstewart Renamed from 'dispath_interval' to 'fetcher_pause_interval'. Now accepts 0.

@darraghotoole darraghotoole force-pushed the dot/configurable_dispatch_interval branch 3 times, most recently from 252b673 to a837a71 Compare May 26, 2016 10:18
@bbaja42 bbaja42 mentioned this pull request May 26, 2016

if @fetcher_pause_interval < 0
message = "Fetcher pause interval value #{@fetcher_pause_interval} is invalid, it cannot be negative"
raise(ArgumentError, message)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to the PR: I'm wondering if we should move these ArgumentError errors to cli.rb, consequently failing in there, instead of later in the startup process. WDYT?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, moving the relevant tests would also be the first tests against cli.rb, which seems to be untested at the moment.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move that at least to the initialize method? That's where it's set.

@phstc
Copy link
Collaborator

phstc commented May 31, 2016

Looks good @darraghotoole 🍻

@mariokostelac do you mind double checking it?

@@ -12,7 +12,17 @@ class Manager

def initialize(condvar)
@count = Shoryuken.options[:concurrency] || 25
raise(ArgumentError, "Concurrency value #{@count} is invalid, it needs to be a positive number") unless @count > 0
@fetcher_pause_interval = Shoryuken.options[:fetcher_pause_interval] || 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are using two different symbols:
:dispatch_interval and :fetcher_pause_interval.
Is that on purpose? I do not see anybody reading dispatch_interval

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was missed during refactor, good catch.

@mariokostelac
Copy link
Contributor

It seems we can't set that value since we are using two different symbols.

@darraghotoole darraghotoole force-pushed the dot/configurable_dispatch_interval branch from a837a71 to f1661e8 Compare June 1, 2016 16:43
@@ -119,6 +119,10 @@ def parse_cli_args(argv)
opts[:concurrency] = Integer(arg)
end

o.on '-i', '--fetcher-pause-interval DECIMAL', 'Interval to pause fetching when all workers are busy' do |arg|
opts[:fetcher_pause_interval] = Float(arg)
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mariokostelac Fixed ^^

@mariokostelac
Copy link
Contributor

mariokostelac commented Jun 1, 2016

I've been thinking more about this one. You're solving a problem with optionally decreasing that time, but you're also introducing a problem of manager hitting the Q very often when there are no jobs. Making that value very close to 0 would mean constantly polling the Q.

I feel we can do very similar thing like I did in #215.
We are pretty sure that we can assign a new job to the worker in two situations:

  • when we just started/restarted a manager
  • when certain process is done with the work and moves from busy to ready collection, which could be when:
    • job is done
    • job crashed

We already call dispatch on start so have to do that same after updating @busy collection in processor_done and processor_died.

Using that approach you get total utilisation of your manager. You spend no time waiting for next dispatch cycle.

I am fine with adding this extra option on boot, but I'd like to make sure we are improving the code with every change.

Could we add those dispatch calls in the same PR @darraghotoole?

@phstc are you good with my approach?

@phstc
Copy link
Collaborator

phstc commented Jun 2, 2016

@phstc are you good with my approach?

@mariokostelac I'm good with it.

I am fine with adding this extra option on boot, but I'd like to make sure we are improving the code with every change.

Loved :)

@mariokostelac
Copy link
Contributor

Fix I've been talking about is merged in f4640d9.

def dispatch
return if stopped?

logger.debug { "Ready: #{@ready.size}, Busy: #{@busy.size}, Active Queues: #{unparse_queues(@queues)}" }

if @ready.empty?
logger.debug { 'Pausing fetcher, because all processors are busy' }
logger.debug { 'Pausing fetcher for #{@fetcher_pause_interval} seconds, because all processors are busy' }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Single-quoted strings are not interpolated, so the log will contain the literal text:

Pausing fetcher for #{@fetcher_pause_interval} seconds, because all processors are busy

You probably want to use double quotes here.

@eugeneius
Copy link
Contributor

This seems conceptually similar to the delay option: https://github.com/phstc/shoryuken/wiki/Shoryuken-options#delay

It's a bit inconsistent that delay can be set in the config file but not from the command line, and now this option will be settable from the command line but not in the config file.

@mariokostelac
Copy link
Contributor

@eugeneius Yes, I do not see any useful difference right now. Since we've fixed the original issue on better way, I am inclined to avoid introducing extra complexity and close this PR.
@darraghotoole @mstewart @bbaja42 thanks for raising the issue and providing a solution for that. If you think that I am wrong with closing this one, please reopen.

@darraghotoole darraghotoole deleted the dot/configurable_dispatch_interval branch June 7, 2016 08:54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants