Promise-Based Cache With ReactPHP
In the previous article, we have already touched caching (when caching DNS records). It is an asynchronous promise-based Cache Component. The idea behind this component is to provide a promise-based
CacheInterface and instead of waiting for a result to be retrieved from a cache the client code gets a promise. If there is a value in a cache the fulfilled with this value promise is returned. If there is no value by a specified key the rejected promise returns.
The component has one simple in-memory
ArrayCache implementation of
CacheInterface. The interface is pretty simple and contains three methods:
set($key, $value) and
Let’s try it to see how it works. At first, we put something in cache:
set($key, $value) simply sets the value of the key
bar. If this key already exists the value will be overridden.
The next step is to get
foo value back from the cache. Before calling
get($key) take a look at the
get($key) method doesn’t return the value from cache, instead, it returns a promise. Which means that we should use promise
done() method to attach onFulfilled handler and actually retrieve the value from cache:
In the previous example actually, there is no need to create a callback simply to call
var_dumpfunction inside. You can pass a string right in
done()method and everything will work exactly the same:
It may occur that there is no value in a cache. To catch this situation we should use promise
otherwise() method and attach an onRejected handler:
The last two examples can be merged and rewritten with one promise
then() call which accepts both onFulfilled and onRejected handlers:
With this approach, we can easily provide a fallback value for situations when there is no value in a cache:
If there is a value in a cache the first callback is triggered and this value will be assigned to
$data variable, otherwise the second callback is triggered and
$data variable gets
The onRejected handler can itself return a promise. Let’s create a callback with a new promise. For example, this callback tries to fetch some data from a database. On success the promise is fulfilled with this data. If there is no required data in a database we return a some default value. Here is a new fallback callback:
A quick overview. Our promise has a resolver handler. This handler accepts two callbacks: one to fulfill the promise with some value, and another - to reject a promise. In our example we immediately fulfill the promise with a string
'some data from database'.
The next step is to replace the onRejected handler for a promise which was returned when we call
In the snippet above
$getFromDatabase callback is triggered when there is no value in cache. This callback returns a promise, so we can continue chaining and attach one more
As you remember our promise is fulfilled with
'some data from database' string. This value will be passed into the last
then callback. As a result, this string will be printed by
To delete something from cache simply call
delete($key) method and specify a key to be deleted.
The Cache Component comes with one simple in-memory
ArrayCache implementation. It simply stores all values in array in memory:
But there are several more implementations:
- WyriHaximus/react-cache-redis uses Redis.
- WyriHaximus/react-cache-filesystem uses filesystem.
- php-react-cache-memcached uses Memcached.
You can find examples from this article on GitHub.
This article is a part of the ReactPHP Series.
Learning Event-Driven PHP With ReactPHP
The book about asynchronous PHP that you NEED!
A complete guide to writing asynchronous applications with ReactPHP. Discover event-driven architecture and non-blocking I/O with PHP!Minimum price: 5.99$