-
Notifications
You must be signed in to change notification settings - Fork 265
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
Add NATS replica client #596
base: main
Are you sure you want to change the base?
Conversation
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 added a few points of feedback. Can you wire this up to cmd/litestream
and add some instructions on how to test it?
@@ -0,0 +1,402 @@ | |||
package nats |
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.
This doesn't seem to be imported or usable by the cmd/litestream
binary. Am I missing something?
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 had hooked it up (i thought) in cmd/litestream/replicate.go
around line 125. Apparently this code wasn't commited
Big NATS fan here (oh, and Litestream too of course). Just stumbled across this PR accidentally and looked through it briefly. Some thoughts:
Apologies for stepping in unannounced. Let me know if I can help out any other way. |
@betamos thanks for taking the time
I can see it both ways, if it's a blocker I'll remove it.
This is a good point. In general you want to set limits on buckets but this goes to your previous point.
I teach NATS usage at Synadia to customers. We highly recommend JWT only. User/pass, while supported currently support it really shouldn't be used. It's very easy to create JWT programmatically and have far superior control available.
Not at all, I think Litestream is an amazing tool and should be available in a NATS centric pipeline. |
I was looking through the litestream docs to see if it supported NATS then came across this PR. Would be great to see this get over the line. I agree with the previous comment about the bucket configuration. I would expect to configure my own bucket and just tell litestream which one to use. There is a number of bucket configurations that will be set depending on my use case at the time. I suggest just taking in a bucket name and expecting it to exist. JWT authentication is my preferred approach but again I wouldn't have litestream be so opinionated. It should support any NATS auth mechanism |
I have been slammed with other projects but I agree with the comments above and will remove the bucket config from this sorry and look for a review |
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.
@delaneyj Took some time to review given our conversation this past week.
} | ||
|
||
func (c *ReplicaClient) Cleanup(ctx context.Context) (err error) { | ||
if c.nc == nil { |
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.
if c.nc == nil { | |
if c.nc != nil { |
|
||
func (c *ReplicaClient) Cleanup(ctx context.Context) (err error) { | ||
if c.nc == nil { | ||
c.nc.Close() |
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.
c.nc.Close() | |
c.nc.Drain() | |
// Block until draining is done. There is also a `ClosedHandler` | |
// callback option for the NATS connection where a channel | |
// could be used.. | |
for c.nc.IsDraining() {} |
BucketReplicas int | ||
BucketMaxBytes int64 | ||
BucketTTL time.Duration |
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 presume the goal is an out-of-box "no setup required", but for all other backends (based on a quick scan of the docs) require setting up the bucket ahead of time. These particular properties are operational concerns which should, IMO, be handled out-of-band and would be safer. For instance, the replicas would need to change for some reason. When Litestream would startup, an existing configuration could conflict with the remote settings of that bucket and either overwrite it (depending on the setting) or error since it has changed.
I suggest removing these and the requirement would be that a bucket is pre-created and you only need credentials and the bucket name when configuring this backend.
This would also remove the need to have upsertObjectStore
.
} | ||
|
||
// Returns a list of available generations. Order is undefined. | ||
func (c *ReplicaClient) Generations(ctx context.Context) (_ []string, err error) { |
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 did not peak at the other backend implementations, so if this is the idiomatic expectation in the codebase then 👍. However, at least for this backend implementation is a bit more difficult to read which values are being returned at times across some of the methods since there is scoped explicit assignment of err
in particular vs. implicit.
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.
Sorry, I didn't define what "it" is in the first sentence.. named return values.
} | ||
|
||
b := buf.Bytes() | ||
natsInfo, err := objectStore.PutBytes(ctx, filename, b) |
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.
Could use Put
which takes an io.Reader
directly.
JWT string `yaml:"jwt"` | ||
Seed string `yaml:"seed"` |
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.
All auth methods should be supported. If an additional dependency is welcome, this package handles all the options as well as looking up the nats context
profile. https://pkg.go.dev/github.com/nats-io/jsm.go/natscontext
Annnd.. I just realized I was a bit redundant with the other commentary 🤦. Apologies folks.. |
NATS is a distributed application framework. It has the ability to store objects similar to S3/Minio in a replicated persistence store. This replica client supports this feature for Litestream.
Note
The
replica_client_test.go
was geared towards only being tested againstfile
. Have moved fromfs/os
errors to Litestream specific ones. This meant updating the file replica client to use these as well.