Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom setting store doesn't use cache (or incorrect instructions) #168

Open
bjhijmans opened this issue Dec 7, 2022 · 4 comments
Open

Comments

@bjhijmans
Copy link

bjhijmans commented Dec 7, 2022

I had to extend the DatabaseSettingStore for some unimportant reasons. So I followed the instructions in the readme and added the a new class:

class CustomDatabaseSettingStore extends Base
{
    public function __construct(Connection $connection)
    {
        parent::__construct(
            $connection,
            config('settings.table'),
            config('settings.keyColumn'),
            config('settings.valueColumn')
        );
    }
    // more code here
}

and I added the following to my AppServiceProvider:

Setting::extend('customDatabaseSettingStore', function ($app) {
    return $app->make(CustomDatabaseSettingStore::class);
});

I have caching enabled, but I found the setting cache suspiciously empty. So I checked, and it turns out that caching settings are never set in the custom store, and I think defaults also don't work. These are usually set in SettingsManager::wrapDriver() which is never called.

I had to add the code from wrapDriver() to my custom store:

class CustomDatabaseSettingStore extends Base
{
    public function __construct(Connection $connection)
    {
        parent::__construct(
            $connection,
            config('settings.table'),
            config('settings.keyColumn'),
            config('settings.valueColumn')
        );

        $this->setDefaults(config('settings.defaults'));

        if (config('settings.enableCache')) {
            $this->setCache(
                app()['cache'],
                config('settings.cacheTtl'),
                config('settings.forgetCacheByWrite')
            );
        }
    }
// more code
}

I think, at the very least, the readme should be updated. I was very surprised that this was needed, especially because it is usually handled by the SettingsManager, which I wouldn't have expected to have to look at. I would prefer if wrapDriver() was somehow called for custom drivers, but it would already be helpful if it were public and easily accessible.

@anlutro
Copy link
Owner

anlutro commented Dec 9, 2022

Hello! This makes total sense. Laravel's Manager class doesn't provide convenient hooks to do the kind of things I wanted with wrapDriver but I think this is achievable with #169.

Do you want to pull the version dev@fix-wrapdriver-custom-store to see if that fixes your issue before I merge?

@bjhijmans
Copy link
Author

Hey! That looks good. I can check it out when I'm back at work on Monday.

I'm not sure about your decision to make it a separate class, though. There's already a setting to disable the cache. I don't see the added value to using a separate class AND a config setting to enable it.

@anlutro
Copy link
Owner

anlutro commented Dec 10, 2022

The extra class is two-fold: It's a way to detect whether the store should support caching (the in-memory one doesn't make sense, for example), and it's to be backwards compatible - the current custom stores don't support caching (as you pointed out) so now this is opt-in behavior with a new class.

I'm not entirely convinced this is the correct approach, especially not having worked with Laravel for more than 5 years now, but it feels right.

@bjhijmans
Copy link
Author

I checked it out. There's a bug currently, readData() is private in both SettingStore and CachedSettingStore, but it is called from SettingStore, so it calls that version and skips caching. It works fine if they're both protected.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants