-
Notifications
You must be signed in to change notification settings - Fork 249
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
feat(sdk/go): Refactor the key/value Go SDK to be more idiomatic #1845
Conversation
adamreese
commented
Oct 3, 2023
- Introduces a client struct responsible for handling the connection
- Remove exposed C types
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A reminder to track or line up updates to examples/docs in https://github.com/fermyon/developer on/around the 2.0 release.
a8c95a9
to
1233330
Compare
1233330
to
f5fa85a
Compare
I have a concern with releasing this with 2.0. The Go SDK will continue to target the old Spin 1.0 world with the release of Spin 2.0. However, we will soon want the Go SDK to target the 2.0 world. This will require additional breaking changes to the Spin SDK to make work. This leads to a versioning challenge - if we release Go SDK 2.0 with these changes, we will then want to release Go SDK 3.0 with the changes need to target Spin 2.0's new world. This leads to the SDK and Spin's version drifting. |
Can we make the Go interface compatible with the new world, "adapting" to the old world? Update: Taking a closer look, I think this is entirely plausible with the implementation in this PR. I would say that translating the new world's use of |
return errors.New("store table full") | ||
case 1: | ||
return errors.New("no such store") | ||
case 2: | ||
return errors.New("access denied") | ||
case 3: | ||
return errors.New("invalid store") | ||
case 4: | ||
return errors.New("no such key") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These should be exported Err*
constants so that callers can distinguish between error types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was going to include that in a separate PR to make all the SDK's consistent. I wasn't sure yet if a custom error type would be the way to go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, that's fine. As a general approach I would probably do something like:
// Named const for payload-less variants
var ErrAccessDenied = errors.New("access denied")
// Error type for most payload-ful variants (not KV)
type ImaginaryError string
// Anonymous errors for `other(string)` variants
errors.New(otherString)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about something like...
type Error struct {
Code int
Message string
}
Stdlib example https://github.com/golang/go/blob/master/src/net/textproto/textproto.go#L35
But it's still a little awkward because Code is an internal value that has no real meaning to the user
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It depends on whether we care more about trying to closely match the WIT or trying to write a "idiomatic" Go lib I think. For the latter I would say separate var Err*
s for no-payloads and type *Error
s for yes-payloads most closely matches the ecosystem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Taking protobuf
as an example:
no-payload:
https://pkg.go.dev/github.com/golang/protobuf/proto#pkg-variables
yes-payload:
https://pkg.go.dev/github.com/golang/protobuf/proto#ParseError
https://pkg.go.dev/github.com/golang/protobuf/proto#RequiredNotSetError
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm sold. I was getting distracted by the wit. Thanks for the journey.
@rylev What changes to the public API were you thinking would need to be changed for migrating to the 2.0 world? My understanding of worlds and adapters shenanigans is limited. |
The biggest difference is a switch to resources, which shouldn't make much of a difference to the exported Go interface (just the implementation, once resources are supported). There are however a bunch of other small changes to the 2.0 interfaces. For KV specifically the biggest small change is the return type of |
f5fa85a
to
535b0fd
Compare
9ce87f9
to
07e04d8
Compare
@@ -0,0 +1,137 @@ | |||
// Package kv provides access to key value stores within Spin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we want to start only building these when building for WASI and otherwise provide a no-op stub? It'll make building mixed spin/non-spin codebases easier.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems fine in theory. Would you copy all the function stubs or is there something to automate that?
- Introduces a client struct responsible for handling the connection - Remove exposed C types Signed-off-by: Adam Reese <[email protected]>
07e04d8
to
aca5ef3
Compare