Self Referential Tree

Created 9/6/99 - Last Updated 9/15/99 - Jack Harich - Go Back


Nutshell Vision

The idea is to do away with a separate kernel altogether by using parts in the same system that's running to play the role of the present BA's kernel. For lack of a better name we will call these the "core parts". They are self referential since they use themselves to run themselves. The effect is a self referential tree of containers and parts. If we can get this to work well, the benefits are astronomical!!!

The benefits include greater conceptual integrity, ease of core customization per container or system, easier understanding due to simplicity, one less major partition, higher reuse, and a certain innate elegance that may appeal to many. Somehow this abstraction will probably open new doors.

My rule of thumb is "The complexity of a system varies with the square of its size." Size can be LOC, function point count, number of classes, number of partitions, etc. Consider the last. If we can reduce the two partitions of Tree of Parts and Kernel to just one partition of Tree of Parts, we have reduced the complexity of systems by a factor of four.


Start System Use Case

If we can figure this one out, we can figure out how to make this work. For help, we look at the "usePart()" Start System Use Case developed yesterday:

  1. Get system marker class or such
  2. Instantiate SystemMgr - Here playing the "bootstrapper" role
  3. systemMgr.setParamStore(paramStore) - Optional, could set more here
  4. systemMgr.startSystem(marker, args)
  5. Use paramStore to get marker Param
  6. Instantiate root container
  7. rootContainer.setParam(markerParam)
  8. rootContainer.usePart("SystemMgr", systemMgr) - Optional
  9. rootContainer.start() - This causes lots of further action.

usePart() causes a container to use that part instead of instantiating the one specified in container DK. This allows pre-existing life to enter a new life form, necessary for reproduction.

Now what would the Self Referential Start System Use Case be?

  1. Instantiate a Bootstrapper part.
  2. Pass it the system marker class or such.
  3. Tell it to start the system. It performs the following steps:
  4. ---------------------
  5. Instantiate Core container. It starts out empty and can't do very much.
  6. Add the Bootstrapper part to the Core container.
  7. Instantiate and add other parts to Core container. This gives it its full functionality.
  8. Use coreContainer.createNew() to get new container, name it Root container.
  9. Add the Core to the Root container.
  10. Set the marker for the Root container. (The Core has no marker. Make it "virtual".)
  11. Start the Root container. This causes the system to start as usual like the BA.

Issues:

1. Need to avoid any extra parts in a container, since they would be distracting. Could we make them hidden, like system files?

2. Will the above really work?

3. Can container X have a Core container that has parts. The Core provides X with its functionality. Would this work? Benefit is uncluttering container X. Perhaps it would work if a container could get parts.

4. Bootstrapper has to know lots. Could represent this in DK for the part. It could ask the ParamStore part to get the Bootstrapper DK.


Try Number 2

Start System Use Case - StartSystem or Bootstrapper class is prime actor.

  1. Create new ContainerCreator.
  2. containerCreator.setMarker(marker)
  3. containerCreator.setParamStore(paramStore)
  4. Container rootContainer = containerCreator.createContainer()
  5. ----------- in containerCreator.createContainer() ------------------
  6. Read DK into a Param
  7. Container container = new ContainerStd() - Class name from param
  8. container.addPart(this) and add marker, paramStore
  9. Create other parts in param, add to container using Adding Parts
  10. ------------------------------------------
  11. rootContainer.startPart() - Starts system like current BA

(Adding Parts) - We need to set Part properties. Do by:

  1. Worker worker = new Worker()
  2. worker.setInstance(instance)
  3. worker.setIsCore(true)
  4. worker.setIsVirtual(false) - Note that replications are true
  5. worker.setIsHidden(true)
  6. container.addPart(worker)

Create Sub Container Use Case - Container is prime actor

  1. Uses - private Container createNewContainer()
  2. ContainerCreator creator = (ContainerCreator)workerSet.getWorker(ContainerCreator)
  3. return creator.createContainer(this) - So can use workers in this container
  4. ----- The creator does the following -----
  5. Just like in Start System UC steps 6, 7, 8 - Good!!!

Lessons Learned - The crucial interfaces are Part, Container, Worker, Marker, ParamStore, ContainerCreator. Lesser are ContainerDef (has container DK), TNode, MessageServices, etc. The above took about 10 hours. We produced an initial class model, then a revised one due to discovery.



Fiddling

Then we tested the basic framework for extensibility for about 15 hours. It held up well by allowing various features to be added, with only minor changes and growth to pre-existing classes. This path is very viable. We evolved the second class model along with modifications, and it's up to date.


Prototype Models

The first Class Model was:

The second and final Class Model was:


Prototype Code

Here's the zip file containing the Java source and classes. We have not yet generated JavaDoc. To run it try "java -nojit org.jcon.core.proto.c1.test.CorePrototype1". Note is uses org.jcon.util.minor.KeyedVector, included in the zip file. The interfaces have extensive doc expressing the intent of this design. Have fun!!! :-)