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

Major rewrite using Generics #51

Merged
merged 3 commits into from
Aug 7, 2022
Merged

Major rewrite using Generics #51

merged 3 commits into from
Aug 7, 2022

Conversation

ccremer
Copy link
Owner

@ccremer ccremer commented Aug 2, 2022

Summary

This PR completely rewrites the library to make use of generics.
One of problems of this pipeline of this sort is how to access or "pass" data through the pipeline, possibly with intermediate data that get added throughout the steps while executing them.
One approach is to have them in the context.Context that is passed through every function. However, native contexts are not only read-only, they are also cumbersome to use since they're so generic by using a key-value store. Users of the context approach would need to create structs or other identifiers as keys, and use pipeline.MutableContext to get a context that allows creating new entries or updating them.

Generics (as introduced in Go 1.18) can eliminate this problem. The context passed through the steps is now extensible. If every step is an instance of T, then users can come up with their own implementation of context.Context and this allows a type-safe access to read and write intermediate values in the steps.

The new usage looks roughly as following:

type MyType struct {
  context.Context
  MyCustomField string
}

p := pipeline.NewPipeline[*MyType]()
p.WithSteps(
  p.NewStep("step name", func(ctx *MyType) error {
    fmt.Println(ctx.MyCustomField)
    return nil
  }))
p.RunWithContext(&MyType{Context: context.Background()})

A number of other breaking changes are as following:

  • Pipeline.Run() is removed, use Pipeline.RunWithContext() instead
  • NewStepFromFunc() is renamed to NewStep(), the old signature of NewStep is gone.
  • Step.F renamed to Step.Action.
  • Step.WithResultHandler() is removed, use Step.WithErrorHandler() instead
  • Step.Handler is now always called if set, independent of the step's error return value. Users should now check for non-nil errors in their error handlers.
  • Result is now a custom type that implements the error interface. Users can now check if this is non-nil and use errors.As to get additional information about the step that threw the error.
  • Pipeline.AddBeforeHook() removed, use Pipeline.WithBeforeHooks() instead
  • NewAnonymous() is removed. I don't think there's really a use case for it.
  • Pipeline.WithOptions() now accepts a struct pipeline.Options with simple fields instead of function pointers, to avoid "generify" these functions as well

(there may be more I lost track of)

Checklist

  • Categorize the PR by setting a good title and adding one of the labels:
    fix, enhancement, documentation, change, breaking, dependency
    as they show up in the changelog
  • Update documentation.
  • Update tests.
  • Link this PR to related issues.

This makes it easier to handle options, as the options are not depending on generic T
@ccremer ccremer marked this pull request as ready for review August 7, 2022 14:34
@ccremer ccremer merged commit 36a394e into master Aug 7, 2022
@ccremer ccremer deleted the generic branch August 7, 2022 14:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant