Access Controls

linas@linas.org linas@linas.org
Sat, 30 Dec 2000 01:04:23 -0600 (CST)


Hi David,

Excellent!


It's been rumoured that David Merrill said:
> > Lets assume we are using onc-rpc (or corba or xml-rpc or soap).
> > 
> > ** GUI user uses mouse to highlight transaction for editing.
> > ** xaccTransBeginEdit() sends rpc/iiop/xml message to server.
> > ** GUI user types in payee, amount
> > ** xaccTransSetDescription(), xaccTransSetAmount() are invoked
> >    by gtk code.  But no rpc's are made; no network traffic.
> > ** GUI user has finished,  clicks 'OK, commit'.
> > ** xaccTransCommitEdit() is called.  It packs up all the changes
> >    into one block, and ships that off to server via rpc. 
> > ** Server does whatever it needs to do with that data (e.g. 
> >    punches it into SQL).
> > ** Server replies 'sucess' or 'failure'
> > ** GUI pops  message 'thank you for entering that transaction.
> >    please come again'.  
> 
> Okay. I got it now.
> 
> The concurrency issue is still unresolved. Let me take a stab at it.
> 
> Option 1, no concurrent edits allowed:
> 
> client 1 -> server "I want to edit record 1"
> server -> client 1 "OK"
> 
> client 2 -> server "I want to edit record 1"
> server -> client 2 "NO"
> 
> Only one user can edit at a time. Easy to implement; can be
> frustrating to the user.

esp. if user 1 leaves for lunch, or ^C's out. 

> Option 2, concurrency allowed, changes are merged:
> 
> In order to merge changes, the db has to know the state of the data
> the user was editing, as well as the new state of the data. But a
> mechanism for retaining a complete audit trail is already in place for
> other reasons, so why not use it for this? So if we take the cvs
> approach, it could work like this:
> 
> client -> server "Here is an update to record 1"

client->server "here is what I think record 1 used to be, 
                and here's what I want it to be".

> server checks to see if record still exists in transaction table
> 
> IF YES	
    compare clients original to server's original.
    if identical, 
>       move original record to audit table
> 	save new record in transaction table
> 	server -> client "OK"
    if not identical,
        compare clients update to servers original
        if identical,
             server -> client "OK"  /* another user has already made the
                                     * same exact change */
        if not identical, 
 	     server -> client "TRY AGAIN"


> The only failure happens when two or more users have edited the same
> field concurrently. There's really nothing we can do about that but
> fail gracefully and let them re-edit if they wish.

Its better to do it record by record, not field by field, to avoid the 
following:

Two  users looking at one record and user1 thinks: geee this is
wrong, hmm the date is wrong, let me fix the date.  User2 thinks
'gee this is wrong, but if I fix the amount then ..."   If we were to
accept and merge user1 & user2 changes field by field... ughh.


> Regardless of which concurrency mechanism is used, we still have to
> provide for data changed by others but not yet updated at the client's
> machine:

corba provides an asynchronous event mechanism that soap lacks, and I
beleive onc-rpc lacks.  We could e.g. do this:

clienta->server
   "gimme records 1-100"
server: notes clienta has 1-100.  If clientb changes record 52, then
   server notes that clienta must be notified, delivers async event. 

clienta listens for events, updates when it gets one.


For rpc or xml/soap, which don't have events, I don't know how to 'roll
our own', it seems complicated. Firewalls mess things up. I've never
really fooled with 'web streaming'; it would require leaving a socket
open to the client, and then there are problems if the socket closes ... 
i.e. various ugly low-level issues. 

A traditional and somewhat klunky solution is:

client->server
     "some mesage"
server->client
     "wait, before we get into that, here are changes to stuff 
     I know you will be interested in"


Again, traditionally, the server just sends out a 'your data is now
invalid' message, allowing the client to figure out if it wants to
refresh or move on to other things.  The most polite message is 
'records 1, 23 and 42 are invalid', rather than 'everything you know is
wrong'.

There are two varients of this.
Choice A:
   server doesn't try to guesss clients state. It simply notes
   *all* changes since the client last contacted server.

  server->client
        "since we last spoke, records 1,23,42 have changed.  I have
        no clue if you even care about these records, but they changed."

Choice B:
   server tries to track client's state.  It only delivers info
   about what it thinks the client posseses.

  server->client
        "I know that once upon a time ask for record 23, and since
        since we last spoke, record 23 have changed.  
        (no mention of 1 or 42 is made).


Choise A doesn't scale well for very busy systems; however, its easier
cleaner to impelment, far less likely to be buggy.  Choice B is prone
to nasty bugs.  I vote for A.


--linas