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(api): Loader interface #459

Merged
merged 11 commits into from
Jan 4, 2021
Merged

refactor(api): Loader interface #459

merged 11 commits into from
Jan 4, 2021

Conversation

sh0rez
Copy link
Member

@sh0rez sh0rez commented Dec 31, 2020

I took a chance at refactoring the code in pkg/tanka/parse.go, which was modified a lot recently. These modifications revealed problems with my original design, which led to poor readability and a tangled control flow.

To address this, this PR strictly separates inline from static (spec.json) parsing. IMO this is far more readable.

It is quite likely I missed some edge-cases, @Duologic is probably able to point at these.

@sh0rez sh0rez added the kind/enhancement Improve something existing label Dec 31, 2020
@Duologic
Copy link
Member

I don't mind seeing a refactoring here, but I have quite an extensive PR that will get affected if this gets merged first. Can we review and merge mine first and then come up with this API rewrite?

@sh0rez
Copy link
Member Author

sh0rez commented Dec 31, 2020

Can we review and merge mine first and then come up with this API rewrite?

Depends on your PR 😛. One of us is going to re-do some work, which sucks, so we should consider both PR's. This is a long overdue topic, and I bet whatever you wish to add becomes simpler when the refactoring happens beforehand ;)

@Duologic
Copy link
Member

It is not very nice to put the burden on me.

@malcolmholmes
Copy link
Contributor

@Duologic can you share your PR here? Isnt it best to review which side will require less work and go that way?

@Duologic
Copy link
Member

#450

@Duologic
Copy link
Member

That PR has been through reviews already, I figured it was the lack of time on the other side that was holding it up, but apparently a rewrite of the API was going on.

@sh0rez
Copy link
Member Author

sh0rez commented Dec 31, 2020

It is not very nice to put the burden on me.

I think I made it pretty clear I merely asked you to show me the other PR, so we can review which side requires less rebasing. You gave me zero information on your PR, so this was all I could do at the time.

To not escalate this further, we will go ahead with yours first.

@sh0rez sh0rez added the lifecycle/blocked Blocked by outstanding changes (to another project) label Dec 31, 2020
Copy link
Contributor

@jvrplmlmn jvrplmlmn left a comment

Choose a reason for hiding this comment

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

Nice! This definitely removes some cognitive overload when navigating the codebase 👍

Feel free to ping me after the conflicts have been resolved 😃

pkg/tanka/static.go Outdated Show resolved Hide resolved
pkg/tanka/static.go Outdated Show resolved Hide resolved
pkg/tanka/load.go Outdated Show resolved Hide resolved
pkg/jsonnet/jpath/dirs.go Outdated Show resolved Hide resolved
pkg/tanka/parse_test.go Show resolved Hide resolved
pkg/tanka/evaluators.go Outdated Show resolved Hide resolved
@sh0rez sh0rez removed the lifecycle/blocked Blocked by outstanding changes (to another project) label Dec 31, 2020
@sh0rez
Copy link
Member Author

sh0rez commented Dec 31, 2020

Rebased. @Duologic @jvrplmlmn PTAL

Copy link
Member

@Duologic Duologic left a comment

Choose a reason for hiding this comment

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

Great rewrite of the API.

Except for the performance impact on the export function, all looks good.

cmd/tk/main.go Outdated Show resolved Hide resolved
pkg/process/process.go Outdated Show resolved Hide resolved
Comment on lines -58 to -61
envs, err := ParseParallel(paths, opts.ParseParallelOpts)
if err != nil {
return err
}
Copy link
Member

@Duologic Duologic Jan 2, 2021

Choose a reason for hiding this comment

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

This loads the environments in parallel, taking it away will have a performance impact. A quick local test run turned out it took ~1m40s to export Grafana's environments, while on master it takes ~40s.

Copy link
Member

Choose a reason for hiding this comment

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

I can cover this in a PR working towards multiple inline environments.

Comment on lines +58 to +64
// TODO: Re-serializing the entire env here. This is horribly inefficient
envData, err := json.Marshal(envs[0])
if err != nil {
return nil, err
}

env, err := spec.Parse(envData, name)
Copy link
Member

Choose a reason for hiding this comment

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

We could change spec.Parse to expect a manifest.Manifest object?

Copy link
Member Author

Choose a reason for hiding this comment

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

I fear that is actually not as easy as it sounds.

The whole reason we use the json re-serialization is to do a deep copy of the underlying data, which is highly tricky in Go otherwise due to pointer types, etc. The resulting v1alpha1.Environment must not be affected by future changes to the original manifest.Manifest.

I'd say we first benchmark how bad this actually is, it might be easily outweighed by an order of magnitude by the Jsonnet compiler, so this might not matter at all

pkg/tanka/load_test.go Outdated Show resolved Hide resolved
Comment on lines -17 to -36
baseDir: "./testdata/cases/array/",
expected: []interface{}{
[]interface{}{
map[string]interface{}{"testCase": "nestedArray[0][0]"},
map[string]interface{}{"testCase": "nestedArray[0][1]"},
},
[]interface{}{
map[string]interface{}{"testCase": "nestedArray[1][0]"},
map[string]interface{}{"testCase": "nestedArray[1][1]"},
},
},
env: nil,
},
{
baseDir: "./testdata/cases/object/",
expected: map[string]interface{}{
"testCase": "object",
},
env: nil,
},
Copy link
Member

Choose a reason for hiding this comment

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

These could move to a unit test for EvalJsonnet().

return nil, err
}

config, err := parseStaticSpec(root, base)
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
config, err := parseStaticSpec(root, base)
env, err := parseStaticSpec(root, base)

Copy link
Member

@Duologic Duologic left a comment

Choose a reason for hiding this comment

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

Just had another look at my comments, I think we can merge this and work in a follow up. I've got something in the pipeline for multiple inline environments.

@sh0rez sh0rez merged commit 21bdb9e into master Jan 4, 2021
@sh0rez sh0rez deleted the loaders branch January 4, 2021 14:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement Improve something existing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants