[keycloak-dev] caching changes

Bill Burke bburke at redhat.com
Wed Feb 17 09:44:40 EST 2016


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.
>>
>

-- 
Bill Burke
JBoss, a division of Red Hat
http://bill.burkecentral.com



More information about the keycloak-dev mailing list