Forum OpenACS Development: Namespaces instead of service-contracts?

Buffers Files Tools Edit Search Mule Help
I've started implementing stable URLs, in short: a page called /object
hooked under the main-site that redirects to the proper object-type
dependant view an object page.

For further reference see this thread
https://openacs.org/forums/message-view?message_id=94374 where Timo and
I have been raving about it.

For that I looked into the service-contract package and couldn't
really make sense out of it. After a couple of hours of messing around
with it I decided to ditch it for *this* implementation and use
namespaces for this project.

I put the current code here:
http://dirkgomez.de/openacs/slash-object.txt. index-vuh is the
redirect page that firstly retrieves the URL and then does the
redirect. The get_url procs are in different namespaces, here
stable_object::${object_type}. So the whole code to retrieve the
object type's URL is two lines of code.

With service-contracts I need two more steps: I need to create a
service contract on package instantation and I need to retrieve
sercice contract information on every page hit.

Currently I fail to see where the service-contracts have an advantage,
maybe we can point out weeknesses and strengths of both
implementations here.

The strengths of the namespaces implementation are:

* Less code

* 100% TCL

* Easy to understand and easy to debug.

* No extra database hits ever.

* Enforces consistency, yet is flexible and abstract

* Doesn't require me to read the docs for yet another package.

Collapse
Posted by Dave Bauer on
Service contracts are also 100% tcl. The database access is only on startup and the infomation is stored in RAM in a running server.

If you define an interface through service contracts or a special tcl namespace, you still need to document the interface. The documentation for the service contract is in the service contract definition. I imagine it could be somehow added to the api-documentation. If you look at /acs-service-contract on your server, i believe it does show the definitions for the service contracts.

I do agree, that the way acs-service-contracts are currently used, we really don't use much more functionality than we could get using special tcl namespaces. Hopefully someone can give some ideas on how it can be used more effectively.

Collapse
Posted by Tilmann Singer on
Some things that can be done additionally with service contracts:

  • Bindings can be deactivated via a webinterface and the deactivation will be made persistent in the db.
  • Automatic discovery of procedure signatures.
  • Easier publication to the outside via XMLRPC or similar protocols since it is based on WDSL (not sure if I got that right).
  • It provides an ID for each implementation.

I think none of these facilities are crucial to 99% of the ways service contracts are or could be used within the toolkit.

Regarding the dynamic deactivation: that would still be perfectly possible when using namespaces only, by simply using the tcl rename command. This could even be made persistent my setting up a a loop upon server startup that renames all deactivated implementations.

Regarding automatic discovery - I have no idea when that would be used besides some really esoteric implementations (besides you can still sort of do that with ad_proc, no?), and the publication to the outside via xmlrpc is a desirable thing but would propably require an extra layer of control in most cases anyway (as opposed to automatically publishing all implementations of on sc automatically or whatever was intended with sc's), so I don't see a big problem in writing extra tcl wrapper procs or setting up some other system besides the sc system for the functionality that one wants to publish to the outside.

The implementation ID is used e.g. in acs-authentication's auth_authorities table to dynamically associate rows in the table with an implementation. As far as I can see an implementation key as string like described below would serve the same purpose - hopefully I'm not missing anything here.

DaveB: are you sure there are no db calls involved? I see this in my log everytime the search indexer finds an item to index:

Notice: Querying 'select acs_sc_binding__exists_p('FtsContentProvider','radio_emission');'

To be more precise what I envision as an alternative system, and I guess that's the same what DaveB and Dirk imagine, I'll try to sketch it out a bit more, possibly repeating what has been said before. This is not (yet) a concrete proposal for any changes. I'd just like to think loud about what could be theoretically possible, and if it would make any sense to order my loose thoughts.

1) It is used for internal use only - to foster the interopability of different OpenACS packages using standard and thus easy to grasp tcl techniques, and retaining the modularity and independency of the packages that interoperate.

2) Define a clear naming rule for service contracts using tcl namespaces. E.g. like this:

package_key::service_contract_name

And the individual implementations would look like this:

package_key::service_contract_name::impl::object_type

The ::impl:: in between makes it clear only by looking at the proc name that it is an implementation of a service contract.

3) Checking wether an implementation for a specific object type exists would go like this: if { [llength [info commands package_key::service_contract_name::impl::$object_type]] }, and invoking all implementations of one contract as easy as:

foreach cmd { [info commands package_key::service_contract_name::impl::*] } {
    if { [catch {
        eval $cmd $args
    } errmsg] } {
        ns_log error "Error for $cmd $args"
    }
}

4) Some way to formally specify a contract like acs_sc::contract::new_from_spec. I wonder though if it wouldn't be possible and easier to do it with something that resembles ad_proc, like this:

ad_interface package_key::service_contract_name { arg1 arg2 arg3 ... } {

    Here goes the documentation of the interface package_key::service_contract_name.

    Authors are advised to put in exact definitions of the expected parameter values,
    the return value and what happens in case of an error.

    @author me

} 

I think in the beginning ad_interface doesn't need to be more than a descriptive helper, making the doc and the signature appear in the api-doc. Maybe later a way can be added to formally check for the correctness of each implementation somehow, but I don't think that is essential since we can never avoid developers shooting themselves in the foot anyway, and the current acs-service-contract offers a lot of possibilities for that too.

Dirk, Don and me have been talking a little about this and as far as I could see there was consensus that a change like this would be very benefitial. I would like to experiment further with the suggestions made here by adding this method to the search package (locally), so that it becomes easier to search-enable arbitrary content, and based on the experiences write a TIP, hopefully in time for 5.1.

There seems to be no reason why this method couldn't run with the existing acs-service-contract stuff in parallel, so it won't break any existing code.

Collapse
Posted by Don Baccus on
Do we need to give up the capability for external integration in order to simplify the implementation of service contracts?

If we want to support plug-ins we want to be able to arbitrarily drop in something external or something written as a set of Tcl procs without the caller knowing the difference.    Today we only directly support direct calls to PL/[pg]SQL or Tcl but in the future might want to support SOAP calls directly, for instance.

I don't really see service contracts themselves as being cumbersome, just their implementation and the lack of documentation.

Hmmm...it looks like Til's suggestion gives up the capability to directly call PL/[pl]SQL directly.  This is one of the advantages of the current service contract mechanism - the caller/spec writer doesn't need to know what language particular implementations are written in.

Also ... service contracts are somewhat pervasively used at the moment, so we can't just get rid of them (fear the wrath of Tom Jackson :)

I see you talk about determining whether or not something's implemented for a particular OBJECT TYPE above.  I don't see service contracts as being the proper mechanism for defining  object type methods.  We don't have a "proper mechanism" and  we probably should and using namespaces such as you describe (which is similar to how datatypes in the form builder are defined) would be a way to do it.  Objects are special within OpenACS and I have no problem treating them as being special.  Service Contracts are extremely general by design, being a way to map specs and bindings whether or not an implementation is part of OpenACS or, for that matter, running on the same server.

I'll try to think about this stuff and look at it some more when my head's a bit clearer (I've just arrived from Berlin and am very tired).