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

[API Overuse Study] Mock endpoint that simulates a quota aware API #27158

Closed

Conversation

damondouglas
Copy link
Contributor

@damondouglas damondouglas commented Jun 16, 2023

This PR closes #27088 by creating a mock endpoint that simulates a quota aware API. The purpose of this mock endpoint is to collect data as part of the Proposal | Exploring existing Beam features to prevent web service API overuse.

See https://github.com/damondouglas/beam/tree/api-overuse-study-mock-endpoint/.test-infra/pipelines#api-overuse for an overview.

I ran the following prior to submitting this PR:
./gradlew beam-test-infra-pipelines:check

The go integration test assumes deployed resources. See https://github.com/damondouglas/beam/tree/api-overuse-study-mock-endpoint/.test-infra/pipelines#api-overuse for details.

The following lists what this PR contributes:

  • Update README with pipeline review
  • Configure service and model proto definitions
  • Configure buf.build for proto generation
  • Autogenerate go and java proto stubs
  • Implement gRPC services and cache
  • Implement Kubernetes client
  • Configure Infrastructure-as-Code for Google Cloud resources
  • Configure Infrastructure-as-Code for Kubernetes resources

Thank you for your contribution! Follow this checklist to help us incorporate your contribution quickly and easily:

  • Mention the appropriate issue in your description (for example: addresses #123), if applicable. This will automatically add a link to the pull request in the issue. If you would like the issue to automatically close on merging the pull request, comment fixes #<ISSUE NUMBER> instead.

See the Contributor Guide for more tips on how to make review process smoother.

To check the build health, please visit https://github.com/apache/beam/blob/master/.test-infra/BUILD_STATUS.md

GitHub Actions Tests Status (on master branch)

Build python source distribution and wheels
Python tests
Java tests
Go tests

See CI.md for more information about GitHub Actions CI.

- Update README with pipeline review
- Configure service and model proto definitions
- Configure buf.build for proto generation
- Autogenerate go and java proto stubs
- Implement gRPC services and cache
- Implement Kubernetes client
- Configure Infrastructure-as-Code for Google Cloud resources
- Configure Infrastructure-as-Code for Kubernetes resources
@damondouglas
Copy link
Contributor Author

damondouglas commented Jun 16, 2023

@jrmccluskey Thank you for reviewing! I will flip this PR to ready if/when checks pass. This is ready :)

@damondouglas damondouglas marked this pull request as ready for review June 17, 2023 00:30
@github-actions
Copy link
Contributor

Assigning reviewers. If you would like to opt out of this review, comment assign to next reviewer:

R: @damccorm for label build.

Available commands:

  • stop reviewer notifications - opt out of the automated review tooling
  • remind me after tests pass - tag the comment author after tests pass
  • waiting on author - shift the attention set back to the author (any comment or push by the author will return the attention set to the reviewers)

The PR bot will only process comments in the main thread (not review comments).

@damondouglas damondouglas changed the title [API Overuse Study] Mock endpoint that simulates a quota aware API. [API Overuse Study] Mock endpoint that simulates a quota aware API Jun 19, 2023
Copy link
Contributor

@jrmccluskey jrmccluskey left a comment

Choose a reason for hiding this comment

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

Okay this is the first pass on the Go files. I started to lose steam down the stretch so I held off on digging into internal/quota/service.go and the integration test file, but this should be a decent start on what I saw and questions I had.

// Variable's string value assigns the system environment variable key.
type Variable string

// Default a value to the system environment.
Copy link
Contributor

Choose a reason for hiding this comment

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

This comment isn't clear for what the method is doing

Copy link
Contributor

Choose a reason for hiding this comment

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

The method name doesn't seem to match the implementation either, since the function only sets the default IFF the variable doesn't already have a value.

Comment on lines +43 to +51
// Key returns the system environment variable key.
func (v Variable) Key() string {
return (string)(v)
}

// Value returns the system environment variable value.
func (v Variable) Value() string {
return os.Getenv((string)(v))
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: The Key-Value naming here isn't inaccurate, but it feels somewhat strained since the Variable type itself only encapsulates the string name of the environment variable.

// Default a value to the system environment.
func (v Variable) Default(value string) error {
if v.Missing() {
return os.Setenv((string)(v), value)
Copy link
Contributor

Choose a reason for hiding this comment

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

All of the (string)(v) casts should be able to be written as string(v)

return fmt.Sprintf("%s=%s", (string)(v), v.Value())
}

// Missing reports as an error listing all Variable among vars that are
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
// Missing reports as an error listing all Variable among vars that are
// Missing returns an error listing all Variable among vars that are

// Map converts a slice of Variable into a map.
// Its usage is for logging purposes.
func Map(vars ...Variable) map[string]interface{} {
result := map[string]interface{}{}
Copy link
Contributor

Choose a reason for hiding this comment

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

Usemake(map[string]any) to instantiate the map (https://gobyexample.com/maps)

any is now equivalent to interface{} and is generally preferable now.

Comment on lines +63 to +70
required = []environment.Variable{
port,
cache.Host,
namespace,
refresherImage,
}

env = environment.Map(required...)
Copy link
Contributor

Choose a reason for hiding this comment

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

same note on the varaidic

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +85 to +110
func vars(ctx context.Context) error {
redisClient := redis.NewClient(&redis.Options{
Addr: cache.Host.Value(),
})

cacheClient := (*cache.RedisCache)(redisClient)

spec.Cache = cacheClient
spec.Publisher = cacheClient

k8sClient, err := k8s.NewDefaultClient()
if err != nil {
return err
}

ns := k8sClient.Namespace(namespace.Value())
spec.JobsClient = k8sClient.Jobs(ns)

if err := redisClient.Ping(ctx).Err(); err != nil {
return err
}

logger.Info(ctx, "pinged cache host ok", logging.String("host", cache.Host.Value()))

return nil
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Same note about the function name from the echo package

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree. Thank you.

Comment on lines +103 to +107
if err := redisClient.Ping(ctx).Err(); err != nil {
return err
}

logger.Info(ctx, "pinged cache host ok", logging.String("host", cache.Host.Value()))
Copy link
Contributor

Choose a reason for hiding this comment

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

Move the liveness check for the redis client above the kubernetes client work

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will do. Thank you.

)

var (
port environment.Variable = "PORT"
Copy link
Contributor

Choose a reason for hiding this comment

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

May be worth having an extra utils package were you can stash shared environment variables like this and any common functions between the packages for ease of use and improvement

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Good point. I'll have a cmd/common package that provides these shared environment variable names.

cacheRefresher cache.Refresher
subscriber cache.Subscriber

env = logging.Any("env", environment.Map(required...))
Copy link
Contributor

Choose a reason for hiding this comment

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

Same variadic note

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please see #27158 (comment). Though in all cases I should have env = logging.Any("env", environment.Map(required...)). It's private and really only meant for re-usable debugging. When you deploy resources in Kubernetes, unless you clearly show what is missing or not configured, can be cumbersome without a consistent method to report this in the logs.

@damondouglas
Copy link
Contributor Author

As I've been using this in a Beam context, it has changed a lot and necessitates closing this PR. I will incorporate your helpful feedback in a new PR and rely on any automated assignment of a new reviewer. Thank you again!

@damondouglas damondouglas deleted the api-overuse-study-mock-endpoint branch September 25, 2024 19:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[API Overuse Study] Mock endpoint that simulates a quota aware API
2 participants