[keycloak-dev] caching changes
Marek Posolda
mposolda at redhat.com
Wed Feb 17 15:10:19 EST 2016
Yeah, so question is if we need it? It looks to me like corner scenario
and nobody complained so far AFAIK, so maybe not...
Marel
On 17/02/16 17:06, Bill Burke wrote:
> Hibernate/JPA supports optimistic locking with a version column.
>
> On 2/17/2016 10:03 AM, Marek Posolda wrote:
>> The thing is, when admin2 press "update realm" , the data on server
>> are already updated from admin1. So he will see the value of
>> "registrationEnabled" field is true and overrides it with his value
>> false.
>>
>> It seems the possibilitity to address this might be to add "version"
>> column in DB. The version is sent to UI of admin console, but it's
>> hidden. When admin2 press "update", he will send the version back and
>> he will see that version in DB is bigger than expected, so someone
>> updated realm in the meantime.
>>
>> But I don't know if this is really issue which needs to be solved or
>> rather corner case...
>>
>> Marek
>>
>> On 17/02/16 15:44, Bill Burke wrote:
>>> Even if you have caching off this is a problem. You have to do this:
>>>
>>> * In RepresentationToModel, don't call setters on properties that
>>> have equal values
>>> * If its not already set, change hibernate to optimized updates,
>>> don't update fields that haven't changed
>>>
>>> On 2/17/2016 8:55 AM, Marek Posolda wrote:
>>>> Should this be done for user's cache too? Couldn't it happen that
>>>> same user is concurrently updated by 2 threads?
>>>>
>>>> Also wonder about scenario like:
>>>> - 2 admin users are editing realm at the same time
>>>> - Admin1 enables user's registration for the realm and click "update"
>>>> - Admin2 changed access token timeout and then click "update" .
>>>> AFAIK at this point, he overwrites the change by admin1 because we
>>>> send whole realm representation in the request.
>>>>
>>>> Do we want to address this? Or is this rather a corner case?
>>>>
>>>> Marek
>>>>
>>>>
>>>> On 12/02/16 19:47, Bill Burke wrote:
>>>>> I'm still working on stuff, but here is a summary of things so far:
>>>>> * ConcurrenyTest is passing
>>>>> * Caching implementation is now a pessimistic locking style based on
>>>>> versions. Locking never happens on reads, only writes. There are two
>>>>> caches. One cache holds the actual data, and is pretty much a
>>>>> vanilla
>>>>> invalidation cache. The other cache olds versioning information
>>>>> and is
>>>>> a local-only cache and just is an id->version map. Given an id,
>>>>> what is
>>>>> the current version of it. Hopefully, the implementation makes sure
>>>>> that you never are able to add or obtain a stale version of an object
>>>>> from the cache. Locking happens for updates. At the end of a
>>>>> transaction, all registered invalidations are iterated on, and a
>>>>> version
>>>>> cache lock on that id is obtain. The db is updated, and after
>>>>> that the
>>>>> locks are released. A lock is also obtained whever something is
>>>>> added
>>>>> to the cache. Again a lock is only obtained on the version cache, so
>>>>> any reads will never block.
>>>>> * KeycloakTransactionManager now has an enlistPrepare method.
>>>>> * There is a new RealmProvider.getClientByClientId() method.
>>>>> Clients now
>>>>> have a clientId "index" in the cache.
>>>>> * There is a new RealmProvider.removeClient() method. This was needed
>>>>> to support getClientByClientId()
>>>>>
>>>>> Some other things that were done:
>>>>> * Unnecessary @JoinTables were removed for certain @OneToMany
>>>>> relationships.
>>>>> * getId() will no longer cause a DB query if you are invoking on a
>>>>> reference to a JPA adapter
>>>>> * RealmModel.getClients() and getClientNameMap() is no longer used to
>>>>> implement getClientByClientId() :)
>>>>> * CachedRealm now stores PrivateKey, PublicKey, and Certificate in a
>>>>> transient variable. We were actually unmarshalling from the
>>>>> cached pem
>>>>> format every time these things were access, which is like few
>>>>> times per
>>>>> login.
>>>>>
>>>>> Next steps:
>>>>> * Create a client list cache for each realm. Currently, if you
>>>>> add/remove a client, this invalidates the realm cache and its doing a
>>>>> big query for each client.
>>>>> * Do some profiling to see if there's other things we can do.
>>>>>
>>>>
>>>
>>
>
More information about the keycloak-dev
mailing list