<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    <div class="moz-cite-prefix">On 17/02/16 18:11, Bill Burke wrote:<br>
    </div>
    <blockquote cite="mid:56C4A9AC.9050508@redhat.com" type="cite">
      <pre wrap="">Currently, adding or deleting a client, or updating a realm causes 
invalidation/eviction of the realm and all clients in that realm. To 
make matters worse, the next time the realm is accessed, it queries and 
loads each client and its relationships.  Why do we do this?  When a 
realm invalidation happens, the cache has no idea if the realm is just 
being updated or removed entirely from the DB. With a realm removal, you 
also need to evict the cache of all clients within the realm.  So, a 
cached realm MUST have a list of all clients within it.  As a result, 
the more clients that get added, keycloak gets slower and slower.  
Eventually though the cache stabilizes after inserts/update/deletes 
subside and we get back to normal performance, but you can see a nasty 
blip for a little bit.</pre>
    </blockquote>
    We don't need to eagerly preload all clients when realm is loaded.
    Infinispan has streaming/predicate API and we are using it in many
    places (see InfinispanUserSessionProvider and all the stuff in
    package org.keycloak.models.sessions.infinispan.<span
      style="background-color:#e4e4ff;">stream</span>
    <meta http-equiv="content-type" content="text/html;
      charset=windows-1252">
    ). So when entry is invalidated, we can have cacheListener, which
    will query infinispan to return all cached clients of the realm and
    remove them. I can see that we already have listener. So possibly we
    can just change this line to use predicate query:
<a class="moz-txt-link-freetext" href="https://github.com/keycloak/keycloak/blob/master/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java#L141">https://github.com/keycloak/keycloak/blob/master/model/infinispan/src/main/java/org/keycloak/models/cache/infinispan/locking/LockingCacheRealmProviderFactory.java#L141</a><br>
    <br>
    <br>
    Other option is, that we can try to optimize eager preload and see
    if we can reduce number of SQL queries at startup. For example, it
    seems that CachedClient constructor sends SQL query to preload just
    realm roles. And then each client sends another SQL query to preload
    his client roles (method CachedClient.cacheRoles ). Couldn't we
    instead send one SQL query to load all roles of realm (both realm
    and client roles)? Maybe we can even send one big SQL query to load
    realm with all it's objects <span class="moz-smiley-s1"><span> :-) 
      </span></span>Possibly some FetchType.EAGER in Hibernate entities
    could help here.<br>
    <br>
    Marek<br>
    <meta http-equiv="content-type" content="text/html;
      charset=windows-1252">
    <blockquote cite="mid:56C4A9AC.9050508@redhat.com" type="cite">
      <pre wrap="">

I think i have a couple of solutions for this:

* Create a separate client cache. Client keys would be 
"{realm.id}.{client.id}".  Iterate on all client keys, and evict those 
that start with the realm id.
* Or, do a DB query for all clients of the realm.

I'm giving this until end of day to see if I can get a good solution, 
otherwise i'm aborting.

</pre>
    </blockquote>
    <br>
  </body>
</html>