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
[ADDED] KeyValue and ObjectStore support for JetStream #832
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.
looks good in general, a few comments of things the ADR covered and deviations on ADR design
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.
Part of the reason why KvEntry is OK is that it is effectively a StoredMessage, with additional metadata about the bucket and the operation. With that said, I would much rather have a presentation where such values are in the headers. But there we get into additional issues: headers from the system may collide with user headers, and if the user sets a header that collides what is the meaning of that.
For replication and watches, the understanding of DELETE
as an operation is important. Empty
is really open to interpretation. The store could a have value by simply indicating that the key exists, thus the need for the operation to be telegraphed.
Outside of applications that deal with replication or that need to do something special on delete, the absence of the value is simpler. For NGS, my KV wrappers actually hide all the unpacking and simply code DELETEs as a null return value (ie I don't differentiate). But In some cases for example where keys should have a TTL, it is important to know the value doesn't exist even if it did.
TBH - I would rather see the ADR extended to deal with blobs and perhaps provide a compare and swap based on value, but understand that this is not what the nats-server is doing.
// Get returns the latest value for the key. | ||
Get(key string) (value []byte, revision uint64, err error) | ||
// Put will place the new value for the key into the store. | ||
Put(key string, value []byte) (revision uint64, 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.
Does Put
fail if the key doesn't exist? - IE looking for clarification between Create
and Put
wondering if what we are trying to accomplish here is some sort of compare and swap.
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.
In the ADR, there is no create, just put, and the behavior is create or replace
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.
would Init
be more indicative than Create
?
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.
Create only succeeds if not present, Update only if it is present and has not changed, and Put just works all the time sans other issues.
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 believe they should all have this functionality.
With respect to the object store we should allow the design to support features (external or internal) such as: Lifecycle Management (delete, TTL) With the proposed design it seems that all of this could be possible through an external system (primarily via object nomenclature) while keeping functionality as simple as possible here. Just want to avoid making it difficult to build a future feature due to a design decision today. |
Lifecycle Management (delete, TTL)
Event Notifications (add/delete/lock)
Locking
Archiving (tiered storage)
Searching/Indexing (tagging)
Versioning
|
5c01667
to
567cf0c
Compare
ok I pushed updates to KV. Will do small update to Object in a bit for versions and Purge as well, etc. |
4c3e19d
to
6ff7625
Compare
@derekcollison Following the PR with the FC fix, this PR has now conflict that will need to be addressed. We need to be careful in reverting your FC changes that we are not putting back the way it was prior to the FC fix PR :-) |
} | ||
|
||
// CreateObjectStore will create an object store. | ||
func (js *js) CreateObjectStore(cfg *ObjectStoreConfig) (ObjectStore, 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 think maybe we should update the interface to have the partial opts like:
func (js *js) CreateObjectStore(cfg *ObjectStoreConfig) (ObjectStore, error) { | |
func (js *js) CreateObjectStore(cfg *ObjectStoreConfig, opts ...JSOpt) (ObjectStore, error) { |
so that later on can pass the arguments below for example like: js.AddStream(scfg, opts)
That would make it possible to change the timeout or context for example.
(This could be addressed in a different PR but before tagging the client to not break the interface)
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.
Doesn't that duplicate what we inherit from the js receiver when you setup JetStream context originally?
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.
In case of MaxWait it would override what was inherited from the default in the JS context, but for nats.Context
option with a timeout for example, those generally passed via arguments like CreateObjectStore(cfg *ObjectStoreConfig, nats.Context(ctx))
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.
some general comments for the call today
a9eec7a
to
820b4a3
Compare
Also: - Fixed message reply in PublishMsgAsync - Ability to seal streams - Ability for consumer to get message headers only, no msg payload - GetLastMsg and purgeStream by subject Signed-off-by: Derek Collison <derek@nats.io>
Also: