spiritix / lada-cache Goto Github PK
View Code? Open in Web Editor NEWA Redis based, fully automated and scalable database cache layer for Laravel
License: MIT License
A Redis based, fully automated and scalable database cache layer for Laravel
License: MIT License
The reflector concept should be removed and replaced with a single reflector based on Query\Builder.
After having this implemented it won't be required anymore to extend the Lada Cache model.
Laravel: v5.6.16
Trying to run lada-cache:flush before a new migration (and also trying to run the db:seed command)
generates a redis error:
panel.vm $ php artisan lada-cache:flush
Predis\NotSupportedException : Cannot use 'KEYS' with redis-cluster.
This is my database.php config:
'redis' => [
'client' => 'predis',
'options' => [
'cluster' => 'redis',
],
'clusters' => [
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
],
They are quite basic at the moment. We should not mock these very basic QueryBuilders and Models but instead have testing stubs and use them like real world examples.
Hey,
Great package, thanks for releasing and maintaining this.
I currently have a problem that I just noticed, it was fine until a few hours ago.
The cache on my website doesn't get cleared when new "items" get added to the database. It doesn't happen with every model, just with a particular one.
It's quite odd to describe and it works just fine on my local env.
Here's a URL in case you want to see it: https://insegreto.com/it/fresh
In that page you'll find a list of posts. New posts are not visible until I manually clear the cache but you can see new comments right away.
I know the info is not much, but maybe you have already an idea of what's happening? Or maybe you can recommend a way to debug this?
--- EDIT
More info. I'm using Envoyer to manage my deployments and after re-deploying (same code) everything is working as expected. I would expect though to have the same issue again in a few hours. Will keep posted.
--- EDIT #2
So.. after 6 hours, here we go again. Same issue. This time, re-deploying didn't fix the issue. I had to run php artisan lada-cache:flush
.
Just wondering if there is a way to bypass the cache. For example, while doing a cron job and wanting direct query result, not a cached version. Or, do I simply need to flush the cache before doing the cron job?
Thanks
Hey there,
first of all, very great package! but i've got a problem having a user and group model
where group has users() and user has groups() many-to-many relation.
for some reason if i update the relation from user model everything is fine. but if i update from group model the old relations stay cached and won't show.
any idea on why that is?
i'm pretty new to laravel and couldn't fine the hook u use to detect and flush cache on using attach() or detach() where are those located?
[EDIT] this is what i do for the update:
$group->display_name = Input::get('display_name');
$group->description = Input::get('description');
$group->save();
// remove all existing users and set only checked
if (\Auth::User()->can('group-assign-user')) {
$group->users()->detach();
$new_users = (Array)Input::get('users');
foreach ($new_users as $user) {
$group->users()->attach($user);
}
}
When trying to use withCount() on a belongsToMany relationship, it fails with this message:
Argument 1 passed to Spiritix\LadaCache\QueryHandler::setBuilder() must be an instance of Spiritix\LadaCache\Database\QueryBuilder, instance of Illuminate\Database\Query\Builder given, called in /home/vagrant/project/vendor/spiritix/lada-cache/src/Spiritix/LadaCache/Database/QueryBuilder.php on line 84
If I removed lada-cache trait, it returns the expected count. I'm using this on hasMany relationships too. lada-cache seems to work fine with those.
Any ideas on how to fix this?
Hello
Running the command php artisan scout:import App\Model it results in a fatal error thrown by lada cache:
Allowed memory size of 268435456 bytes exhausted (tried to allocate 20480 bytes) in /home/runcloud/webapps/laravel-vivicity/vendor/spiritix/lada-cache/src/Spiritix/LadaCache/Encoder.php on line 43
At the moment it is hardcoded in Illuminate\Database\Eloquent\Model::newBaseQueryBuilder.
If we could find a way to override it, the model class would not be required anymore.
Note that since Laravel 5.7
php artisan cache:clear
will not clear the default REDIS connection that lada-cache is configured to use (and doesn't appear to have any way to change)
This means that currently lada-cache is using the 'database' configuration of REDIS in Laravel (called 'default') (for things like sessions) and not the 'cache' configuration (called 'cache') .
The only work around I can see at the moment, is to change the redis cache configuration in Laravel (/app/config/cache.php) to have it's connection set to the 'default' and not 'cache'.
This of course undoes the reason it was changed in the first place, doing php artisan cache:clear
will also delete anything placed in the REDIS 'database' configuration (i.e. sessions and the like)
It seems like its not working when I have multiple database connections.
https://laravel.com/docs/5.5/database#using-multiple-database-connections
Is there any ETA for Laravel 6 support? And will there be Lumen support also?
Some files must be excluded from Code Climate checks since they are copy-pasted from Laravel or part of the unit tests. See here.
Seems to be not working:
https://codeclimate.com/github/spiritix/lada-cache/tests/TaggerTest.php
I have built a read-only API that does heavy database querying and would like to use this project. I tried to install and it failed at vendor:publish
with the following error.
I'm asking this with the an anticipation that it requires less work to support Lumen. If not, that's fine, let me know. Thanks!
php artisan vendor:publish
PHP Fatal error: Call to undefined method Laravel\Lumen\Application::share() in /Users/bhargav/Projects/myfyba/api/vendor/spiritix/lada-cache/src/Spiritix/LadaCache/LadaCacheServiceProvider.php on line 138
Fatal error: Call to undefined method Laravel\Lumen\Application::share() in /Users/bhargav/Projects/myfyba/api/vendor/spiritix/lada-cache/src/Spiritix/LadaCache/LadaCacheServiceProvider.php on line 138
[Symfony\Component\Debug\Exception\FatalErrorException]
Call to undefined method Laravel\Lumen\Application::share()
This project looks great, but I had some technical questions about how lada-cache actually works.
Without looking at the actual source code it is difficult to understand what is actually happening, which, I believe, is an important factor to decide if this library is right for me.
They are not tested at the moment.
Hey,
thanks a lot for making this awesome package.
I'm playing around with it and it seems to do everything I need, but wanted to ask if will reliably cache nested queries like the following (If I add primary keys named ID to all pivot tables):
Would this create different cached versions for the below query based on the dynamic variables, or would the dynamic parts invalidate the cache every time a visitor hits my site from another country, OS, device type etc.
return $this->domain->load([
'advertisers' => function ($q) {
$q->with([
$this->adsRelationship => function ($q) {
$q->whereHas('countries', function ($q) {
$q->whereIn('key', [session('country_code'), 'XX']);
})
->whereHas('operatingSystems', function ($q) {
$q->whereIn('key', [session('os'), 'all']);
})
->whereHas('deviceTypes', function ($q) {
$q->whereIn('key', [session('device_type'), 'all']);
})
->whereHas('browsers', function ($q) {
$q->whereIn('key', [session('browser'), 'all']);
})
->when($this->adType == 'images', function ($q) {
$q->with([
'cpaBanners' => function ($q) {
$q->whereHas('adSize', function ($q) {
$q->where('size', '=',
$this->width . 'x' . $this->height);
});
}
]);
})
->when($this->adType == 'contextuals', function ($q) {
$q->whereHas('adSize', function ($q) {
$q->where('size', '=',
$this->width . 'x' . $this->height);
});
})
->when($this->adType == 'urls', function ($q) {
$q->doesnthave('cpaBanners');
})
->when($this->adType == 'snippets', function ($q) {
$q->doesnthave('adSize');
});
}
]);
}
]);
Also, am I correct that once Installing Lada, I should remove all calls to "Cache::remember()" in my controllers for it to work as intended?
Thank you! :) 👍
How To Use This If i Using Jens MongoDB on Laravel ?
can i modified and extends Jens MongoDB Class Model To src/Spiritix/LadaCache/Database/Model only or i modified too all of in this folder src/Spiritix/LadaCache/Database/ ?
sample src/Spiritix/LadaCache/Database/Model.php
`
I have observed that though Lada-cache works for the most part, when it comes to eloquent relationships, the cache invalidation doesn't seem to work as expected.
For example:
$this->belongsToMany('App\Models\TableClass1','TableClass2','table_class1_id','table_class2_id');
The above relationship is cached properly during all the read operations for TableClass1, but if any row of TableClass1 or TableClass2 is modified, it purges the cache for the subsequent relationship for all rows of TableClass1/2.
The problem is very much similar to as reported in Issue #11 ( Just that this time its related to eloquent relationship).
In the new 1.2 version there seems to be a problem with Model::firstOrNew function which somehow bypasses the lada-cache QueryModel
[Symfony\Component\Debug\Exception\FatalThrowableError]
Type error: Argument 4 passed to Spiritix\LadaCache\Database\QueryBuilder::__construct() must be an instance of Spiritix\LadaCache\QueryHandler, none given, called in /home/vagrant/www/panacea/vendor/l
aravel/framework/src/Illuminate/Database/Query/Builder.php on line 2070
Nothing there at the moment
I use $product->withCount('screens')->get();
On $screen->destroy($id), screens_count not updated.
It's probably because the directory names for the migrations are lower case.
Can we have traits instead of all models extending the Spiritix\LadaCache\Database\Model class? It would make more sense if lada-cache going forward uses traits for peaceful co-existence with other classes.
Let's say I have an article table with 100k articles and 100 of those articles are being opened constantly every second so I would need to cache each of those articles. So far so good.
But once I update one article all of the caches for other articles are purged even though I only need the cache for the specific article that I changed to be purged.
I debugged a bit and saw that :table:article:row:28
is being invalidated and also :table:article
and I'm guessing that invalidating :table:article
tag causes the issue?
If I set considerTables = false in Tagger.php then cache doesn't seem to be invalidated at all even though there still is the :table:article:row:28
tag
I have a model (table) companies
id (index key), companyname, address, phone
I also have a model (table) categories
id (index key), category
this relation is many to many, companies may have many categories and one category may have many companies. For that reason I created a table companies_categories
id_company (index key), id_category (index key)
My question is if lada cache with the current logic will cache everything included the relation with row invalidation? As you see I have assigned both tables with primary key "id" but the relation table has no "id" and I am not sure how this will work.
If you debug here:
you can see that tags are not prefixed with the lada:
prefix
output from redis-cli monitor
1474295382.561930 [2 127.0.0.1:57456] "EXISTS" "lada:tags:database:receptes:table:taxonomy_group"
1474295382.567505 [2 127.0.0.1:57456] "SMEMBERS" "lada:tags:database:receptes:table:taxonomy_group"
1474295382.567958 [2 127.0.0.1:57456] "EXISTS" "lada:tags:database:receptes:table:taxonomy_group:row:6"
1474295382.568279 [2 127.0.0.1:57456] "SMEMBERS" "lada:tags:database:receptes:table:taxonomy_group:row:6"
1474295382.572728 [2 127.0.0.1:57456] "DEL" "lada:ca4f3478a25b1a65e6ba63b3d486464b"
1474295382.573023 [2 127.0.0.1:57456] "DEL" "lada:8878cfb82fadfd146ec585caa3b9df35"
1474295382.573387 [2 127.0.0.1:57456] "DEL" "lada:239982319ac7e7e3bde82a09befe8db7"
1474295382.573605 [2 127.0.0.1:57456] "DEL" "tags:database:receptes:table:taxonomy_group"
1474295382.573867 [2 127.0.0.1:57456] "DEL" "tags:database:receptes:table:taxonomy_group:row:6"
The cache is working properly, but something must be wrong with the debug bar collector. It marks all cache requests as [Hit], even right after the cache is flushed.
Hi
Using Model::selectSub($subQuery, 'foo')
doesn't work using LadaCacheTrait
The error is
Argument 1 passed to Spiritix\LadaCache\QueryHandler::setBuilder() must be an instance of Spiritix\LadaCache\Database\QueryBuilder, instance of Illuminate\Database\Query\Builder given, called in D:\Progetti\laravel-vivicity\vendor\spiritix\lada-cache\src\Spiritix\LadaCache\Database\QueryBuilder.php on line 94
Currently the library is written for 5.1 LTS.
Test if everything works well with 5.2.
If backwards incompatible changes are required to get it running, create a new repository for 5.2.
In the service provider on line 57:
if (class_exists('Barryvdh\\Debugbar\\LaravelDebugbar')) {
$this->registerDebugbarCollector();
}
This throws major errors if you have DebugBar installed but not enabled.
I had to create my own provider and check the container for debugbar:
if ($this->app->offsetExists('debugbar')) {
$this->registerDebugbarCollector();
}
would be a much better solution.
Or simply make registerDebugbarCollector()
public so it can be overloaded.
Why Lada Cache require php 5.6?
Laravel 5.2 require php 5.5.9 so I think if Lada Cache can require same php as laravel. It's will make another people can use this library easier.
Do you have plan to make it as traits?
I think traits is better more than extend class and user can use it easier.
Would it be possible to use lada to cache the logged in user to avoid reading the database on every request? As lada doesn't support it out of the box, I am using this plugin https://github.com/hobbiot/cacheable-auth-user but I was wondering if I can use lada for this as well.
What is the default expiration time and is it possible to specify custom expiration time?
Let's say I need a list of 10 latest articles whose publish date is less than current time
Example
Article::where('published_at', '<', \DB::raw('now()'))->orderBy('published_at', 'desc')->paginate(10)
It would be great if it would be possible to set how long to cache this query, since displaying articles depends on the current time and we wouldn't want the query to be cached longer than 2 minutes
I guess the problem could be solved by creating a cron that polls the database every minute and finds all the articles whose published_at is less than current time and is_visible is 0 and sets it to 1 and then in the pagination query we just try to find all articles whose is_visible is 1, but I'm not sure if this would be the best or simplest approach instead of just setting a small expiration time for query.
Unfortunately it seems like orchestral/testbench is not able to handle Artisan commands in unit tests.
It provides the method $this->artisan(...), but always throws an exception.
Not working at the moment.
It would result in all models getting cached but not invalidated properly. This is because the class who writes values in the cache doesn't know which models are extending the cache model.
Also I am not sure what would happen if you join a model that is cached from a model which is not cached.
Using locking mechanisms requires usage of raw sql queries to bypass Lada Cache.
https://laravel.com/docs/5.6/queries#pessimistic-locking
I'm using lockForUpdate, but it obviously won't work if there is caching in-between, because it is not possible to tell the DB to lock something if we never even reached the DB right? 😸
The solution is simply resort to raw query i.e. using the \DB::xxx statements.
Here is an example that I use to bypass Lada Cache and then transform result array back into model object:
$table = (new YourAmazingModel())->getTable();
$items = \DB::table($table)
->lockForUpdate()
->where(' ... filter results ... ')
->orderBy('id', 'asc')
->take(15)
->get();
// Transform array to YourAmazingModel
foreach ($items as $key => $item) {
$items[$key] = (new YourAmazingModel())->newFromBuilder((array)$item);
}
$items = collect($items);
// Now you can loop $items and update them as necessary to release the row locks
Note: Do not forget to wrap your code in transaction so that you can revert the lock in case of exception and avoid deadlocks.
Hello,
I am trying to fetch customers that billing_details.collective_bill = true
. So at the first time the query gets cached everything works fine but if i enable or disable a customers billing_details.collective_bill
the relation gets invalidated but it isn't updated or invalidating the query below. So i am getting the cached results.
Customer::with([
'billing_details.accounting_period',
'latest_collective_invoice' => function ($query) {
$query->select(['id', 'client_id', 'customer_id', 'created_at']);
},
'orders_interpret' => function ($query) {
$query->select(['id', 'customer_id', 'status_id'])
->with(['invoice'])
->withoutInvoice(OrderStatusType::CollectiveInvoice);
},
'orders_translate' => function ($query) {
$query->select(['id', 'customer_id', 'status_id'])
->with(['invoice'])
->withoutInvoice(OrderStatusType::CollectiveInvoice);
}
])
->whereHas('billing_details', function ($query) {
$query->where('collective_bill', true);
})
->where(function ($query) {
$query->where(function ($query) {
$query->whereHas('orders_interpret', function ($query) {
$query->withoutInvoice(OrderStatusType::CollectiveInvoice);
});
})
->orWhere(function ($query) {
$query->whereHas('orders_translate', function ($query) {
$query->withoutInvoice(OrderStatusType::CollectiveInvoice);
});
});
})
->get();
this error broke my site on production, when i have cache for compiled classes, and every time LadaCacheServiceProvider do call to:
protected function mergeConfigFrom($path, $key)
{
$config = $this->app['config']->get($key, []);
$this->app['config']->set($key, array_merge(require $path, $config));
}
there is error what i got:
ErrorException: Exception 'ErrorException' with message 'array_merge(): Argument #2 is not an array' in /var/app/current/bootstrap/cache/compiled.php:4967
Sample stack trace
in Illuminate\Foundation\Bootstrap\HandleExceptions::handleError called at ? (?)
in array_merge called at /var/app/current/bootstrap/cache/compiled.php (4967)
…vendor/spiritix/lada-cache/src/Spiritix/LadaCache/
LadaCacheServiceProvider.php (55)
in Spiritix\LadaCache\LadaCacheServiceProvider::boot called at ? (?)
in call_user_func_array called at /var/app/current/bootstrap/cache/compiled.php (1187)
…tainer\Container::call called at /var/app/current/bootstrap/cache/
compiled.php (1808)
…lication::bootProvider called at /var/app/current/bootstrap/cache/
compiled.php (1800)
in Illuminate\Foundation\Application::Illuminate\Foundation\{closure} called at ? (?)
in array_walk called at /var/app/current/bootstrap/cache/compiled.php (1801)
…tion\Application::boot called at /var/app/current/bootstrap/cache/
compiled.php (2139)
…otProviders::bootstrap called at /var/app/current/bootstrap/cache/
compiled.php (1587)
…ication::bootstrapWith called at /var/app/current/bootstrap/cache/
compiled.php (2303)
…Http\Kernel::bootstrap called at /var/app/current/bootstrap/cache/
compiled.php (2256)
…ndRequestThroughRouter called at /var/app/current/bootstrap/cache/
compiled.php (2240)
…ate\Foundation\Http\Kernel::handle called at /var/app/current/public/
index.php (55)
whereHas don't updated on cache
I use https://github.com/jenssegers/laravel-mongodb/ and I use it in combination with mysql.. it works great and most packages also work out of the box.. but this one I'm not so sure since it interacts a lot with eloquent and laravel-mongodb uses its own eloquent sort of
I have a problem. At some point of time the cache of the following request ceases to be updated for the unknown reasons.
$newProducts = $product->catalogItem()
->whereNotNull('available')
->whereNull('preorder')
->orderBy('release_date', 'desc')
->limit($limitProductsOnTabs)
->get();
public function scopeCatalogItem($query)
{
return $query->select('products.id', 'image', 'name', 'rrp', 'wmr', 'activation_id', 'slug', 'has_discount', getNameCurr())->with('activation')->with('genres');
}
But the page of product is successfully cached. Why?
Is this working for shared hosting? As i known redis is not working. Redis want your own server. I am looking to implement a cache system all of our project. Thanks in advance.
when i dont want lada
i run the artisan command to disable it and it told me
Cache disabled
but when i changed to file cache this appears
BadMethodCallException in Repository.php line 367:
This cache store does not support tagging.
We should test all types of relations and complex queries.
The factories and models are already prepared.
It would be great to have sample queries for all cases and have them tested automatically.
The above error is thrown when using Laravel 5.7 Sub-Query Joins
$payments = Payment::groupBy('file_id');
$files = File::join('clients', function ($join) {
$join->on('clients.id', '=', 'files.client_id')
->where('clients.active', 1)
->whereNull('deleted_at');
})->leftJoinSub($payments, 'payments', function ($join) {
$join->on('files.id', '=', 'payments.file_id');
})->select('files.*')
->addSelect(DB::raw('SUM(payments.amount) as total_paid'))
->take(10)
->get();
dump($files);
Any way to deal with this?
Just tried to install with 5.4, and getting this error from composer require:
...
> php artisan optimize
[Symfony\Component\Debug\Exception\FatalThrowableError]
Call to undefined method Illuminate\Foundation\Application::share()
Script php artisan optimize handling the post-update-cmd event returned with error code 1
Does lada-cache support 5.4?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.