-
Notifications
You must be signed in to change notification settings - Fork 173
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
[WIP]: Initial ObjectStore client implementation #331
Conversation
When a NATS Server restarted behind an LB, reconnection would fail since the proper connect timeout exception was not being caught, leaving the client hanging sometimes. Signed-off-by: Waldemar Quevedo <wally@synadia.com>
Signed-off-by: Waldemar Quevedo <wally@synadia.com>
Signed-off-by: Waldemar Quevedo <wally@synadia.com>
Fix issue when reconnecting against LB
Create dependencies.md
…ze-option Support set pending size to client connect options
Bumps [py](https://github.com/pytest-dev/py) from 1.8.0 to 1.10.0. - [Release notes](https://github.com/pytest-dev/py/releases) - [Changelog](https://github.com/pytest-dev/py/blob/master/CHANGELOG.rst) - [Commits](pytest-dev/py@1.8.0...1.10.0) Signed-off-by: dependabot[bot] <support@github.com>
Signed-off-by: Waldemar Quevedo <wally@synadia.com>
Removed loop from options, deprecated from nats.connect().
Update __main__.py
Hey @wallyqs it would be great to hear your thoughts on this PR. |
Thanks @domderen for the contribution and the rebase. Sorry for the delay, I will start looking today. |
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've started to check the cross language compatibility of the implementations, first with Go and I plan to do the same with JavaScript.
(I have a use case where I write objects in Python and read them from JavaScript.)
nats/js/object_store.py
Outdated
|
||
data = None | ||
if msg.data: | ||
data = base64.b64decode(msg.data) |
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.
data = base64.b64decode(msg.data) | |
data = msg.data.decode() |
nats/js/object_store.py
Outdated
) | ||
raise e | ||
|
||
info.mtime = datetime.utcnow().timestamp() |
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.
info.mtime = datetime.utcnow().timestamp() | |
info.mtime = datetime.now(timezone.utc).isoformat() |
nats/js/object_store.py
Outdated
nuid=id.decode(), | ||
size=0, | ||
chunks=0, | ||
mtime=0 |
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.
from datetime import datetime, timezone
# ...
mtime=0 | |
mtime=datetime.now(timezone.utc).isoformat(), |
nats/js/object_store.py
Outdated
|
||
# Make sure the digest matches. | ||
sha = h.digest() | ||
digest_str = info.digest.replace(OBJ_DIGEST_TYPE, "") |
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.
digest_str = info.digest.replace(OBJ_DIGEST_TYPE, "") | |
digest_str = info.digest.replace(OBJ_DIGEST_TYPE, "").replace(OBJ_DIGEST_TYPE.upper(), "") |
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.
Hey, could you elaborate, why somthing like this?
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've seen both "digest": "sha-256=xxx"
and "digest": "SHA-256=xxx"
. Probably we should change this line instead: https://github.com/tothandras/nats.py/blob/object_store/nats/js/object_store.py#L50. The Go client uses SHA
: https://github.com/nats-io/nats.go/blob/f4102422df7df83b2032318fd14a248c45f113e1/object.go#L232 and the JS/Deno client uses sha
: https://github.com/nats-io/nats.deno/blob/6bdf6ff33f740e3c2c30251a79d291b1cb5288ff/tests/objectstore_test.ts#L87
nats/js/object_store.py
Outdated
obj = self.__sanitize_name(name) | ||
|
||
if not key_valid(obj): | ||
raise InvalidObjectNameError | ||
|
||
meta = OBJ_META_PRE_TEMPLATE.format(bucket=self._name, obj=obj) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
nats/js/object_store.py
Outdated
if not key_valid(obj): | ||
raise InvalidObjectNameError | ||
|
||
meta = OBJ_META_PRE_TEMPLATE.format(bucket=self._name, obj=obj) |
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.
See: https://github.com/nats-io/nats.go/blob/f4102422df7df83b2032318fd14a248c45f113e1/object.go#L442
meta = OBJ_META_PRE_TEMPLATE.format(bucket=self._name, obj=obj) | |
meta = OBJ_META_PRE_TEMPLATE.format(bucket=self._name, obj=base64.urlsafe_b64encode(bytes(obj, "utf-8")).decode().rstrip("=")) |
nats/js/object_store.py
Outdated
chunk_subj = OBJ_CHUNKS_PRE_TEMPLATE.format( | ||
bucket=self._name, obj=id.decode() | ||
) | ||
meta_subj = OBJ_META_PRE_TEMPLATE.format(bucket=self._name, obj=obj) |
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.
meta_subj = OBJ_META_PRE_TEMPLATE.format(bucket=self._name, obj=obj) | |
meta_subj = OBJ_META_PRE_TEMPLATE.format(bucket=self._name, obj=base64.urlsafe_b64encode(bytes(obj, "utf-8")).decode().rstrip("=")) |
Hey @tothandras thanks for your comments. I'm on holidays at the moment, but will look into it once I'm back in ~2 weeks. |
@domderen enjoy your holiday! |
Hey @tothandras I updated this PR with your comments. I think I included them all, but would you mind taking a look? |
@domderen If you could rebase on master I could try it out. I'm probably less suited for reviewing the code itself. I lack the deep knowledge of Python. :) |
Hey I think the rebase should be done, though I'm not sure if I didn't mess something up... Looks like a lot of changes now... |
@domderen I think you can try something like the following below to squash into a single commit and avoid the merge conflicts using your current branch: # Checkout the object store branch
git checkout object_store
# Take a diff against latest main, we'll apply this diff as a patch.
git diff main > obj.diff
# Rename current local object_store branch.
git branch -m object-store-backup
# Redo object_store branch
git checkout main
git branch object_store
git checkout object_store
# Apply the diff as a patch on top of object_store branch and commit.
git apply -3 obj.diff
# Fix formatting
make format
git commit -s -m "Add Object Store implementation"
# Force push the object_store branch that is now squashed and rebased.
git push main object_store -f I gave it a try at squashing into a single commit via a diff the result can be found here: https://github.com/nats-io/nats.py/compare/obj |
I just run into an issue with |
Signed-off-by: Dominik Deren <dominik.deren@live.com>
Hey @wallyqs thanks for the help! I followed your steps and force pushed just those changes that looked like my original implementation. It should make it easier to review. Let's see if the build passes now, if not I'll take a look at tests. |
@tothandras I think I tried to take this implementation of __sanitize_name from the golang implementation. Are they different now? |
Hmm there are two tests failing, but those are two different tests in two different builds, both don't seem to be related to my changes... Should I expect some flakiness in those tests? |
Sorry, I was wrong. It seems I didn't apply all the patches on my fork. |
…to object_store
Hi everyone! Are there any plans to resume this PR in the short term? I noticed it was reviewed six months ago, but has been stale for some time now. Also, looks like the Travis build failed due to a flaky test but it's been excluded from Thank you all! |
Hey, I was updating this PR occasionally when I needed to change something in the Object Store implementation for my own needs. I'm happy to keep going on this PR, but I'm not sure if owners see it as valuable, or if they would prefer a different direction. It is also still missing some of the APIs that Object Store has in golang version, and I'm not sure what would be the minimal required scope for it to get merged. |
This pull request contains a JetStream ObjectStore client implementation. It is an early draft that at the moment contains following functionalities:
It was re-implemented from the golang code in nats.go repo.
This code is not complete yet! I'm sharing it in this form to gather some initial feedback if this is the right direction for this implementation. Any feedback is welcome :)
I think it would be good to implement ObjectStore calls around Bytes.IO types, to allow handling streams, same as the golang version does, but I went with simpler bytes implementation for now. I can try to extend it later on if it will look like a right direction.