Paradigms for CGI application development?

David Dick david_dick at iprimus.com.au
Wed Nov 6 14:34:18 CST 2002



Scott Penrose wrote:

>> How do people get around these problems?  Why is the code for web app 
>> UIs very different to that of desktop app UIs?  I suppose some of 
>> these problems could be solved if the web server kept the running 
>> program in memory across requests (instead of starting a new instance 
>> each time), but I don't know of any system that does this.  Are there 
>> any?  (And I haven't thought about it much, but I suspect this 
>> approach would also be horribly complicated too, albeit in different 
>> ways.)
>
>
> I have seen LOTS of software around for coping with State, and keeping 
> the persistence of an object. But in all cases I have not seen the 
> concept of your example.
>
>   sub transfer_part1 {
>     # ...
>     confirm("Really transfer?", "transfer_part2");
>   }
>
>   sub transfer_part2 {
>     my ($result) = @_;
>
>     if ($result) {
>       # DO TRANSFER
>     }
>
>     else {
>       # ABORT TRANSFER
>     }
>   }
>
> Where 'confirm' above basically would trigger.
>
>     - Save the current state and location
>     - Generate a web page and appropriate URL
>
> And then on return the code would have to
>
>     - Reauthenticate the request (make sure it is the same user and 
> same request)
>     - Check it has not timed out
>     - Restore states
>     - Jump back into location.
>
> Of course the save and restore states are not necessary, the 
> application could continue to run (this is the idea of the agents talk 
> that Danger gave a few months ago).
>
> Now we can simplify it a little by...
>
> Where 'confirm' above basically would trigger.
>
>     - Generate a web page and appropriate URL to return
>
> And then on return the code would have to
>
>     - Reauthenticate the request (make sure it is the same user and 
> same request)
>     - Return from the method.
>
> This is tricky but no impossible. The idea is quite nice in that you 
> would be generating simple dispatch mechanisms, we now need to only 
> know which of the 'agents' we need to talk back to.
>
> The tricks would be around clean up (like all stateful implementations 
> across a non stateful protocol). eg: the 'confirm' method would have 
> some type of timeout, which then returns with fail somehow.

i would have thought that the correct way of looking at it is not trying 
to emulate a GUI environment at all.  The problem essentially (unless i 
have missed something :)) is that we want a confirmation step and we 
want to be assured that the transfer only happens _once_.

This can be achieved with a minimum of fuss with the following steps.

provide a confirmation screen that has the details of the transfer with 
a confirmation URL something like

/transfer?State=Confirm&TransferId=[% transfer_id %]&LastUpdated=[% 
last_updated %]&LastUpdatedBy=[% last_updated_by %]&

where the transfer_id is the UID for the Transfer Object and the 
last_updated and last_updated_by fields are a representation of who and 
when last modified this transfer object.

assuming that the business has no processes at all... no names, no pack 
drill :), multiple people can all get to this same step and attempt to 
confirm the transfer at the same time.

therefore the transfer script (when it gets a State=Confirm etc, etc) must

1) Obtain a write lock on the transfer object (SELECT....FROM transfer 
WHERE transfer_id = $transferId FOR UPDATE)
2) Compare (SELECT last_updated_by, last_updated FROM transfer WHERE 
transfer_id = $transferId) with the LastUpdated and LastUpdatedBy values 
obtained via  $cgi->param().
3) If they are the same, then no-one has modified the object since we 
last looked at it.  If they are not the same, error out with a message 
telling the user that the object has
been modified since they last saw it.
4) If no-one has modified the object since we last looked at it, confirm 
the transfer (UPDATE transfer SET status = 'Confirmed', last_updated = 
$currentTime, last_updated_by = $currentUser)
5) Release the write lock on the transfer (COMMIT)

so long as these steps are followed, there will not be a drama with 
multiple successful confirmations.

>
> Also in a normal application, if another application is run, we can 
> usually say 'sorry locked, exit the other one first'. We can't do that 
> in Web, as it may be that the application is no longer accessible (eg: 
> browser crashed and lost session id), so we have to offer the user a 
> way of force quitting the application.
>
> There are many bits of software out there to handle state and dispatch 
> mechanisms to allow the request/confirm/do or cancel approach above, 
> but all that I have seen require new entry points for each, and an 
> object to hand around. Has anyone seen any code to do what Michael is 
> suggesting above, and jump from the middle of a routine, like you 
> would processing in a normal application.?

I've never this sort of code in a package, but i can't think how to put 
it in a package.  As stated previously, my best effort is to write a 
template once and then modify the template for each new job.  So I have 
no idea basically... :)





More information about the Melbourne-pm mailing list