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

Create an option to stop ignoring weights. By default weights will still be ignored. #174

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

minkovich
Copy link

This commit is based on the following by @bobtfish
#131

but does the following things differently:

  1. By default weights are ignored. This is to maintain current behavior for safety.
  2. HAProxy will reconfigure if weights changes.

be ignored. This commit is based on:
airbnb#131

but does the following things differently:
1. By default weights are ignored. This is to maintain current behavior
for safety.
2. HAProxy will reconfigure if weights changes.
@@ -741,6 +742,10 @@ def generate_backend_stanza(watcher, config)
backend = backends[backend_name]
b = "\tserver #{backend_name} #{backend['host']}:#{backend['port']}"
b = "#{b} cookie #{backend_name}" unless config.include?('mode tcp')
if !@opts['ignore_weights'] && backend.has_key?('weight')
weight = backend['weight'].to_i
b = "#{b} weight #{weight}"
Copy link
Collaborator

Choose a reason for hiding this comment

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

So I believe that HAProxy will use the last weight provided. If that's true I think this should probably slot this in between the HAProxy backend server_options and the server haproxy_server_options level.

Copy link
Collaborator

Choose a reason for hiding this comment

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

or maybe we should bail of server options also contains weight? i don't have a strong feeling as to what the precedence order should be... at least printing a warning to logs when there are contradictory options seems like a good idea.

this is probably indicating that it's time to refactor this function, it's getting pretty big.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yea, I noted a similar concern about complexity in #171. I'm not sure if these PRs are the right place for that though or if we should refactor it once they're merged.

I agree printing a warning is useful, but I don't think we should bail out as I can understand use cases where someone might want to set some combination as a fallback scheme. weight and haproxy_server_options come from the registration side and server_options come from the discovery side. I can understand a situation where one side might have information the other does not.

Copy link
Author

Choose a reason for hiding this comment

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

@igor47 and @jolynch, let me move these lines and add a warning when a conflict is detected.

…s from taking traffic just because they have different weights, add more tests.
if !@opts['ignore_weights'] && backend.has_key?('weight')
# Check if server_options already contains weight, is so log a warning
if watcher.haproxy['server_options'].include? 'weight'
log.info "synapse: weight is defined by server_options and by nerve"
Copy link
Contributor

Choose a reason for hiding this comment

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

log.warn (nit)

@@ -742,6 +742,14 @@ def generate_backend_stanza(watcher, config)
b = "\tserver #{backend_name} #{backend['host']}:#{backend['port']}"
b = "#{b} cookie #{backend_name}" unless config.include?('mode tcp')
b = "#{b} #{watcher.haproxy['server_options']}" if watcher.haproxy['server_options']
if backend.has_key?('weight')
# Check if server_options already contains weight, is so log a warning
if watcher.haproxy['server_options'].include? 'weight'
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the backend (server) provided haproxy_server_options data is a more concerning conflict than server_options (a weight in the server_options would be like a default for servers or something).

Copy link
Author

Choose a reason for hiding this comment

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

@jolynch, that's a good point. To reduce the number of iteration for this PR, could you suggest what message you'd like to see when haproxy_server_options also includes weight?

@jolynch
Copy link
Collaborator

jolynch commented Feb 24, 2016

I'm not clear on how we know to restart without something like line 715?

@minkovich
Copy link
Author

@jolynch

I'm not clear on how we know to restart without something like line 715?

Doesn't the new unit test in spec/lib/synapse/service_watcher_base_spec.rb show that reconfigure will be called when weights change? Doesn't that imply that HAProxy will be reconfigured? Am I missing something?

@jolynch
Copy link
Collaborator

jolynch commented Feb 26, 2016

@minkovich Sorry I should have been more clear. A watcher calling set_backends is necessary but not sufficient to determine a restart is needed (I believe your unit tests test that set_backend/reconfigure are called). Restarting has to be done via notification (by setting to True) on the @restart_required variable after interrogating the local HAProxy to ensure that the state that Synapse has (via set_backends) matches what is in the running HAProxy which may or may not be what is in the configuration file because of stats socket updates.

The typical update ordering is set_backends -> reconfigure -> haproxy.update_config -> haproxy.update_backends (which may or may not set @restart_required). There are also a few short cuts where we just set @restart_required directly (like the haproxy_server_options handling code).

Basically Synapse is juggling three state stores and trying to keep them consistent. It's trying to watch the registry (zk), reflect that state internally (synapse) and then ensure that this state is consistent with the routing component (haproxy). I think your change reflects the changes from zk -> synapse, but I don't see how it reflects them from synapse to haproxy.

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.

4 participants