Re: Starting to modularize legacy

Charles Severance wrote:

On Feb 23, 2006, at 1:55 PM, Mark Norton wrote:

Josh Holtzman wrote:

As a first attempt at decoupling all of the services that are jammed into legacy, I just pulled the entity package out of / legacy-service into its own jar. Because it has dependencies on other legacy stuff, the new jar must include the exceptions, time, and user packages from legacy.

According to my analysis, the Entity dependencies are: Site, User, Time, and Exception. The dependencies on Time are understandable, to some degree and we could live with that. The exceptions associated with entity should be defined and bundled with entity, rather than shared. This greatly reduces cross-service dependencies, as far as exceptions go.

I think that Site needs to be abstracted to become "Context" - a Site is one form of Context. I am thinking here about uses of the Sakai Framework other than just CLE's. So at some level Context is a framework concept and "Site" is an implementation of Context.

An interesting idea, Chuck. I do think that the existing Site object is too closely tied to "sites as portals", so moving more towards a context oriented site makes some sense. Push the context stuff lower in the stack, portal stuff higher.

User is similar - we need a framework level user and a common level User.

Less clear. What capabilities would be at the common level that wouldn't be at the framework level, given the layer definitions below? I do think that User should be more abstract that UserDirectory. There are more than one way to implement a User than in a directory. UserDirectory is a holdover from CHEF, as near as I can tell.

Here is a possible layering naming convention

application - Calendar, Chat, Melete, .....

common - The basic stuff that any CLE would need - ContentHosting - userDirectory - EduPerson - Content Package Import

framework - low level stuff with value - add - but still generic for a CLE or not a CLE - can have persistence - imagine things like Entity, Events, CLustering, etc -

kernel - very very low level - provisions servlets and components - so generic it could be used for *any* application - *NO* persistence other than in-memory objects

For the most part, these make sense, though the differences between common and framework are not clear to me. We may need the common layer just because services at that level will depend heavily on framework service and if we merged them, we'd get side-ways dependencies. Can we agree that service dependencies should always be downwards at a lower level and never higher or sideways?

Dependencies on User could be eliminated by returning a User Id string. This doesn't really reduce the dependency. It just decouples the services by making the reference more abstact (String vs. User). Still, it would make it much more modular. Note also the circular definition: User entends Entity, Entity relies on User. This feels wrong to me.

Circular = Bad.

Understandable, but not good. We can fix this without too much trouble.

I also had to change the EntityProducer interface's syncWithSiteChange(Site site, ChangeType change) to syncWithSiteChange(String siteId, ChangeType change) to keep the Site dependency out of the framework.

This is the Site dependency noted above. I have mentioned this to Glenn in the past and there was some discussion about alternative approaches at that time. Personally, I think that a reference to Sites at the Entity level is completely wrong. It totally violates the layering of services. I think we should consider moving it into the Site Service (if possible) or consider developing a synchronization service of some kind. It sholdn't be in Entity at all. That said, your proposed change reduces coupling. I could live with that.

We need to find a way to reduce the coupling - the event discussion might get us there - but this requires careful thought.

Josh's suggestion would get us the biggest bang for the buck in the short term (Site becomes SiteId). Longer term, Sakai really needs some kind of generic notfication system for internal and external synchronization. Course Management needs this ASAP. Maybe we can figure it out as a new service and integrate it further down the line.

Perhaps this can be the start of a "framework" layer below legacy?

Entity should be in common, if it is going to be the base construct for system resources (called Qualifiers in OKI-speak). Common should be the basis for the new Sakai framework. Kernel is below it, application and education services above it. Legacy services need to be evaluated on a case basis to see where they fit.

We can't really move entity into common at this time, though. Not without making some of the design changes I mentioned above. Nothing in common should depend on legacy services. Putting it into it's own JAR is just a holding action until we can separate it's concerns and reduced service coupling. What is really gained by putting it into it's own JAR? Can the legacy services be split up by doing that?

If we are considering a new entity that could be in common, we should give some thought to the mix-in vs. interface extension design patterns. There are advantages to the current approach, but mix-ins have a lot to say for themselves, too. To my mind, Entity should provide very basic capablities that we want all resources to have. It's pretty close to where it needs to be, I think.

I really really do not want to wholesale rename things for 2.2. I thing that we can get away with some refactoring (making new jars etc) in preparation for a rename pass - but I would prefer to minimize the needed changes to tools under development (both inside and outside the source tree) and web services and local plugin code.

Makes sense. Package name changes are not quite as bad though, right?

Renaming is easy once things are nicely broken out - and the "bad" connections are changed. Fall is a good time (say october) to do these kinds of things (sorry Rutgers) because I think that increasingly sites will not upgrade over holiday break except those sites in pilot and able to "keep up".

Read the follow ups to this. To my way of looking at it, there is no good time to be making these sorts of changes. Therefore we have to be careful and rigorous every time. Does it make sense to capture (document) how we go about this sort of thing? In general, I mean.

I am not saying "zero" API changes - just making sure each is well thought out and communicated clearly to active tool developers - and done in time so that we don't freak everyone out right before code freeze. So that will limit what we get into 2.2.

Yes, I agree.

At the same time, I do want to see us make *some* progress on 2.2 in this area (cleanup) because we need to fix a few basics so that we can noodle on the more complex stuff without continuously being distracted by the basic icky stuff.

What's on your list of things to be changed?

The good news is that this took only about two hours to accomplish, and Sakai seems to be running happily. I couldn't make a comprehensive patch for this, since svn wouldn't include any of the "added" files (svn help anyone?). Let me know if you want to look at the changes, and I'll zip it up and send it out.

I'm hoping that other minor API tweaks will allow the rest of legacy to be modularized.

Historically this type of refactor is not so hard as long as you take a deep break and retest and then write up the document to the dev list about what folks need to do to react and and then help tool writers who need help.

I think so, too.

- Mark Norton

This automatic notification message was sent by Sakai Collab
( from the WG: Framework site.
You can modify how you receive notifications at My Workspace > Preferences.