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

feat(sdk/go): Refactor the key/value Go SDK to be more idiomatic #1845

Merged
merged 1 commit into from
Oct 27, 2023

Conversation

adamreese
Copy link
Member

  • Introduces a client struct responsible for handling the connection
  • Remove exposed C types

@adamreese adamreese added this to the 2.0 milestone Oct 3, 2023
Copy link
Member

@vdice vdice left a 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.

@rylev
Copy link
Collaborator

rylev commented Oct 17, 2023

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.

@lann
Copy link
Collaborator

lann commented Oct 17, 2023

Spin 2.0's new world

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 none to indicate "no such key" into a ErrNoSuchKey would be ideomatic for Go anyway.

Comment on lines +123 to +130
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")
Copy link
Collaborator

@lann lann Oct 17, 2023

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.

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 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.

Copy link
Collaborator

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)

Copy link
Member Author

@adamreese adamreese Oct 20, 2023

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

Copy link
Collaborator

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 *Errors for yes-payloads most closely matches the ecosystem.

Copy link
Collaborator

@lann lann Oct 20, 2023

Choose a reason for hiding this comment

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

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'm sold. I was getting distracted by the wit. Thanks for the journey.

@adamreese
Copy link
Member Author

@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.

@lann
Copy link
Collaborator

lann commented Oct 17, 2023

@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 get switching from result<list<u8>, error> to result<option<list<u8>>, error>, where it will return ok(none) if a key isn't found rather than err(no-such-key). For the Go interface I think it will make sense to translate that ok(none) back into a e.g. ErrNoSuchKey error anyway.

sdk/go/kv/kv.go Outdated Show resolved Hide resolved
@adamreese adamreese force-pushed the feat/sdk-go-kv-v2 branch 2 times, most recently from 9ce87f9 to 07e04d8 Compare October 26, 2023 19:22
@@ -0,0 +1,137 @@
// Package kv provides access to key value stores within Spin
Copy link
Member

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.

Copy link
Collaborator

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]>
@adamreese adamreese merged commit cc3f9f9 into fermyon:main Oct 27, 2023
9 checks passed
@adamreese adamreese deleted the feat/sdk-go-kv-v2 branch October 27, 2023 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
No open projects
Status: Done
Development

Successfully merging this pull request may close these issues.

5 participants