Open gpenin opened 2 days ago
Hi @gpenin,
you can now use the DI config s. resources/container.php
to configure the cache instance. I.e. in case you want to change the cache adapter you can use s.
$services->set(Predis\Client::class)
->args(['tcp://10.0.0.1:6379']);
$services->set(RedisAdapter::class);
$services->alias(CacheItemPoolInterface::class, RedisAdapter::class)
->public();
In general you dont need to share the cache folder since it is only used for performance, so every Fusio instance can have its own cache folder.
Hi @chriskapp,
Thanks a lot for your answer. I must be missing something because my Redis instance still does not contain any object after adding the aforementionned configuration in /var/www/html/fusio/resources/container.php. The [/var/www/html/fusio/cache] directory, that I previously shared with NFS, is still feeded with local data for each container.
I've checked the containers outputs and I did not find any error messages.
Let me add some precisions of the "problem" I'm trying to solve : when the Fusio instances are using their own cache storage, if, for example, we set an operation as inactive on the container 1 (through UI + HAProxy loadbalancing), the API call will be inactive if a client is routed to the container 1, and will still be active if a client is routed to the containers 2 & 3 (but the "UI view" will be correct whichever container is used for configuration viewing).
We managed to improve the situation by :
But I would like to avoid using a NFS shared storage for this usage.
Here is my resources/container.php configuration :
<?php
use Fusio\Engine\Adapter\ServiceBuilder;
use PSX\Framework\Dependency\Configurator;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
return static function (ContainerConfigurator $container) {
$services = ServiceBuilder::build($container);
$services = Configurator::services($services);
/*
$services->load('App\\Action\\', __DIR__ . '/../src/Action');
$services->load('App\\Connection\\', __DIR__ . '/../src/Connection');
$services->load('App\\Service\\', __DIR__ . '/../src/Service')
->public();
$services->load('App\\Table\\', __DIR__ . '/../src/Table')
->exclude('Generated')
->public();
$services->load('App\\View\\', __DIR__ . '/../src/View');
*/
$services->set(Predis\Client::class)
->args(['tcp://redis-fusio:6379']);
$services->set(RedisAdapter::class);
$services->alias(CacheItemPoolInterface::class, RedisAdapter::class)
->public();
};
Regards,
This helps to better understand your use case, in general you need to clear the cache folder so that the DI container compiles again, then the Predis client should be also used, note also I have just wrote this from the top of my head so you also need to require the predis/predis
client s.
composer require predis/predis
Regarding your problem, this is currently indeed the case since we also heavily cache the schema output. Inside Fusio we have a dedicated EventListener which we use to clear the cache in case an operation gets updated, in general you could also add a custom event listener to somehow invalidate the cache on every instance. Otherwise a shared cache between every instance should also work.
Hi @chriskapp,
Unfortunately, this is still not working despite all my attempts. I'm building a Docker image, trying to activate the Redis internal cache usage, but it's failing at the register step, with the following error :
=> ERROR [fusio 5/6] RUN php /var/www/html/fusio/bin/fusio system:register "Fusio\Adapter\Redis\Adapter" 0.6s
------
> [fusio 5/6] RUN php /var/www/html/fusio/bin/fusio system:register "Fusio\Adapter\Redis\Adapter":
0.588 PHP Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\RuntimeException: Cannot autowire service "Symfony\Component\Cache\Adapter\RedisAdapter": argument "$redis" of method "__construct()" has type "Predis\ClientInterface|Redis|RedisArray|RedisCluster|Relay\Relay" but this class was not found. in /var/www/html/fusio/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php:48
0.588 Stack trace:
0.588 #0 /var/www/html/fusio/vendor/symfony/dependency-injection/Compiler/Compiler.php(73): Symfony\Component\DependencyInjection\Compiler\DefinitionErrorExceptionPass->process()
0.588 #1 /var/www/html/fusio/vendor/symfony/dependency-injection/ContainerBuilder.php(752): Symfony\Component\DependencyInjection\Compiler\Compiler->compile()
0.588 #2 /var/www/html/fusio/vendor/psx/framework/src/Dependency/ContainerBuilder.php(60): Symfony\Component\DependencyInjection\ContainerBuilder->compile()
0.588 #3 /var/www/html/fusio/container.php(3): PSX\Framework\Dependency\ContainerBuilder::build()
0.588 #4 /var/www/html/fusio/bin/fusio(42): require_once('...')
0.588 #5 {main}
0.588 thrown in /var/www/html/fusio/vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php on line 48
------
failed to solve: process "/bin/sh -c php /var/www/html/fusio/bin/fusio system:register \"Fusio\\Adapter\\Redis\\Adapter\"" did not complete successfully: exit code: 255
My Dockerfile :
ARG VERSION
FROM fusio/fusio:${VERSION}
COPY ./container.php /var/www/html/fusio/resources/container.php
RUN cd /var/www/html/fusio && composer require predis/predis fusio/adapter-redis
RUN php /var/www/html/fusio/bin/fusio system:register "Fusio\Adapter\Redis\Adapter"
RUN rm -rf /var/www/html/fusio/cache
My container.php :
<?php
use Fusio\Engine\Adapter\ServiceBuilder;
use PSX\Framework\Dependency\Configurator;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;
use Symfony\Component\Cache\Adapter\RedisAdapter;
return static function (ContainerConfigurator $container) {
$services = ServiceBuilder::build($container);
$services = Configurator::services($services);
/*
$services->load('App\\Action\\', __DIR__ . '/../src/Action');
$services->load('App\\Connection\\', __DIR__ . '/../src/Connection');
$services->load('App\\Service\\', __DIR__ . '/../src/Service')
->public();
$services->load('App\\Table\\', __DIR__ . '/../src/Table')
->exclude('Generated')
->public();
$services->load('App\\View\\', __DIR__ . '/../src/View');
*/
$services->set(Predis\Client::class)
->args(['tcp://redis-fusio:6379']);
$services->set(RedisAdapter::class);
$services->alias(CacheItemPoolInterface::class, RedisAdapter::class)
->public();
};
I am grateful for any help.
Regards,
ok, the following container.php
should work s.
$services->set(\Predis\Client::class)
->args(['tcp://redis-fusio:6379']);
$services->alias(\Predis\ClientInterface::class, \Predis\Client::class);
$services->set(\Symfony\Component\Cache\Adapter\RedisAdapter::class)
->arg('$redis', \Symfony\Component\DependencyInjection\Loader\Configurator\service(\Predis\ClientInterface::class));
$services->alias(\Psr\Cache\CacheItemPoolInterface::class, \Symfony\Component\Cache\Adapter\RedisAdapter::class)
->public();
you also dont need to register the redis-adapter, so in your dockerfile you only need:
COPY ./container.php /var/www/html/fusio/resources/container.php
RUN cd /var/www/html/fusio && composer require predis/predis
RUN rm -rf /var/www/html/fusio/cache
you may also want to copy the composer.lock
from your project so that you dependencies are fixed and change only if you explicit run a composer update
we use i.e. the following Dockerfile in several projects s.
FROM fusio/fusio:5.1
COPY ./composer.json /var/www/html/fusio/composer.json
COPY ./composer.lock /var/www/html/fusio/composer.lock
COPY ./configuration.php /var/www/html/fusio/configuration.php
COPY ./container.php /var/www/html/fusio/container.php
COPY ./provider.php /var/www/html/fusio/provider.php
RUN cd /var/www/html/fusio && composer install
Hope this helps.
Hi,
I'm trying to setup Redis as an internal cache for a multiple Fusio instances deployment (using Docker Swarm), but it seems that the 'psx_cache_factory' option in configuration.php is not used anymore (since commit #d4668c8) ?
If this is the case, is there another way, rather than a shared storage (like NFS for example), to share an internal cache between multiple Fusio instances ? Also, is sharing the internal cache a correct approach for a multiple Fusio instances deployment ?
Regards,