Skip to content

Commit

Permalink
Fixing cache pre-fix issues when using redis cluster
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelfolaron committed Nov 18, 2024
1 parent e404402 commit beccd6c
Show file tree
Hide file tree
Showing 13 changed files with 153 additions and 165 deletions.
51 changes: 32 additions & 19 deletions app/Core/Configuration/laravelConfig.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@
| specified when running a cache operation inside the application.
|
*/

'default' => 'installation',

/*
Expand Down Expand Up @@ -179,7 +178,7 @@
| that reason, you may prefix every cache key to avoid collisions.
|
*/
'prefix' => 'leantime_cache_',
'prefix' => '',

],
'session' => [
Expand Down Expand Up @@ -395,23 +394,6 @@
'compiled' => realpath(storage_path('framework/views')),

],
'redis' => [
'client' => 'phpredis',
'options' => [
'cluster' => 'redis',
'context' => [],
'compression' => 3, // Redis::COMPRESSION_LZ4
],
'default' => [
'url' => env('LEAN_REDIS_URL', ''),
'scheme' => env('LEAN_REDIS_SCHEME', 'tls'),
'host' => env('LEAN_REDIS_HOST', '127.0.0.1'),
'password' => env('LEAN_REDIS_PASSWORD', null),
'port' => env('LEAN_REDIS_PORT', '127.0.0.1'),
'database' => '0',
'prefix' => 'leantime_cache',
],
],
'database' => [
'default' => env('LEAN_DB_DEFAULT_CONNECTION', 'mysql'),
/*
Expand Down Expand Up @@ -460,5 +442,36 @@
]) : [],
],
],


],

/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer body of commands than a typical key-value system
| such as Memcached. You may define your connection settings here.
|
*/
'redis' => [
'client' => 'phpredis',
'options' => [
'cluster' => 'redis',
'context' => [],
'compression' => 3, // Redis::COMPRESSION_LZ4
],
'default' => [
'url' => env('LEAN_REDIS_URL', ''),
'scheme' => env('LEAN_REDIS_SCHEME', 'tls'),
'host' => env('LEAN_REDIS_HOST', '127.0.0.1'),
'password' => env('LEAN_REDIS_PASSWORD', null),
'port' => env('LEAN_REDIS_PORT', '127.0.0.1'),
'database' => '0',
],
],


];
3 changes: 2 additions & 1 deletion app/Core/Db/Db.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ public function __construct($connection = 'mysql')
Log::error("Can't connect to database");
Log::error($e);

exit('Cannot connect to database');
throw new \Exception($e);

}
}

Expand Down
2 changes: 1 addition & 1 deletion app/Core/Http/HttpKernel.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ class HttpKernel extends Kernel
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\Leantime\Core\Middleware\TrustProxies::class,
\Leantime\Core\Middleware\SetCacheHeaders::class,
\Leantime\Core\Middleware\InitialHeaders::class,
\Leantime\Core\Middleware\StartSession::class,
\Leantime\Core\Middleware\Installed::class,
Expand All @@ -44,6 +43,7 @@ class HttpKernel extends Kernel
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\Leantime\Core\Middleware\Auth::class,
\Leantime\Core\Middleware\ApiAuth::class,
\Leantime\Core\Middleware\SetCacheHeaders::class,
\Leantime\Core\Middleware\Localization::class,
\Leantime\Core\Middleware\CurrentProject::class,
\Leantime\Core\Middleware\LoadPlugins::class,
Expand Down
14 changes: 3 additions & 11 deletions app/Core/Middleware/LoadPlugins.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,10 @@ public function handle($request, Closure $next): Response

self::dispatchEvent('pluginsStart', ['request' => $request]);

$this->pluginMiddleware = self::dispatchFilter('pluginMiddlware', $this->pluginMiddleware, ['request' => $request]);
//Good event to use for all kinds of plugin events that should run early on like adding language files
self::dispatchEvent('pluginsEvents', ['request' => $request], 'leantime.core.middleware.loadplugins.handle');

$response = app()->make(Pipeline::class)
->send($request)
->through(app()->shouldSkipMiddleware() ? [] : $this->pluginMiddleware)
->then(function ($request) use ($next) {

//Good event to use for all kinds of plugin events that should run early on like adding language files
self::dispatchEvent('pluginsEvents', ['request' => $request], 'leantime.core.middleware.loadplugins.handle');

return $next($request);
});
$response = $next($request);

self::dispatchEvent('pluginsTermintate', ['request' => $request, 'response' => $response]);

Expand Down
2 changes: 2 additions & 0 deletions app/Core/Middleware/StartSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ protected function handleStatefulRequest(IncomingRequest $request, $session, Clo
$this->startSession($request, $session)
);

self::dispatchEvent('session_started');

$this->collectGarbage($session);

//Going deeper down the rabbit hole and executing the rest of the middleware and stack.
Expand Down
7 changes: 3 additions & 4 deletions app/Core/Providers/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,22 @@ public function register()
//If redis is set up let's use redis as cache
if ($app['config']['useRedis']) {

$app['config']->set('cache.prefix', '');

//Default driver just in case it is being asked for
$app['config']->set('cache.stores.redis.driver', 'redis');
$app['config']->set('cache.stores.redis.connection', 'cache');
$app['config']->set('cache.stores.redis.prefix', 'leantime_cache');

//Only needed when using sessions with redis
$app['config']->set('cache.stores.sessions.driver', 'redis');
$app['config']->set('cache.stores.sessions.connection', 'sessions');
$app['config']->set('cache.stores.sessions.prefix', 'leantime_sessions');

$app['config']->set('cache.stores.installation.driver', 'redis');
$app['config']->set('cache.stores.installation.connection', 'installation');
$app['config']->set('cache.stores.installation.prefix', 'leantime_cache:installation');

$app['config']->set('cache.stores.'.$domainCacheName.'.driver', 'redis');
$app['config']->set('cache.stores.'.$domainCacheName.'.connection', 'cache');
$app['config']->set('cache.stores.'.$domainCacheName.'.prefix', 'leantime_cache:'.$domainCacheName.'');
$app['config']->set('cache.stores.'.$domainCacheName.'.prefix', ''.$domainCacheName.'');

}

Expand Down
1 change: 1 addition & 0 deletions app/Core/Providers/Logging.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Leantime\Core\Providers;

use Illuminate\Container\Container;
use Illuminate\Log;
use Illuminate\Support\ServiceProvider;

Expand Down
41 changes: 27 additions & 14 deletions app/Core/Providers/Redis.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,30 +22,44 @@ public function register()
*/
$this->app->singleton('redis', function ($app) {

//Setting up three different redis stores
//We are using a slightlyt diffewrent config structure and keep redis at the root level of our config

$cacheConfig = $app['config']['redis']['default'];
$cacheConfig['prefix'] = 'leantime_cache';
$cacheConfig['prefix'] = 'leantime_cache:';

$installationConfig = $app['config']['redis']['default'];
$installationConfig['prefix'] = 'leantime_cache:installation';
$installationConfig['prefix'] = 'leantime_cache:installation:';

$sessionsConfig = $app['config']['redis']['default'];
$sessionsConfig['prefix'] = 'leantime_sessions';
$sessionsConfig['prefix'] = 'leantime_sessions:';

//Prepare available redis connections
//These connections (cache, installation, sessions) can be used for sessions and cache
if ($app['config']->useCluster) {

$app['config']['redis']['clusters'] = [
'cache' => [$cacheConfig],
'installation' => [$installationConfig],
'sessions' => [$sessionsConfig],
];
//Cluster configs and prefix management works differently than regular connections
$options = $app['config']['redis']['options'];

//The default config is not needed anymore and shouldn't be used since the connection is a cluster
//connection and won't work in the standard config setup
$app['config']->set('redis.default', null);
$app['config']->set('redis.cluster', true);

$app['config']->set('redis.clusters.cache', array_merge(['options' => $options], [$cacheConfig]));
$app['config']->set('redis.clusters.cache.options.prefix', $cacheConfig['prefix']);

$app['config']->set('redis.clusters.installation', array_merge(['options' => $options], [$installationConfig]));
$app['config']->set('redis.clusters.installation.options.prefix', $installationConfig['prefix']);

$app['config']->set('redis.clusters.sessions', array_merge(['options' => $options], [$sessionsConfig]));
$app['config']->set('redis.clusters.sessions.options.prefix', $sessionsConfig['prefix']);

} else {

$app['config']['redis'] = [
'cache' => $cacheConfig,
'installation' => $installationConfig,
'sessions' => $sessionsConfig,
];
$app['config']->set('redis.cache', $cacheConfig);
$app['config']->set('redis.installation', $installationConfig);
$app['config']->set('redis.sessions', $sessionsConfig);

}

Expand All @@ -58,7 +72,6 @@ public function register()
$this->app->bind('redis.connection', function ($app) {
return $app['redis']->connection();
});

}

public function provides()
Expand Down
111 changes: 0 additions & 111 deletions app/Domain/Auth/Templates/userInvite.tpl.php
Original file line number Diff line number Diff line change
@@ -1,111 +0,0 @@
<?php
foreach ($__data as $var => $val) {
$$var = $val; // necessary for blade refactor
}
$user = $tpl->get('user');
?>
<div class="projectSteps">
<div class="progressWrapper">
<div class="progress">
<div
id="progressChecklistBar"
class="progress-bar progress-bar-success tx-transition"
role="progressbar"
aria-valuenow="0"
aria-valuemin="0"
aria-valuemax="100"
style="width: 12%"
><span class="sr-only">12%</span></div>
</div>


<div class="step current" style="left: 12%;">
<a href="javascript:void(0)" data-toggle="dropdown" class="dropdown-toggle">
<span class="innerCircle"></span>
<span class="title">
<i class="fa-regular fa-circle"></i>
Step 1
</span>
</a>
</div>

<div class="step " style="left: 37%;">
<a href="javascript:void(0)" data-toggle="dropdown" class="dropdown-toggle">
<span class="innerCircle"></span>
<span class="title">
<i class="fa-regular fa-circle"></i>
Step 2
</span>
</a>
</div>

<div class="step " style="left: 62%;">
<a href="javascript:void(0)" data-toggle="dropdown" class="dropdown-toggle">
<span class="innerCircle"></span>
<span class="title">
<i class="fa-regular fa-circle"></i>
Step 3
</span>
</a>
</div>

<div class="step " style="left: 88%;">
<a href="javascript:void(0)" data-toggle="dropdown" class="dropdown-toggle">
<span class="innerCircle"></span>
<span class="title">
<i class="fa-regular fa-circle"></i>
Step 4
</span>
</a>
</div>

</div>
</div>
<br /><br /><br />


<h2><?php echo $tpl->language->__('headlines.set_up_your_account'); ?></h2>

<?php $tpl->dispatchTplEvent('afterPageHeaderClose'); ?>
<div class="regcontent">
<?php $tpl->dispatchTplEvent('afterRegcontentOpen'); ?>

<form id="resetPassword" action="" method="post">
<?php $tpl->dispatchTplEvent('afterFormOpen'); ?>

<?php echo $tpl->displayInlineNotification(); ?>

<input type="hidden" name="step" value="1"/>

<div class="">
<input type="text" name="firstname" style="margin-bottom:15px" id="firstname" placeholder="<?php echo $tpl->language->__('input.placeholders.firstname'); ?>" value="<?= $tpl->escape($user['firstname']); ?>" />

</div>
<div class="">
<input type="text" name="lastname" id="lastname" style="margin-bottom:15px" placeholder="<?php echo $tpl->language->__('input.placeholders.lastname'); ?>" value="<?= $tpl->escape($user['lastname']); ?>" />
</div>
<div class="">
<input type="text" name="jobTitle" id="jobTitle" style="margin-bottom:15px" placeholder="<?php echo $tpl->language->__('input.placeholders.jobtitle'); ?>" value="<?= $tpl->escape($user['jobTitle']); ?>" />
</div>
<div class="">
<input type="password" name="password" id="password" style="margin-bottom:15px" placeholder="<?php echo $tpl->language->__('input.placeholders.enter_new_password'); ?>" />
<span id="pwStrength" style="width:100%;"></span>
</div>
<div class=" ">
<input type="password" name="password2" id="password2" style="margin-bottom:15px" placeholder="<?php echo $tpl->language->__('input.placeholders.confirm_password'); ?>" />
</div>
<small><?= $tpl->__('label.passwordRequirements') ?></small><br /><br />
<div class="">
<input type="hidden" name="saveAccount" value="1" />
<?php $tpl->dispatchTplEvent('beforeSubmitButton'); ?>
<input type="submit" name="createAccount" value="<?php echo $tpl->language->__('buttons.next'); ?>" />

</div>
<?php $tpl->dispatchTplEvent('beforeFormClose'); ?>
</form>
<?php $tpl->dispatchTplEvent('beforeRegcontentClose'); ?>
</div>

<script>
leantime.usersController.checkPWStrength('password');
</script>
1 change: 1 addition & 0 deletions app/Domain/Help/Composers/Helpermodal.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ public function with(): array

$currentModal = $this->helperService->getHelperModalByRoute($action);


if (
$completedOnboarding == '1'
&& $currentModal !== 'notfound'
Expand Down
4 changes: 4 additions & 0 deletions app/Domain/Ideas/Repositories/Ideas.php
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@ public function editCanvasItem($values): void
public function patchCanvasItem($id, $params): bool
{

if (isset($params['act'])) {
unset($params['act']);
}

$sql = 'UPDATE zp_canvas_items SET ';

foreach ($params as $key => $value) {
Expand Down
8 changes: 4 additions & 4 deletions app/Domain/Plugins/Services/Registration.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ public function registerLanguageFiles(array $languages)
$languageArray += parse_ini_file(app_path().'/Plugins/'.$pluginId.'/Language/en-US.ini', true);
}

if ((($language = session('usersettings.language') ?? $config->language) !== 'en-US') && in_array($language, $languages)) {
if ((($userLanguage = session('usersettings.language') ?? $config->language) !== 'en-US') && in_array($userLanguage, $languages)) {

if (! Cache::store('installation')->has($pluginId.'.language.'.$language)) {
if (! Cache::store('installation')->has($pluginId.'.language.'.$userLanguage)) {
Cache::store('installation')->put(
$pluginId.'.language.'.$language,
parse_ini_file(app_path().'/Plugins/'.$pluginId.'/Language/'.$language.'.ini', true),
$pluginId.'.language.'.$userLanguage,
parse_ini_file(app_path().'/Plugins/'.$pluginId.'/Language/'.$userLanguage.'.ini', true),
Carbon::now()->addDays(30)
);
}
Expand Down
Loading

0 comments on commit beccd6c

Please sign in to comment.