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

using dedicated HTTP clients #1251

Merged
merged 11 commits into from
Dec 18, 2020
Merged

using dedicated HTTP clients #1251

merged 11 commits into from
Dec 18, 2020

Conversation

arschles
Copy link
Contributor

@arschles arschles commented Oct 13, 2020

This attempts to use a dedicated, global HTTP client with a configurable global timeout for all scalers that do HTTP operations. This is a draft PR for now, but I'll update the docs too if the direction is acceptable.

Checklist

Relates to #1133

Much of this was done with the help of @iennae

@zroubalik
Copy link
Member

@aman-bansal PTAL^

@aman-bansal
Copy link
Contributor

Sure I will take a look by EOD

@@ -42,7 +44,7 @@ type azureBlobMetadata struct {
var azureBlobLog = logf.Log.WithName("azure_blob_scaler")

// NewAzureBlobScaler creates a new azureBlobScaler
func NewAzureBlobScaler(config *ScalerConfig) (Scaler, error) {
func NewAzureBlobScaler(httpClient *http.Client, config *ScalerConfig) (Scaler, error) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Changing the contract for creating a new scaler seems unnecessary. I very much like the recent changes where we simplified the creation of a scaler object with ScalerConfig. It's a cleaner approach.

adapter/main.go Outdated
@@ -106,9 +107,13 @@ func main() {
cmd.Flags().AddGoFlagSet(flag.CommandLine) // make sure we get the klog flags
cmd.Flags().IntVar(&prometheusMetricsPort, "metrics-port", 9022, "Set the port to expose prometheus metrics")
cmd.Flags().StringVar(&prometheusMetricsPath, "metrics-path", "/metrics", "Set the path for the prometheus metrics endpoint")

var globalHTTPTimeoutMS int
cmd.Flags().IntVar(&globalHTTPTimeoutMS, "http-timeout", 300, "The default timeout of all HTTP requests (unless you explicitly set it otherwise)")
Copy link
Contributor

@aman-bansal aman-bansal Oct 16, 2020

Choose a reason for hiding this comment

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

I don't think http-timeout is a critical parameter. It shouldn't be part of command flags.

I guess having something of say 3 sec as constant is fine. If a client wants to specify a different timeout he can simply add it to trigger metadata of config. It seems neat to me.

@zroubalik @turbaszek do you have any thoughts in this regard?

Copy link
Member

@zroubalik zroubalik Oct 19, 2020

Choose a reason for hiding this comment

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

I am not 100% against this, but on the other hand, I can see your point. I honestly don't have a strict opinion on this 🤷‍♂️ I am open to hear others' ideas.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My thought process was that this would give a single timeout for all triggers. Would you rather go with a per-trigger timeout?

Copy link
Contributor

Choose a reason for hiding this comment

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

okay here are the possible solutions I see. I might be missing few things so do let me know if I am wrong anywhere.

How I view keda is something like this, we start keda with few flags that manages the state of keda operators and keda metric server. Each scaler manages its own state based on trigger metadata(including auth meta). I don't see any information that passes from keda to scalers as such. ScalerConfig is the example of that. Scaler config is just basic name and metadata information. Keda manages which scaler to run, after that each scaler is independent.

Now with this issue what we are trying is pass some control parameters to each scaler, and that's where the problem is we don't have any implementation regarding this (atleast i don't see anything).

So I see three different solutions for this:

  1. Introduce global variable. Though I don't see any global variables in the code right now. This would introduce complexity while testing and all the know drawbacks of global variables.

  2. Expand Scaler Config to have some parameters of Keda. This will help to extend more control parameters that might needed in future. But this is increasing the scope. I don't think this issue needs that much of rework. But yes something to think of and maybe build use cases around this.

  3. Introduce a new env variable. We will pick it from the env variable. This is easy, neat and std industry practice. We could have something like this KEDA_HTTP_DEFAULT_TIMEOUT. This will do the trick.

@zroubalik @arschles What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Apologies for the delay, I had to give a talk yesterday.

@aman-bansal I agree regarding 1, so I would vote against that personally.

I think I'm on the same page as you regarding 2 and 3. Assuming we have a global timeout variable that you pass into KEDA when you start it up, you could also allow people to override that on a per-trigger basis by passing a timeout in the manifest you submit.

Specific to 3, I'm happy to change it to read from an environment variable rather than a flag. Let me know

Copy link
Member

Choose a reason for hiding this comment

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

I like the environment variable approach as well.

@arschles
Copy link
Contributor Author

@aman-bansal @zroubalik I commited a change for both reading the timeout from an env var and also putting the HTTP client into the ScalerConfig (instead of changing the signatures for each scaler constructor).

One question that I still have is, in the Metrics API scaler, how should we configure the TLS transport? Currently, I have a TODO on it because if you configure it in the constructor, you'd be setting it on the global HTTP client. See https://github.com/kedacore/keda/pull/1251/files#diff-c832e36c124014f31496fdbc15f77397f48b73855a7b7441fd95525ed6112f54R82

@zroubalik
Copy link
Member

@arschles I think that we should expose the env variable in Deployment yaml file (bc Helm chart is not the only installation method).

Sorry I missed the TLS transport question, do you have any particular solution in mind?

@zroubalik zroubalik changed the base branch from v2 to main October 30, 2020 13:23
@aman-bansal
Copy link
Contributor

I don't think we can do this. TLS config is something which is scaler specific. It needs to be manager per scaler basis. One single http.Client can't handle multiple TLS configs.
How about this for an approach:
Just like pkg/scaling/resolver/scale_resolvers.go:110#resolveEnv resolves env variables for a container and add it to the scaler config, entertain one more case where env variable is read from keda container. It will become part of scaler config. Now for every scaler you have this information available. Not just initialise each client per scaler.

@arschles
Copy link
Contributor Author

arschles commented Nov 6, 2020

@aman-bansal the metrics API scaler was the only one I saw that needs to specify its own TLS config (see my comment in that file) - would it make sense to make that a special case for now, instead of creating a client per scaler? I'm happy to do either, but the connection pooling across scalers could be beneficial. I'm not familiar with common workloads for KEDA, so I'll let you all decide whether that is truly beneficial

@aman-bansal
Copy link
Contributor

currently we have tls support in metric api scaler and kafka scaler. There is one open PR for rabbit mq scaler.

@arschles
Copy link
Contributor Author

@aman-bansal got it. I'll change this to create one client per scaler like you said then.

@arschles
Copy link
Contributor Author

arschles commented Nov 13, 2020

@aman-bansal I've updated to create a new HTTP client for each scaler, instead of sharing one across them all. PTAL 😄

Also, I saw that there's a TODO item in the OP to update the documentation. Where should I update? I saw the deployment section, does it make sense to do it there?

Finally, for the changelog TODO item, where should I update in that file? The latest release, v2.0.0 is already released

@arschles
Copy link
Contributor Author

Corresponding helm chart update: kedacore/charts#90

@arschles
Copy link
Contributor Author

Just fixed all the golang-ci checks. Looks like tests are broken on a context deadline exceeded error, but I cannot repro locally. am I not setting something up locally to be able to talk to rabbit?

pkg/scalers/http_clients.go Outdated Show resolved Hide resolved
pkg/scalers/metrics_api_scaler.go Outdated Show resolved Hide resolved
@zroubalik
Copy link
Member

Just fixed all the golang-ci checks. Looks like tests are broken on a context deadline exceeded error, but I cannot repro locally. am I not setting something up locally to be able to talk to rabbit?

That was just some intermittent failure caused by the environment, I've rescheduled the checks and it is passing now.

@zroubalik
Copy link
Member

Could you please update Changelog as well?

@arschles
Copy link
Contributor Author

@zroubalik I've been busy working on the HTTP scaling stuff but I haven't forgotten about this. I am going to be on vacation for the rest of the week and I'll get back to this early next.

@arschles
Copy link
Contributor Author

arschles commented Nov 30, 2020

@zroubalik ok, just made all the changes you requested and resolved conflicts. PTAL

Edit: I forgot to sign a commit and then messed up rebasing, so now this PR is a mess. sorry - I'll either figure out how to fix or re-open

@arschles
Copy link
Contributor Author

arschles commented Dec 1, 2020

@zroubalik alright, I had time to give this my full attention and it should be fixed up now (I foolishly didn't rebase the first time 😦). PTAL

fixes kedacore#1133

Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
arschles and others added 7 commits December 4, 2020 12:22
Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
@zroubalik
Copy link
Member

zroubalik commented Dec 7, 2020

@arschles one more small rebase and fixing the static check and I think we are good to merge! Thanks 👍

We should document the KEDA_HTTP_DEFAULT_TIMEOUT env variable somewhere though, I am thinking about this section: https://keda.sh/docs/2.0/operate/ WDYT @tomkerkhove ?

@tomkerkhove
Copy link
Member

We should document the KEDA_HTTP_DEFAULT_TIMEOUT env variable somewhere though, I am thinking about this section: keda.sh/docs/2.0/operate WDYT @tomkerkhove ?

Sounds like a good spot to me indeed!

@arschles
Copy link
Contributor Author

arschles commented Dec 9, 2020

Great, I'll fix this up today and add to the docs. Thanks @zroubalik @tomkerkhove 😄

arschles and others added 2 commits December 9, 2020 11:28
Cannot call os.Exit(1) because it prevents the klog.Flush defer

Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
@zroubalik
Copy link
Member

Looking good! let's merge this once the docs are out :)

arschles added a commit to arschles/keda-docs that referenced this pull request Dec 10, 2020
kedacore/keda#1251

Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
@arschles
Copy link
Contributor Author

@zroubalik @tomkerkhove see kedacore/keda-docs#324 for the docs PR

Copy link
Member

@zroubalik zroubalik left a comment

Choose a reason for hiding this comment

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

LGTM, thanks a lot @arschles for this!

@zroubalik zroubalik merged commit e05fb91 into kedacore:main Dec 18, 2020
@zroubalik zroubalik mentioned this pull request Jan 4, 2021
4 tasks
zroubalik pushed a commit to kedacore/keda-docs that referenced this pull request Jan 19, 2021
* adding docs for the httpclient PR
kedacore/keda#1251

Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
@arschles arschles deleted the httpclient branch February 8, 2021 21:35
ycabrer pushed a commit to ycabrer/keda that referenced this pull request Mar 1, 2021
Signed-off-by: Aaron Schlesinger <aaron@ecomaz.net>
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