[Building Sakai] theory about missing users in site

Noah Botimer botimer at umich.edu
Wed Mar 5 13:04:19 PST 2014


Sounds like you're on the right track then. Forcing an atomic add with a brief but wide transaction may be the best option.

Thanks,
-Noah

On Mar 5, 2014, at 3:42 PM, Charles Hedrick wrote:

> The JSP operates through the API. It doesn’t do commits. It assumes that a save does the right thing.
> 
> My guess: people don’t adjust membership of a site manually that often, and if they do, having it take 10 min to stabilize isn’t an issue. They don’t do it in such a way that two people are editing the site on different front ends and conflict. There’s no real locking on site and group updates. We just assume the site manage isn’t used in a way that will cause conflicts. But if you do things programmatically, that may no longer be true.
> 
> What’s unusual about this is lots of adds to a site occurring on multiple front ends, and people expect to be able to use it immediately. That not an issue, because a user ends upon logged in on the same   front end where they were added to the site.
> 
> This usage is similar to Lesson’s use of groups. We add people to groups to control tool access. We also had race conditions until I started using joinGroup with the optional last argument. (Without it there’s no locking in the low-level code. Passing Integer.MAX as the last value causes a SELECT FOR UPDATE and then an insert, which makes things work. I ended up using the same code as Lessons, though with an additional complication because I need to add the user before they login.I now do session.setUserId to the user, joinGroup, and then set it back to null (because they’re not logged in). Then I do a real login.
> 
> 
> On Mar 5, 2014, at 3:26 PM, Noah Botimer <botimer at umich.edu> wrote:
> 
>> There should be a cluster-wide membership invalidation on any changes. If something has disrupted that, it is almost certainly a bug.
>> 
>> I think you identify some important items here. An atomic add/remove with cache invalidation would narrow the window in terms of time. Committing only the delta would narrow the window in terms of scope.
>> 
>> Given that this is not a problem that has come up with any regularity, I wonder if site-manage is doing anything special to mitigate the issue. I don't think it is, so I suspect that the invalidation isn't firing for some reason, though it just might not come up with site-manage since site admin is usually pretty single-threaded. Anyway, with invalidation alone, the window should be somewhere in the neighborhood of one second. i would expect one of the users to see the problem immediately, not some minutes into a test.
>> 
>> Is it at all possible that the JSP is doing something strange with transactions? Specifically, is the add committed to disk immediately (ruling out a dangling transaction waiting for a full commit/rollback)?
>> 
>> Thanks,
>> -Noah
>> 
>> On Mar 5, 2014, at 11:10 AM, Charles Hedrick wrote:
>> 
>>> I have a site that any user can join. It’s used for training people, and documenting that they have been trained.
>>> 
>>> They use a JSP that joins them to the site and then puts them into it. They take a test in the site. but 15 min into the test, they are suddenly no longer in the site.
>>> 
>>> Here’s my theory:
>>> 
>>> The code in the JSP was
>>> 
>>> + 	         AuthzGroup realmEdit = AuthzGroupService.getAuthzGroup(realmId);
>>> + 	         realmEdit.addMember(email, role, true, false);
>>> + 	         AuthzGroupService.save(realmEdit);
>>> 
>>> But I think this code has a race condition. I believe getAuthzGroup will get a cached version of the realm. So it could be out of date. If a user is added on one front end, the next user could fetch an old version of the realm, add to that, and save it, thus losing the first user. The next time the first front end refreshes its cache, the user will be out of the site.
>>> 
>>> What I’m trying as a fix is to use joinGroup. This appears to be race-free, because it uses SQL that does an add.
>>> 
>>> In my case it has a problem, in that joinGroup always works on the current user. I want to do this before the login. I can fake it, but it would be convenient to have addUser and removeUser operations that specify a user.
>>> 
>>> The situation would be better if there were a getAuthzGroupEdit, that always fetched from the database. That would limit the race condition to a fairly small window.
>>> 
>>> Another approach would be for the AuthzGroup object to have a duplicate copy of all the fields.The save operation does’t wipe out the group and recreate it. It quite intelligently compares current and new value ,and make the appropriate changes. But you really want to compare with the original value of the object, not the current database.
>>> 
>>> Consider
>>> 
>>> getAuthGroup returns {Smith{
>>> someone on another front end adds Jones
>>> the program adds White
>>> the program saves {Smith, White}
>>> 
>>> You want to compare the new value, {Smith, White} against the original value when the group was fetched, i.e. {Smith}. That will cause you to add White. The code compares it with the current database, which is {Smith, Jones}, thus causing it to delete Jones and add White.
>>> 
>>> 
>>> _______________________________________________
>>> sakai-dev mailing list
>>> sakai-dev at collab.sakaiproject.org
>>> http://collab.sakaiproject.org/mailman/listinfo/sakai-dev
>>> 
>>> TO UNSUBSCRIBE: send email to sakai-dev-unsubscribe at collab.sakaiproject.org with a subject of "unsubscribe"
>> 
> 

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://collab.sakaiproject.org/pipermail/sakai-dev/attachments/20140305/47fb8cbe/attachment.html 


More information about the sakai-dev mailing list