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

chore: Add consul and dynamodb support #248

Merged
merged 17 commits into from
Oct 24, 2024

Conversation

keelerm84
Copy link
Member

No description provided.

@keelerm84 keelerm84 requested a review from a team as a code owner October 22, 2024 19:57
consul *consul.Client
}

// {{{ PersistentStore implementation
Copy link
Member

Choose a reason for hiding this comment

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

Is this a fold marker? Is it intentional?

Copy link
Member Author

Choose a reason for hiding this comment

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

Well yes and no. I was wanting to show where it started and ended, so I was putting in some easy markers that you can jump between.

Are they also default vim markers? Yes, but that's beside the point. 😄

Honestly, I was expecting more work in these files and figured it would be more useful than it is. So I will remove it.

RequestItems: map[string][]*dynamodb.WriteRequest{table: batch},
})
if err != nil {
// COVERAGE: can't simulate this condition in unit tests because we will only get this
Copy link
Member

Choose a reason for hiding this comment

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

Maybe this comment does apply, but the coverage suppression probably doesn't.

(Though I am not 100% sure it makes sense in its original location, which was also a test.)

"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/dynamodb"
c "github.com/hashicorp/consul/api"
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: c -> consul

),
))

// Create a DynamoDB client from just a session.
Copy link
Contributor

Choose a reason for hiding this comment

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

what is the alternative?


// {{{ PersistentStore implementation

func (c ConsulPersistentStore) DSN() string {
Copy link
Contributor

@cwaldren-ld cwaldren-ld Oct 22, 2024

Choose a reason for hiding this comment

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

It's not necessarily bad to have this be a value receiver, but it does feel a bit confusing when the rest are pointer receivers. Go syntax sugar will make it work at the callsite.

It will make a copy of the ConsulPersistentStore struct, which could have unintended side-effects (like perhaps there is some mutex deep in the consul client that cannot be copied). Go is great.

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 will update to be a pointer receiver.

Get(key string) (string, error)
GetMap(key string) (map[string]string, error)
WriteMap(key string, data map[string]string) error
Get(prefix, key string) (string, bool, error)
Copy link
Contributor

Choose a reason for hiding this comment

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

It's not immediately clear to me what (string, bool, error) means, but I suspect it's value, present, error?

Doc comment would work, or giving each return value a name would also be fine

Copy link
Contributor

Choose a reason for hiding this comment

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

Another option: since we hve the whole Opt thing going on, this could be an OptString, error

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 like the optional string, so I'll go with that.


if err != nil {
return nil, fmt.Errorf("list failed for %s: %s", key, err)
}
Copy link
Contributor

Choose a reason for hiding this comment

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

For errors returned from these wrapper methods, it could make sense to prefix them with the impl name so that it's clear exactly where the error is coming from. I don't have a good suggestion for the prefix though.

return nil, fmt.Errorf("consul-wrapper: foo bar")

ideally Consul itself is prefixing stuff with consul as well, but maybe not?

Because this can get repetitive, there are usually two options:

  1. Make a helper like return nil, c.newErr(...)
  2. Make a dedicated error type like return nil, &consulErr { action: "list", key: key, err: err } and have it render the error string

What you have is also probably fine. This is more of a best practice. Feel free to disregard.

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 think I will leave this one to our refactoring work tomorrow.

func (c *ConsulPersistentStore) WriteMap(prefix, key string, data map[string]string) error {
kv := c.consul.KV()

// Start by reading the existing keys; we will later delete any of these that weren't in allData.
Copy link
Contributor

Choose a reason for hiding this comment

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

allData

think the comment needs to be tweaked

if err != nil {
return fmt.Errorf("failed to get existing items prior to Init: %s", err)
}
oldKeys := make(map[string]bool)
Copy link
Contributor

Choose a reason for hiding this comment

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

If oldKeys is meant to represent a set, I find it clearer to use map[string]struct{}. That way, there's no need to check v (on line 81 of this diff).

On line 77, you'd delete from the set.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I thought about this when I was copying this work over from the actual implementations. I went back and forth on whether consistency was better.

I'll just fix it here.

sdktests/server_side_persistence_consul.go Outdated Show resolved Hide resolved
}

func batchOperations(kv *consul.KV, ops []*consul.KVTxnOp) error {
for i := 0; i < len(ops); {
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 comes from the consul integration, but it would be good if we had a comment explaining what it is actually doing at a high level.


const (
// Schema of the DynamoDB table
tablePartitionKey = "namespace"
Copy link
Contributor

Choose a reason for hiding this comment

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

Since these are all in the same package, you could access, say, tableName from the Redis file or whatever. It could be worth prefixing these to make them unique.

Better yet would be refactoring these into dedicated packages, that way they can't start accidentally sharing constants. But that would be a fair amount of work.

I'm surprised initedKey isn't being used in Redis impl (and is being used here)

Copy link
Member Author

Choose a reason for hiding this comment

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

Prefixed the dynamodb ones, and then moved the init one to the base file (I know that doesn't change anything, it's just an implication). Also changed its name and updated the usage in other places.

"github.com/launchdarkly/go-sdk-common/v3/ldcontext"
"github.com/launchdarkly/go-sdk-common/v3/ldvalue"
"github.com/launchdarkly/go-server-sdk-evaluation/v3/ldbuilders"
"github.com/launchdarkly/sdk-test-harness/v2/framework/ldtest"
"github.com/launchdarkly/sdk-test-harness/v2/servicedef"
)

const (
PersistenceInitedKey = "$inited"
Copy link
Contributor

Choose a reason for hiding this comment

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

This is now a public constant accessible from other packages (capital P). Unclear if this is intended?

@keelerm84 keelerm84 merged commit e398001 into feat/persistence-tests Oct 24, 2024
2 checks passed
@keelerm84 keelerm84 deleted the mk/sdk-768/other-dbs branch October 24, 2024 16:46
keelerm84 added a commit that referenced this pull request Oct 24, 2024
keelerm84 added a commit that referenced this pull request Oct 31, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants