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

Tagging system #53

Open
Julien-R44 opened this issue Feb 11, 2025 · 5 comments
Open

Tagging system #53

Julien-R44 opened this issue Feb 11, 2025 · 5 comments
Assignees
Labels
enhancement New feature or request

Comments

@Julien-R44
Copy link
Owner

Julien-R44 commented Feb 11, 2025

Creating an issue in case people have the same question.

I am not fully happy with the namespace system we have. Not enough for easy invalidation. So I would love to have tags and it's planned, but it's quite a tricky thing to nail down, especially in bentocache, where we have a lot of different features

I've been doing quite a bit of research on the topic and should try an implementation when I have some time. The API will be super simple:

await bento.getOrSet({
  key: 'foo',
  factory: getFromDb(),
  tags: ['tag-1', 'tag-2']
});

await bento.set({ 
  key: 'foo',
  tags: ['tag-1']
});

Then, we could delete all entries tagged with tag-1 using:

await bento.delete({ tag: 'tag-1' });

This would remove all entries that have the tag-1 tag.

It's likely that this tagging system will deprecate the current namespace system we have. I think they would become useless once we have tags. We would keep namespaces until v2, but they would be marked as deprecated via JSDoc

@Julien-R44 Julien-R44 self-assigned this Feb 11, 2025
@Julien-R44 Julien-R44 added the enhancement New feature or request label Feb 11, 2025
@wodCZ
Copy link

wodCZ commented Feb 11, 2025

Super happy to see this issue. Allow me to propose a mechanism that I believe is universal for any kind o production system: https://github.com/mcollina/async-cache-dedupe#invalidation.

It's actually quite similar to the tags you illustrated, except that in the proposed solution the tags can be computed based on the factory result.

Suppose I have a Product model that can be assigned to many Categories. I then do a query for Product:1 that is currently assigned to ['Category:1', 'Category:2']. I then mark Category:2 as archived in other part of the system, and I'd like to invalidate all Product queries/caches that referenced the Category:1.

That's impossible to tell with static tags without the context of factory result. But from my understanding, the difficult part is tag-based invalidation. Collecting tags (or references) from a callback instead of array shouldn't present too many complications?

@Julien-R44
Copy link
Owner Author

Julien-R44 commented Feb 11, 2025

Yup absolutely, I should have included it in my first comment. In fact, the tags will be compatible with the adaptive caching system we have today. So :

const product = await bento.getOrSet({
  key: 'product:1',
  factory: async (ctx) => {
     const product = await getFromDb(1)

     ctx.setTags(product.categories.map((category) => category.name))

     return product
  }
});

Lemme know if it could suit you

@wodCZ
Copy link

wodCZ commented Feb 11, 2025

Beautiful 😍 I believe that solves my last trouble with the library, and would make bentocache the ultimate caching library for production-grade node apps!

In fact, such API should be sufficient to implement an automatic ORM caching layer similar to https://github.com/Suor/django-cacheops. Basically, all relations returned by the ORM are saved as references, and all updates/deletes automatically invalidate relevant results.
That's definitely something out of scope of bentocache itself, but could provide very solid ground for a 3rd party integration.

Possibly, ctx.addTags would be useful to make it easier to collect tags from multiple helpers, but I guess that could be achieved with ctx.setTags([...ctx.tags, ...result.otherRelations.map(r => r.id)]).

@Julien-R44
Copy link
Owner Author

Julien-R44 commented Feb 16, 2025

I merged PR #57, which adds experimental support for tags 🎉
Experimental, because the feature is pretty complex. So I would really like to have some feedbacks and use it in some real world projects to be more confident about it

Next steps:

  • Add a new docs page on it, because the internals of the tag system, the way it works, is not ultra-conventional. This needs to be documented. Also add a warning that tags are experimental and ideally require feedback
  • Release bentocache@1.2.0 with tags
  • Keep this issue open to track feedback on tags

Still not sure if we should deprecated namespace. Lemme know if you have any thoughts

Also @wodCZ and @dunhamjared thanks a lot for the sponsorship 🙏

@Julien-R44
Copy link
Owner Author

1.2.0 released with docs

Release notes : https://github.com/Julien-R44/bentocache/releases/tag/bentocache%401.2.0
Docs : https://bentocache.dev/docs/tagging

If you encounter any bugs with tagging or have any feedback, please let me know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants