[Cosmo-dev] Cosmo WebUI Service Layer
Bobby Rullo
br at osafoundation.org
Sat Mar 10 10:22:03 PST 2007
>>
>
> First, I understand the "organizational argument" here, this might
> be a nicer way to organize the problem. So you've got me partially
> convinced there..
>
> Let's think quickly about what the Transport/Format Abstraction
> Layer (TAL) will need to look like:
>
> 1) We need it to support asynchronous or synchronous calls
> 2) We need to support multiple authentication methods (ticketed vs.
> owned by current user)
>
Right.
> From some offline chatter, I think you're thinking the TAL will
> look like:
>
> cosmo.tal.json = {
> saveItem(arg1, arg2, ..., transportInfo){},
> ...
> other Item CRUD methods
> ...,
> getCollections(arg1, arg2, ..., transportInfo){}
> ...
> }
>
Yes, more or less.
> one way to implement saveItem would look like (apologies for the
> handwaving, and leaving out details about how the "synchronicity"
> of a call is passed):
>
> saveItem(item, transportInfo){
> convert Item to JSON representation;
> if (call is synchronous) {
> if (transportInfo.ticketKey){
> jsonrpc-service.saveItem(item, ticketKey)
> else (){
> jsonrpc-service.saveItem(item)
> }
> }
> else{
> if (transportInfo.ticketKey){
> jsonrpc-service.saveItem(asyncHandlerMethod, item, ticketKey)
> else (){
> jsonrpc-service.saveItem
> (asyncHandlerMethod, item)
> }
> }
> }
>
More or less, but I don't like using the existence of a certain
property to figure out the type of an object. So more like:
...
if (transportInfo instanceof Ticket){
service.save(item, transportInfo.ticketKey);
} else if (transportInfo instance of XXXX{
//etcetera
}
...
And I'm sure that you could figure out a way not to have to do that
logic twice, once for sync and async.
>
> another possible implementation would be:
>
> ticketedSaveItem(item, transportInfo){
> convert Item to JSON representation;
> if (call is synchronous){
> jsonrpc-service.saveItem(item, ticketKey)
> } else (){
> jsonrpc-service.saveItem(ayncHandlerMethod, item, ticketKey)
> }
> }
> ownedSaveItem(item, transportInfo){
> convert Item to JSON representation;
> if (call is synchronous){
> jsonrpc-service.saveItem(item, ticketKey)
> } else (){
> jsonrpc-service.saveItem(ayncHandlerMethod, item, ticketKey)
> }
> }
>
> This looks a lot like what we have in 0.6, except we have
> TicketedConduit.saveItem and OwnerConduit.saveItem.
>
> A third option is to implement synchronousSaveItem and
> asynchronousSaveItem along these lines.
>
> Whichever way you cut it, when you change transport layers you'll
> need to reimplement all of this, which I think would be pretty
> close to reimplementing "all four conduits."
Yes, I see what you mean.
>
> To look at this another way:
>
> In my proposal as posted, Conduits are responsible for several things:
> 1) Talking to the transport layer
> 2) Marshalling raw data into useful JS Objects that look like we
> want them to
> 3) Providing a useful API to client code (the UI)
> 4) Publishing to appropriate Topic channels on after (and before?)
> calls
> 5) (?) Providing some minimal error handling (perhaps mapping some
> server side exceptions to more useful client side exceptions)
>
> Which of these things to you think should go into the Transport
> Abstraction Layer?
>
Just one and two I think. Of course that IS the meat of it. I
envision the conduits as really just there to encapsulate enough
information to figure out how to make the appropriate TAL calls and
publish some topics perhaps.
Frankly, I'm not feeling 100% about it myself, but I just wanted an
interface to code to which allows you to specify different types of
collections (subscribed, owned) without having to know how exactly
you get them over the wire.
It does seem like a bit of a code smell to have yet another place
where there's just a bunch of proxy calls to a yet deeper layer.
Here's a radical idea - we did talk about not having conduits in
items offline yesterday and instead just having the conduits live in
collections. What if we didn't have conduits at all and instead just
have transport info objects in the collections. Now the model
object's save implementation will look like:
Item.prototype.save = function(){
var collection = this.getACollectionICanWriteOn();
cosmo.service.save(this, collection.transportInfo);
}
Bobby
More information about the cosmo-dev
mailing list