[keycloak-dev] KeycloakSession question

Stian Thorgersen stian at redhat.com
Mon Apr 13 08:10:44 EDT 2015


DefaultFileConnectionProviderFactory has a single instance of InMemoryModel and a ReadWriteLock. When creating a DefaultFileConnectionProvider it obtains a read lock and passes it in to DefaultFileConnectionProvider, which is unlocked when DefaultFileConnectionProvider is closed. To write the file you could either have a background thread that does it, or just have DefaultFileConnectionProvider do it. In either case it should first obtain a write lock on the ReadWriteLock associated with DefaultFileConnectionProviderFactory. This lock makes sure that there isn't any sessions changing the model while writing to disk so you don't get inconsistencies.


----- Original Message -----
> From: "Stan Silvert" <ssilvert at redhat.com>
> To: "Stian Thorgersen" <stian at redhat.com>
> Cc: keycloak-dev at lists.jboss.org
> Sent: Monday, 13 April, 2015 2:00:28 PM
> Subject: Re: [keycloak-dev] KeycloakSession question
> 
> On 4/13/2015 2:02 AM, Stian Thorgersen wrote:
> > As I've proposed before DefaultFileConnectionProviderFactory should have a
> > ReadWriteLock. DefaultFileConnectionProvider should get a read lock. Then
> > there should be a background thread that writes the changes, this should
> > get a write lock. Simple and efficient.
> Walk me through this then.  What are you locking on?  The in-memory
> model or the file?  What is the step-by-step process?
> 
> I don't see how this is different from my proposal except that you are
> using a background thread.  But I might not be fully understanding what
> you want to do.
> 
> BTW, I'm not actively working on this.  But if I get a little spare time
> I'd like to try something that would fix the cache tests and I think
> this might do it.
> >
> > ----- Original Message -----
> >> From: "Stan Silvert" <ssilvert at redhat.com>
> >> To: keycloak-dev at lists.jboss.org
> >> Sent: Friday, 10 April, 2015 6:50:17 PM
> >> Subject: Re: [keycloak-dev] KeycloakSession question
> >>
> >> Besides needing to implement a way to make the in-memory copy, that
> >> would leave me with the same problem I have now.
> >>
> >> If I write the copy to disk, I might overwrite changes from some other
> >> KeycloakSession.  Remember, I have to write the whole model to disk and
> >> my local model might be stale.  This is the problem I have today as
> >> every KeycloakSession has its own copy that was read from disk.
> >>
> >> If I write from the master in-memory model, I need to wait for active
> >> sessions to end before I write it out to disk.  That's what I'm
> >> proposing to do.
> >>
> >> On 4/10/2015 12:28 PM, Bill Burke wrote:
> >>> Adapters are created per KeycloakSession too (RealmAdapter, etc.).  If a
> >>> write method is called on the adapter, you know that underlying instance
> >>> must be synced at commit time.
> >>>
> >>> So, here are the steps you should do:
> >>>
> >>> 1. Somebody accesses RealmModel
> >>> 2. RealmAdapter is created, it delegates to shared in-memory model
> >>> 3. If RealmAdapter write method is called copy in-memory model of
> >>> RealmAdapter, make your changes within the copy
> >>> 4. At commit, flush the changes to the RealmAdapter to main memory model
> >>> and disk.
> >>>
> >>> If you want to get more consistency, add a version field to in-memory
> >>> model, that way you can do "optimistic" concurrency and abort the sync
> >>> if the version field is changed.  We should actually probably do this
> >>> with our JPA model too.
> >>>
> >>> On 4/10/2015 11:55 AM, Stan Silvert wrote:
> >>>> On 4/10/2015 10:28 AM, Bill Burke wrote:
> >>>>> KeycloakSession is analogous to an EntityManager in JPA.  It only
> >>>>> exists
> >>>>> for the duration of the request.  What you'd want is for File-based
> >>>>> storage to queue up writes and flush them when the KeycloakSession is
> >>>>> committed.
> >>>> That's basically what happens now.  The problem is that there is no
> >>>> concept of individual writes.  Every time you write, you must write the
> >>>> entire model.  With each KeycloakSession having its own copy of the
> >>>> model, one KeycloakSession can overwrite the changes of another.
> >>>>
> >>>> If you use a single shared in-memory model, you have to wait until
> >>>> everyone is done writing to it before you can save it to disk. That's
> >>>> the scheme I outlined below.  It sounds like it will work since we know
> >>>> that each KeycloakSession will end in a timely manner.
> >>>>
> >>>>> On 4/10/2015 9:15 AM, Stan Silvert wrote:
> >>>>>> Is KeycloakSession always short-lived?
> >>>>>>
> >>>>>> If so, it might be relatively easy to make the JSON File based
> >>>>>> persistence more robust and probably fix the cache tests that
> >>>>>> currently
> >>>>>> fail with it.
> >>>>>>
> >>>>>> All KeycloakSessions would share the same in-memory model.  When a
> >>>>>> KeycloakSession ends and requests to write the model to disk, all new
> >>>>>> requests for access to the model are blocked.  When all active
> >>>>>> KeycloakSessions are done, we write out the model and unblock the new
> >>>>>> KeycloakSessions.
> >>>>>>
> >>>>>> But this only works if we can assume KeycloakSession is short-lived.
> >>>>>> _______________________________________________
> >>>>>> keycloak-dev mailing list
> >>>>>> keycloak-dev at lists.jboss.org
> >>>>>> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> >>>>>>
> >>>> _______________________________________________
> >>>> keycloak-dev mailing list
> >>>> keycloak-dev at lists.jboss.org
> >>>> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> >>>>
> >> _______________________________________________
> >> keycloak-dev mailing list
> >> keycloak-dev at lists.jboss.org
> >> https://lists.jboss.org/mailman/listinfo/keycloak-dev
> >>
> 
> 


More information about the keycloak-dev mailing list