Data Cache in Resgate

Hello everyone,

When we started using Resgate recently, we noticed that Resgate seems to buffer data in some kind of cache.

Is there an option to deactivate this data buffering or limit the size of the cache?
We are slightly worried that it might consume a large portion of our limited resources once we start passing around more objects.

Best regards

Judi

Hi!

Resgate does cache data that is currently subscribed by any of its clients, and it will keep it cached for a short while after the last client unsubscribed to that resource or disconnected.

It is currently not possible to disable this functionality, as it is also part of the recovery mechanism.
There are plans to enable caching to storage, and not only use in-memory caching, but I am not sure that would be sufficient for you.

Some general tips (see what applies to you):

  • Subscribe on demand. Get the data when it is time to view it, and release it (off()) when no longer in view.
  • Use pagination or similar for large portions of data (similar to the suggestion above).
  • Avoid duplicate resource IDs for identical data.
  • Install more RAM :grin:
  • Load balance between multiple Resgate (see here) servers.

I don’t know your exact use case, but if I knew more I might be able to help better.

Best regards,
Samuel

1 Like

Hi,

I’m bumping this as my question is quite the same.

My service has some external ressources that can be updated without the service knowing it. For those ressources, the service cannot update the resgate cache, and therefore cache is problematic.

If I understand well, I could actually go around this by sending a system.reset for the ressource that must not be cached each time I send this ressource (right after). I would prefer an option were I say once to resgate that this ressource must never be cached, for example though a dedicated ressource called by resgate at startup asking for cache control settings for the ressources. This could be implemented following Cache-Control header.

Also, I find it problematic to ignore the client Cache-Control headers. I thing resgate should take this in account when standard rest API calls are done.

Regarding naming, I would also suggest to have a more intuitive name for system.reset as it basically does cache invalidation, so why not simply call it cache.invalidate?

Welcome to the forum! :partying_face:

Resgate and the RES protocol was created primarily for real-time resources. Accessing the data through HTTP was always part of the scope, but within certain boundaries due to the protocol design.

However, the issue with external data that might be updated without notice, need a solution. I’ve faced the same problems myself.

I don’t think Cache-Control request headers is the correct way to go, as I don’t believe (web)clients should have to be concerned about which resource are cachable or not. But, I could imagine extending the response to get requests with a “max-age” like cache property, telling Resgate the resource will never get any modifying events, and that it should be evicted from the cache after max-age is reached (or on system.reset).

Something like this:

{
    "result: {
        "model": { "foo": "bar" },
        "maxAge": 60 // Evict after 60 seconds
    }
}

This could also translate into a Cache-Control: max-age=60 response header for HTTP requests.

Would something like that solve your issue?

Another way to handle it is by having the service periodically (every x seconds) fetching the external resource, and once in a while sending a system.reset to see if any clients are still interested in the data; if a Resgate responds to the system.reset, the service continues fetching the resource, otherwise stops.

This is how I solved it in the rest2res service:

I agree that system.reset is not very intuitive. But system is the reserved namespace for all system calls, events, and errors. So it would then be system.invalidateCache or something similar. The name came from initially just being thought of as an event sent on service restart/reset. But it is now used for much more than that. Oh well :slight_smile:

Best regards,
Samuel

Hi Samuel,

Thanks for your response, and sorry for my late reaction, I thought I would receive a notification on response.

Would something like that solve your issue?

You are right, I don’t know why I had request Cache-Control header in mind, your proposition makes much more sense and would totally cover the use case.

Another way to handle it is by having the service periodically (every x seconds) fetching the external resource

This would be a scenario acceptable only in some cases, but may lead to a 100% CPU usage for nothing in others.

So it would then be system.invalidateCache or something similar.

That’s great too. It’s just “reset” that is a bit scary when you come from the outside.

Would you imagine adding the cache control feature to the roadmap?

Best regards,
Christian

Sure can do! I think it is a really good idea.

But it requires some more thinking. Just maxAge isn’t enough. I would want it to include some type of cache mode. These are the three modes I can think of:

live

Default setting. Resource is considered live, and Resgate expects to gets modifying events/resets whenever the resource changes. This is current behaviour.

static

After sending the resource to the client, Resgate will never send the client any modifying events (even on resets). Combined with maxAge, Resgate may serve it from the cache up until maxAge is reached. If no maxAge is set (or is 0), Resgate will evict it as soon as it has been served to requesting clients.

If Resgate gets a reset for a resource with static mode, it should evict it from the cache without further action.

If Resgate gets a modifying event for a resource with static mode, it may update the cached resource and reset the maxAge timer. However, it will not propagate the changes to any clients. Normally, a service serving a resource with static cache mode should not send modifying events. But if it happens, the behaviour of Resgate should be defined.

autoreset (refetch? or just auto?)

Used in combination with maxAge. Once maxAge is reached, Resgate will behave as if receiving a reset on the resource, and will automatically refetch the resource, compare it with the cached version, and generate events that describes any changes. It will then restart the maxAge timer, repeating the process until no clients are subscribing to the resource. When noone is subscribing, at which time it will simply evict it from the cache.

If Resgate gets a reset event for a resource with autoreset mode, it will directly trigger the refetch and restart the maxAge timer.

If Resgate gets a modifying event for a resource with autoreset mode, it will update the cache and restart the maxAge timer. The event will also be sent to all subscribing clients.


I think that should cover most needs.

In your case, it is perhaps the static that is relevant.

Any comments on this?

Best regards,
Samuel