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: add redis adapter #304

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

kid-icarus
Copy link
Contributor

@kid-icarus kid-icarus commented Mar 2, 2024

Adding this for review. I've tested this locally and it seems to work just fine. Ultimately I'd like to add some integration tests here, as it has none, similar to the nodefs storage adapter.

For that to work, I was considering leveraging a test container to ensure that Redis is installed, but that would require an update to our test github action (to install docker).

I meant to open this PR earlier but thought I'd get a conversation started :)

@kid-icarus kid-icarus force-pushed the redis-adapter branch 2 times, most recently from 6eb0c27 to 7c849ba Compare March 2, 2024 09:44
@acurrieclark
Copy link
Collaborator

This looks good to me, but the only reason we know the existing adapters work is because we are using them in production!

As you mention, there aren't any specific tests for any of the Storage Adapters, and it would in indeed be good to have a standard set for all of them.

Without being in a position to test it myself, I am loathe to merge just yet. I imagine this will be something people are looking for though.

@pvh
Copy link
Member

pvh commented Mar 4, 2024

I think as the system matures we ought to start putting the storage & network adapters in their own repos (though then we lose automated test integration... hmm) but this is definitely something I've wanted to see for a while so thanks for sharing it!

Copy link
Contributor

@bijela-gora bijela-gora left a comment

Choose a reason for hiding this comment

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

Hi,

I decided to check the list of PRs before trying to code a Redis-based implementation of StorageAdapterInterface. And here it is. Thank you for your work! Don't you mind I will review it?

@@ -0,0 +1,19 @@
Copyright (c) 2024-Present, Ryan Kois
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like in this file you missed the first line. Like here.

"dependencies": {
"@automerge/automerge-repo": "workspace:*",
"debug": "^4.3.4",
"ioredis": "^5.3.2"
Copy link
Contributor

Choose a reason for hiding this comment

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

It feels like the ioredis must be peer dependency. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah that makes sense, I agree

* @param opts - Options to pass to the Redis client.
*/
constructor(
opts?: RedisOptions
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe Redis instance must be passed as a constructor parameter?

async loadRange(keyPrefix: string[]): Promise<Chunk[]> {
const lowerBound = [...keyPrefix, '*'].join(":")
const result: Chunk[] = []
const stream = this.redis.scanStream({
Copy link
Contributor

Choose a reason for hiding this comment

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

Nice!

@bijela-gora
Copy link
Contributor

@pvh hello,

Your phrase: "though then we lose automated test integration... hmm" reminded me the Promises/A+ Compliance Test Suite. What do you think of the idea of developing a set of tests that could be used to test any implementation of the StorageAdapterInterface?

@pvh
Copy link
Member

pvh commented Mar 6, 2024

Sounds great if it can be kept simple. I think the tricky part here is operational complexity -- for things like nodefs & indexeddb there are easily available implementations but for Redis, Postgres, or other backends, we'll need to have the ability to spin up the service at runtime. For SaaS-only backends (say, S3) there's yet more complexity.

That said, I'm quite interested in a solution. I think @HerbCaudill was the one who designed the system we use to test the network adapters and as we grow beyond a monorepo, I think something along the lines you propose could be valuable.

@HerbCaudill
Copy link
Collaborator

Yeah, i think it would be a good idea to restructure the storage adapter tests that currently live in StorageSubsystem.test.ts so that they work more like the network adapter acceptance tests here - you can look in each of the existing network adapters' tests to see how they're invoked.

@bijela-gora
Copy link
Contributor

bijela-gora commented Mar 27, 2024

@kid-icarus hi,

The test suit for a storage adapter implementation merged recently #307 and ready to be used!

@kid-icarus
Copy link
Contributor Author

Awesome, thank you @bijela-gora! I'll take a look sometime in the next week or so 🙏🏻

@pvh
Copy link
Member

pvh commented Apr 4, 2024

@kid-icarus How do you feel about hosting this as a standalone package at /automerge/automerge-repo-storage-redis/?

I think my intuition is that adapters which rely on things not found in most browsers / OS should have their own repo and then whatever CI we set up can be independent.

@bijela-gora
Copy link
Contributor

@pvh

I'd like to share that I created an SQLite storage adapter for JS/TS projects: https://github.com/bijela-gora/automerge-repo-storage-better-sqlite3

I created it because I'm going to use it in my pet project.

Thank you for the awesome Automerge project!

@kid-icarus
Copy link
Contributor Author

kid-icarus commented Apr 6, 2024

@kid-icarus How do you feel about hosting this as a standalone package at /automerge/automerge-repo-storage-redis/?

I think my intuition is that adapters which rely on things not found in most browsers / OS should have their own repo and then whatever CI we set up can be independent.

That makes sense from a principled perspective 👍🏻

One pro of a separate repo is more control over CI, being able to throw whatever external dependencies into a Dockerfile, etc. Another pro is that if there are breaking changes in automerge(-repo), namely the types in this specific case, the burden isn't placed on the core team to update the adapter in the monorepo.

One con would be extra care to specify automerge and automerge-repo as a combination of dev and peer dependencies, so that adapter consumers aren't using duplicate, potentially incompatible versions of them. This also means that as newer versions of automerge(-repo) are released, we'll need to bump those dev dependencies. Dependabot can help with that, but it's just the general con of something living in a monorepo vs an external repo.

That said, I'm more than happy to have the package live in a separate repo :)

@pvh pvh force-pushed the main branch 2 times, most recently from e61f8e3 to d3d1a7d Compare July 26, 2024 20:13
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.

5 participants