Magic Cloud

An Open Source Application Generator


Magic Lambda Caching

Cache helper slots for Magic, more specifically the following slots.

All of the above slots requires a key as its value.

[cache.set]

Invoke this slot to save an item to the cache. The slot takes 3 properties, which are as follows.

Below is an example of a piece of Hyperlambda that simply saves the value of “Howdy world” to your cache, using “cache-item-key” as the key for the cache item.

cache.set:cache-item-key
   expiration:5
   value:Howdy world

To remove the above item, you can use the following Hyperlambda.

cache.set:cache-item-key

[cache.get]

Returns an item from your cache, or null if there are no items matching the specified key. Below is an example of retrieving the item we saved to the cache above.

cache.get:cache-item-key

[cache.try-get]

This slot checks your cache to look for an item matching your specified key, and if not found, it will invoke its [.lambda] argument, and save its returned value to the cache with the specified key, before returning the value to caller. This is a particularly useful slot, since it will synchronise access to the cache key, preventing more than one lambda object from being invoked simultaneously, given the same key.

cache.try-get:cache-key
   expiration:5
   .lambda
      return:Howdy world

The slot is implemented in such a way that only the first invocation towards the specified key will actually execute your [.lambda] object, allowing you to have very expensive executions to create your items, that you want to store into the cache, without experiencing race conditions, or having more than one thread actually create the item and store into the cache. This should in general be your “goto slot” whenever you want to use the cache slots in this project.

[cache.clear]

This is a shorthand slot to completely clear cache, removing all items.

cache.set:cache-item-key
   expiration:5
   value:Howdy world
cache.clear
cache.get:cache-item-key

Notice, the above Hyperlambda should not return any item in its last invocation to [cache.get] since the cache was cleared before invoking it. The slot also optionally takes a [filter] argument, which if provided, will only delete items starting out with the specified filter. Usage example can be found below.

cache.clear:foo.bar

The above will only remove cache items having a key that starts out with “foo.bar” implying that for instance the following items will be cleared.

While an item with a key of “x.foo.bar” will not be removed. This allows you to “namespace” your cache items, and clearing out for instance all cache items matching the specified namespace, in one go.

[cache.list]

Lists all items in cache, and returns to caller.

cache.set:cache-item-key
   expiration:5
   value:Howdy world
cache.list

This slot also supports the following optional arguments.

Internals

Internally the cache this project is using is not the MemoryCache from .Net, since this class suffers from a whole range of problems in regards to its API, such as not being able to count or iterate items, etc. Hence, the actual implementation is completely custom, and is based upon the IMagicMemoryCache interface, which by default is wired up towards its MagicMemoryCache implementation. This is a conscious choice, since first of all the IMemoryCache that .Net provides out of the box is really slow, in addition to that it is missing a lot of crucial parts expected from a mature memory based cache implementation.

If you want to access the actual cache from C# or something, make sure you use it through the dependency injected IMagicMemoryCache interface, providing you with the implementation class needed to consume it from C#. This interface has a lot of nice methods you can use to have a robust and fast memory based cache implementation in your C# code - In addition to that it synchronises access such that no race conditions can be experienced. However, it is a memory based cache. If you need better caching features, going beyond what a basic memory based cache implementation can achieve, you might want to implement Redis or something similar as your own custom C# extension.

Project website

The source code for this repository can be found at github.com/polterguy/magic.lambda.caching, and you can provide feedback, provide bug reports, etc at the same place.

Quality gates

License

This project is the copyright(c) 2020-2021 of Thomas Hansen thomas@servergardens.com, and is licensed under the terms of the LGPL version 3, as published by the Free Software Foundation. See the enclosed LICENSE file for details.