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

refactor(orc8r): Replace multi.go with hashicorp/go-multierror module #12627

Merged
merged 3 commits into from May 13, 2022

Conversation

alexzurbonsen
Copy link
Contributor

@alexzurbonsen alexzurbonsen commented May 3, 2022

Summary

This PR modifies Magma's multi error management to use the hashicorp/go-multierror module.

Formatting of multierrors changes due to the format used in the hashicorp module.
The new output looks like this:

"x errors occured:
	* error
	* error
	* error
	... \n\n"

whereas the former output was

"errors: [index: error; index: error; ...]"

where error is a string that contains the error message, and in many cases additional parts with further details abouth the error.

hashicorp/go-multierror is already used in this repo, often in conjunction with the Errorf function from github.com/pkg/errors. Since it is not longer maintained we use the standard lib fmt.Errorf in this PR. We also opened an issue to remove the pkg/errors from magma #12632.

Since now unused, we delete multi.go and respective tests. Plus grpc_to_http.go, which was already unused before.

Test Plan

  • Precommit checks in orc8r/cloud and feg/gateway./build.py -c
  • Build orc8r ./build.py --all

Additional Information

Done in pairing with @mpfirrmann.

@pull-request-size pull-request-size bot added the size/XL Denotes a Pull Request that changes 500-999 lines. label May 3, 2022
@github-actions
Copy link
Contributor

github-actions bot commented May 3, 2022

Thanks for opening a PR! 💯

A couple initial guidelines

Howto

  • Reviews. The "Reviewers" listed for this PR are the Magma maintainers who will shepherd it.
  • Checks. All required CI checks must pass before merge.
  • Merge. Once approved and passing CI checks, use the ready2merge label to indicate the maintainers can merge your PR.

More info

Please take a moment to read through the Magma project's

If this is your first Magma PR, also consider reading

@github-actions github-actions bot added component: cwf component: feg FEG-gateway related issues component: orc8r Orchestrator-related issue labels May 3, 2022
@pull-request-size pull-request-size bot added size/L Denotes a Pull Request that changes 100-499 lines. and removed size/XL Denotes a Pull Request that changes 500-999 lines. labels May 3, 2022
@github-actions
Copy link
Contributor

github-actions bot commented May 3, 2022

feg-workflow

    2 files  202 suites   38s ⏱️
371 tests 371 ✔️ 0 💤 0
385 runs  385 ✔️ 0 💤 0

Results for commit f2aa99a.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Contributor

github-actions bot commented May 3, 2022

cloud-workflow

    7 files  356 suites   2m 3s ⏱️
985 tests 985 ✔️ 0 💤 0

Results for commit f2aa99a.

♻️ This comment has been updated with latest results.

@github-actions
Copy link
Contributor

github-actions bot commented May 3, 2022

agw-workflow

     77 files     122 suites   7m 21s ⏱️
1 162 tests 1 153 ✔️ 9 💤 0
1 163 runs  1 154 ✔️ 9 💤 0

Results for commit b0dcf3a.

♻️ This comment has been updated with latest results.

@alexzurbonsen alexzurbonsen marked this pull request as ready for review May 4, 2022 11:44
@sebathomas
Copy link
Contributor

The insync-check is failing, you probably need some more go mod clean-up.

@maxhbr
Copy link
Member

maxhbr commented May 4, 2022

The pr title prefix is fairly generic and does not match best practices, maybe better would be refactor(orc8r): .

@alexzurbonsen alexzurbonsen changed the title chore: Replace multi.go with hashicorp/go-multierror module refactor(orc8r): Replace multi.go with hashicorp/go-multierror module May 4, 2022
@alexzurbonsen alexzurbonsen requested a review from maxhbr May 4, 2022 13:05
@alexzurbonsen alexzurbonsen requested a review from maxhbr May 4, 2022 16:32
Copy link
Member

@maxhbr maxhbr left a comment

Choose a reason for hiding this comment

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

LGTM

@uri200 uri200 requested a review from emakeev May 5, 2022 19:10
Copy link
Contributor

@uri200 uri200 left a comment

Choose a reason for hiding this comment

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

Why are we removing our own implementation of errors if we already have it?
Why aren't we removing hashicorp instead to avoid that module not being supported in the future? (same that happened with errors module)

Note we also try to maintain the errors in one single line. So printing them in multiple lines is something we should avoid. Otherwise debugging and parsing becomes difficult. (for example you can not use grep properly anymore and you need to look for previous lines to see the full error)

if len(sessionIDToIMSI) != 0 {
err := directoryd.MapSessionIDsToIMSIs(ctx, networkID, sessionIDToIMSI)
multiError = multiError.AddFmt(err, "failed to update directoryd mapping of session IDs to IMSIs %+v", sessionIDToIMSI)
if err != nil {
Copy link
Contributor

Choose a reason for hiding this comment

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

i know this has been mentioned below, but just as a placeholder: remove all ifs since Append will ignore nils

Copy link
Member

Choose a reason for hiding this comment

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

this contains formatting, the errors. Errorf result will still not be nil, even if err was nil.

But this 3 line block could be extracted to a function, since they just differ in a few words.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Introduced a wrapper in this file.

@@ -25,6 +25,8 @@ import (
"github.com/aeden/traceroute"
"github.com/emakeev/snowflake"
"github.com/golang/glog"
"github.com/hashicorp/go-multierror"
"github.com/pkg/errors"
Copy link
Contributor

Choose a reason for hiding this comment

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

why are we introducing an unsupported package here

#12632

Copy link
Member

Choose a reason for hiding this comment

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

The ticket #12632 was created as a result of realizing that the unsupported package was used here. I think this is for consistence but I agree that this PR should maybe also fix (parts of) #12632.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@uri200 The package is removed in the final commit of this PR, so this is not part of the changes. (The PR isn't nicely tailored for commit by commit review, sorry.)

Copy link
Contributor

Choose a reason for hiding this comment

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

The ticket #12632 was created as a result of realizing that the unsupported package was used here. I think this is for consistence but I agree that this PR should maybe also fix (parts of) #12632.

Could you please elaborate? We introduce 12627 which we are not sure, we need and then we create #12632 to fix issues that #12627 will create?

Copy link
Member

Choose a reason for hiding this comment

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

Oh, sorry, that was not formulated clear enough.

#12632 was created while working on #12627. But it will also be solved here for the touched code. So no new instances of #12632 will be introduced and the code commented here is actually fixed in a later commit, as @alexzurbonsen explained.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Cleaned up the commit history. Now all changes that replace merrors by hasicorp/go-multierror are in one commit.

@maxhbr
Copy link
Member

maxhbr commented May 6, 2022

Why aren't we removing hashicorp instead to avoid that module not being supported in the future? (same that happened with errors module)

I expect that the chances that this package is better maintained than our own library function are pretty high. It is also well tested and due to its wide usage it is also probably already known to many contributors.

Note we also try to maintain the errors in one single line.

That is a good point!

@uri200
Copy link
Contributor

uri200 commented May 10, 2022

Let's wait for @emakeev , he may have some context on multi error code.

Copy link
Contributor

@emakeev emakeev left a comment

Choose a reason for hiding this comment

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

Could you please explain what is the purpose of this change?
The usage pattern seems to be nearly identical,
the implementation already exists & in use and hasn't been problematic so far.

Is there any reason, we want to spend time of developers & reviewers to fix something which is not broken while there are so many real improvements Magma can benefit from?

If you just need to change the format of the errors' string (which also has to be justified, BTW), it could be accomplished by a small 4 lines PR vs this 400 lines PR and keep flexibility to modify the format later anytime you need/want, just change func (me *Multi) Error() string to:

func (me *Multi) Error() string {
	if me == nil {
		return "<nil>"
	}
	switch len(me.errors) {
	case 0:
		return ""
	case 1:
		return me.errors[0].Error()
	default:
		var b bytes.Buffer
		fmt.Fprintf(&b, "%d errors occurred:\n", len(me.errors))
		fmtStr := "\t* %v\n"
		for _, e := range me.errors {
			fmt.Fprintf(&b, fmtStr, e)
		}
		b.Write([]byte("\n"))
		return b.String()
	}
}

--- a/orc8r/lib/go/merrors/multi.go
+++ b/orc8r/lib/go/merrors/multi.go
@@ -41,12 +41,12 @@ func (me *Multi) Error() string {
                return me.errors[0].Error()
        default:
                var b bytes.Buffer
-               fmtStr := "errors: [%d: %v"
-               for i, e := range me.errors {
-                       fmt.Fprintf(&b, fmtStr, i, e)
-                       fmtStr = "; %d: %v"
+               fmt.Fprintf(&b, "%d errors occurred:\n", len(me.errors))
+               fmtStr := "\t* %v\n"
+               for _, e := range me.errors {
+                       fmt.Fprintf(&b, fmtStr, e)
                }
-               b.Write([]byte("]"))
+               b.Write([]byte("\n"))
                return b.String()
        }
 }

or something like this...

@emakeev
Copy link
Contributor

emakeev commented May 10, 2022

I expect that the chances that this package is better maintained than our own library function are pretty high. It is also well tested and due to its wide usage it is also probably already known to many contributors.

note that it also applies to the rest of Magma codebase (merror is maintained as well as the rest of Magma code), the original implementation is simple, controlled by us, allows us to format multi errors ANY way we want or need, now and in the future and it relies only on std Go packages.
But - the bigger question is - why fix something which is not broken? What's the incentive to do it?

@maxhbr
Copy link
Member

maxhbr commented May 11, 2022

Hey @emakeev,

Thank you for your comments.

There are right now two implementations of multierrors used in Magma:

  • our own implementation, used in 5 files and
  • the hashicorp one, used in 12 files.

We saw an opportunity to clean up the source code and decided to go for the more commonly used one. The hashicorp library is also widely known, better documented and might rely less on tribal knowledge. Migrating to that also preserves the possibility to add arbitrary ErrorFormat formatters and drops ~300 lines of source code we needed to maintain.

Regarding the formatting change:
Since more often than not, the code already uses the default hashicorp formatting with multiline error messages, we think that this would make it at least more consistent.

@emakeev
Copy link
Contributor

emakeev commented May 12, 2022

Hey @emakeev,

Thank you for your comments.

There are right now two implementations of multierrors used in Magma:

  • our own implementation, used in 5 files and
  • the hashicorp one, used in 12 files.

We saw an opportunity to clean up the source code and decided to go for the more commonly used one. The hashicorp library is also widely known, better documented and might rely less on tribal knowledge. Migrating to that also preserves the possibility to add arbitrary ErrorFormat formatters and drops ~300 lines of source code we needed to maintain.

Regarding the formatting change: Since more often than not, the code already uses the default hashicorp formatting with multiline error messages, we think that this would make it at least more consistent.

Sure, it seems to be reasonable to settle on a single implementation & since the work is already done, I don't see an issue w it. I'll leave it to @uri200 to decide if the change to multi line format is acceptable for FeG.

@uri200
Copy link
Contributor

uri200 commented May 13, 2022

you need to fix the insych issue
Maybe you just need to run ./build.py -g

@uri200 uri200 enabled auto-merge (squash) May 13, 2022 03:56
remove grpc_to_http.go because it is unused

Signed-off-by: Alexander zur Bonsen <alexander.zur.bonsen@tngtech.com>

deleted multi_error_test.go

Signed-off-by: Marco Pfirrmann <marco.pfirrmann@tngtech.com>

remove multi.go

Signed-off-by: Alexander zur Bonsen <alexander.zur.bonsen@tngtech.com>
@alexzurbonsen alexzurbonsen force-pushed the multierror branch 2 times, most recently from 0cecb84 to 200c71d Compare May 13, 2022 08:20
Author: Marco Pfirrmann <marco.pfirrmann@tngtech.com>
Signed-off-by: Marco Pfirrmann <marco.pfirrmann@tngtech.com>

changed merrors.Multi to multierrors.Error

Signed-off-by: Marco Pfirrmann <marco.pfirrmann@tngtech.com>

certifier.go: changed merrors package to hashicorp/multierrors

Signed-off-by: Marco Pfirrmann <marco.pfirrmann@tngtech.com>

introduce missing null checks

Signed-off-by: Alexander zur Bonsen <alexander.zur.bonsen@tngtech.com>

renaming multiError variables for better readability

Signed-off-by: Marco Pfirrmann <marco.pfirrmann@tngtech.com>

multierror.Append is assigned to the errs variable

Signed-off-by: Marco Pfirrmann <marco.pfirrmann@tngtech.com>

remove pkg/errors package from this PR and use std lib

Signed-off-by: Alexander zur Bonsen <alexander.zur.bonsen@tngtech.com>

include nil check in wrapper in indexer_servicer.go

signed-off-by: Marco Pfirrmann <marco.pfirrmann@tngtech.com>
Signed-off-by: Alexander zur Bonsen <alexander.zur.bonsen@tngtech.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component: cwf component: feg FEG-gateway related issues component: orc8r Orchestrator-related issue size/L Denotes a Pull Request that changes 100-499 lines.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants