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

🫶 Add new SetGoMemLimitWithOptions #9

Closed
wants to merge 4 commits into from

Conversation

mirecl
Copy link
Contributor

@mirecl mirecl commented Jul 6, 2023

✅ Add configure options for SetGoMemLimitWithEnv:

❗For example:

logger, _ := zap.NewProduction()
sugar := logger.Sugar()

memlimit.SetGoMemLimitWithOptions(
   memlimit.WithLogger(sugar.Debugf), // default: `log.Printf`
   memlimit.WithProvider(memlimit.FromCgroupV1), // default: `memlimit.FromCgroup`
   memlimit.WithRatio(.8), // default: `0.9`
   memlimit.WithEnv(), // default: `false`
)

P.S. I am confident that this commit will be beneficial for the community.

@mirecl
Copy link
Contributor Author

mirecl commented Jul 6, 2023

@KimMachineGun, what do you think about it?

Copy link
Owner

@KimMachineGun KimMachineGun left a comment

Choose a reason for hiding this comment

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

Thank you for your contribution.
The idea seems great!

memlimit/memlimit.go Outdated Show resolved Hide resolved
memlimit/memlimit.go Outdated Show resolved Hide resolved
Comment on lines 48 to 54
// WithLogger uses the supplied printf implementation for log output.
// By default log.Printf.
func WithLogger(printf func(string, ...interface{})) Option {
return optionFunc(func(cfg *config) {
cfg.printf = printf
})
}
Copy link
Owner

Choose a reason for hiding this comment

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

The logging patterns will be changed after the Go 1.21 release to use the log/slog package. (Go 1.21 is expected to be released in August.)

What about separating the logger part to another PR and re-visiting after the Go 1.21 release?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@KimMachineGun, now there is no way to manage logging outside the library and by default the log package is used. In the new function SetGoMemLimitWithOptions, I propose to give the user the opportunity to use
your logger (e.g. zap)

Copy link
Owner

Choose a reason for hiding this comment

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

I think the printf style logger is not as customizable as slog.Logger. slog.Logger can even handle log level and logging style (in a structured way such as json, key-value style, etc) as well.

So I want to reserve the name WithLogger for slog.Logger and avoid adding new API (even in another name) likely to be deprecated soon (after Go 1.21).

Would slog.Logger not be sufficient to qualify your needs?

memlimit/memlimit.go Outdated Show resolved Hide resolved
@mirecl
Copy link
Contributor Author

mirecl commented Jul 10, 2023

@KimMachineGun, ✅
I propose to include these improvements in v0.3.0

@mirecl mirecl changed the title 🫶 Add configure SetGoMemLimitWithEnv 🫶 Add new SetGoMemLimitWithOptions Jul 10, 2023
@mirecl mirecl requested a review from KimMachineGun July 10, 2023 13:45
@mirecl
Copy link
Contributor Author

mirecl commented Jul 14, 2023

@KimMachineGun ,what do you think about it?

Comment on lines +51 to +65
// WithRatio configure memory limit.
// By default `defaultAUTOMEMLIMIT`.
func WithRatio(ratio float64) Option {
return Option(func(cfg *config) {
cfg.ratio = ratio
})
}

// WithEnv configure memory limit from environment variable.
// By default `false`.
func WithEnv() Option {
return Option(func(cfg *config) {
cfg.env = true
})
}
Copy link
Owner

Choose a reason for hiding this comment

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

It seems like WithRatio and WithEnv work exclusively for each other.
What about not adding WithEnv and using the environment variable if WithRatio is not used?
(i.e. using the environment variable by default, and if the ratio is provided, using it instead.)

@KimMachineGun
Copy link
Owner

@mirecl
I apologize for the delayed review. I've been quite occupied these days 🥲.

@t-e-s-tweb
Copy link

Actually this is my question. Can I use the whole example code as it is? are these options chosen in some preference or do i have to only set one type of variable?

@KimMachineGun
Copy link
Owner

@t-e-s-tweb
Yes, this PR will not change(or remove) any public API exported before, so you can use the whole example code as it is.
And also, since I care about backward compatibility significantly, breaking change is unlikely to happen before the next major version.

@KimMachineGun
Copy link
Owner

@mirecl
Hi mirecl, Go 1.21 is finally released. Can we resume this pr?

@t-e-s-tweb
Copy link

quick question, if all the options are imported in go file, then how do they take priority over one another or should only one be used at a time? e.g using env, hardlimit by ram, by ratio or by cgroups? if all are added then which is applied? is there any way to check the currently applied limit?

@KimMachineGun
Copy link
Owner

@t-e-s-tweb
If I understand your question correctly, since the ratio and the provider are different concepts in automemlimit, basically no priority is there.
And you can check the current value of GOMEMLIMIT through debug.SetMemoryLimit(-1).

Below is a simplified version of the automemlimit process.

  1. Get the ratio that specifies the portion of memory that will be used as GOMEMLIMIT.
  • The default ratio is 0.9.
  • You can configure it with SetGoMemLimitWithOptions + WithRatio.
  • If you use SetGoMemLimitWithEnv or SetGoMemLimitWithOptions + WithEnv, you can overwrite the ratio at the application initialization time with the environment variable.
  1. Get the total memory size from the provider.
  • The default provider is FromCgroup. (support all cgroups versions)
  • You can configure it with SetGoMemLimitWithOptions + WithProvider.
  1. Apply the memory limit (total memory size * ratio).

@KimMachineGun
Copy link
Owner

I forked it to a new PR for the fast follow-up for Go 1.21.
Thank you again, @mirecl!

@t-e-s-tweb
Copy link

while using

func init() {
	// Configure memory limit with options
	memlimit.SetGoMemLimitWithOptions(
		memlimit.WithEnv(),          // Configure memory limit from environment variable
		memlimit.WithRatio(0.9),     // Set the memory limit ratio
		memlimit.WithProvider(memlimit.FromCgroupV2), // Use the FromCgroupV2 provider
	)

	// And so on...
}

i get

./main.go:13:11: undefined: memlimit.SetGoMemLimitWithOpts
./main.go:14:12: undefined: memlimit.WithEnv
./main.go:15:12: undefined: memlimit.WithRatio
./main.go:16:12: undefined: memlimit.WithProvider

@mirecl
Copy link
Contributor Author

mirecl commented Aug 19, 2023

@KimMachineGun, most likely need a new release (tag).

@KimMachineGun
Copy link
Owner

@mirecl
This change will be released after a few days of testing.
I'll let you know when it is released.

@KimMachineGun
Copy link
Owner

@mirecl
This change was released as v0.3.0!

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.

3 participants