Hi Stef--
> Do you have a description of Naiad?
Not a proper one, no. There's just the Spoon mailing list archives[1]
and my "position statement" at Dan's request for the modules mailing
list[2]. Soon... I'm hoping we can still discuss what we want such a
system to do in the meantime, though.
> What is a Naiad module?
Currently, it's an object with:
- an ID
- added method IDs
- removed method IDs
- removed class IDs
- a name
- a description
- an author ID
- an initialization block
- prerequisite module IDs
- component module IDs
IDs are all Leach/Salz UUIDs. Two modules, each resident in different
object memories, can synchronize their respective systems via remote
messaging. The requesting module asks the providing module to
synchronize the two systems. The providing module:
- ensures that its author is defined in the requesting system
- has its prerequisite modules synchronize with the requesting system
- defines its added methods
- removes its removed methods
- removes its removed classes
- synchronizes its component modules with the requesting system
The requesting module, now equivalent to the providing module, runs the
initialization block. (Note that the receiving system can now act as a
provider to other systems.) The actual system changes made during the
synchronization depend on the initial state of the requesting system.
Many of the pitfalls of fileouts are avoided, since the author doesn't
have to second-guess the initial state of the requesting system. The
requesting and providing systems can work through their differences
almost entirely on their own. The information exchanged is not static,
as with a fileout or similar.
Requested methods can define their literals properly in the requesting
system, including defining new classes when necessary.
I've implemented a system for expressing Naiad commands as URLs. Such a
URL, when selected, issues a command to the Spoon system running on
localhost. The so-called "path" segment of a link is a text-encoded
action, which the local Spoon webserver evaluates.
There are several different commands: for quitting Spoon, making a
snapshot, installing modules, and so on. A module installation command
contains the hostname and port of the machine serving the module, and
the module's UUID. The receiving Spoon system uses this information to
create a remote-messaging connection between itself and the serving
system; the two systems then synchronize themselves via remote messages.
See [3] for an example of a Naiad link.
One simple way of enabling module discovery is simply to publish lists
of Naiad links on webpages, with module cataloging information, and let
Google do the indexing. I also intend to create a more integrated
discovery system with Spoon systems in a relay architecture, similar to IRC.
> I'm really interested in knowing that and what we could do with them +
> improving if necessary.
Now's a good time to discuss the design. What would you like it to do?
> Are other people welcome to use and build on top of spoon and Naiad?
Yes, see [4] (which has been in effect since the first public release,
of 14 February 2004).
> How do you see possible collaboration?
I'm all for it. :) Is there something more specific you want to know?
> > Ideally, I'd like the new modules to contain well-factored and
> > highly-readable expressions of the ideas of the old subsystems,
> > rather than just blind repackagings, but we'll see... it's tempting
> > to just imprint things to save time. :)
>
> You mean that you would like to rewrite some parts?
Yes, particularly the virtual machine implementation. I think it could
be much clearer in many places.
thanks!
-C
[1] http://lists.squeakfoundation.org/pipermail/spoon
[2] http://minnow.cc.gatech.edu/squeak/5618
[3] http://netjam.org/spoon/modules
[4] http://netjam.org/spoon/releases/current/frame.php#license
--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]
Hi all--
Now that I've been living with it for a while, here are a few details
on the shrinking technique I mentioned a couple of months ago (where
methods that haven't been run recently get reclaimed by the garbage
collector). Also, at the end, are some notes on what I'm doing now and
my next steps.
When I did the earlier imprinting work, I added two bytes to the
compiled method trailer format. One bit in those bytes indicates whether
the virtual machine has run the method (the other fifteen are for
recording the method's linear version). I changed the virtual machine to
set that bit every time it runs a method. By clearing that bit on all
methods, then examining them later after running the system for some
duration, one can tell all the methods which were run over that
duration. A method without that bit set is "inert".
I extended the garbage collector with an alternative mark phase that
doesn't mark or trace inert methods (with the exception of methods
associated with currently-active contexts). References to inert methods
are replaced with nil. This leaves some method dictionaries with nils
where methods used to be.
My typical development mode so far has been to use a "full" object
memory equipped with remote-messaging tools to control a target object
memory over a network. This lets me make changes to the target with
impunity. In particular, I don't have to worry about the target getting
wedged because I've broken the user interface, because I'm using another
system's user interface. I've got a remote system browser, debugger,
process browser, and workspace. The remote system browser uses the
master system's compiler, and transfer methods directly into the target,
so the target need not have a compiler (or ClassBuilder). No class names
are ever exchanged between master and target, and source code is
completely optional.
I changed the target system's Object>>doesNotUnderstand: so that,
before raising an exception, it first attempts to install the missing
method from the connected master system. If installation is successful,
it resends the method and carries on. I changed method lookup in the
virtual machine so that when a nil is encountered where an inert method
used to be, it is handled as a message-not-understood. So, the master
system effectively acts as a virtual memory for the target, providing
missing methods inline as they are encountered.
In the past (before the garbage collector changes), a new target system
was created as a copy of the master system. I would then connect master
and target, and use the remote tools in the master to shrink the target
manually. I've done two passes that way; the first took three months of
work in 2003, the second took two weeks of work in 2005. The reason I've
made multiple passes is that I kept realizing significant system
features I'd forgotten to include before I started shrinking (e.g.,
remote debugging), and it'd be much more work to retrofit it into the
target than to just shrink a new master copy. Since there will probably
always be new fundamental things to add, I decided I ought to just make
the shrinking process more automatic.
Now I've got a class in the master that can automatically gut the
target in 30 minutes. It invokes code in the target that can throw out
entire "inert classes" (classes which have no references and no
non-inert methods). I got rid of the entirety of Morphic this way, for
example, without having to understand anything about how Morphic works.
***
In January I wrote a module-aware webserver for the target, to which
the web-based Spoon installer will redirect the user after downloading
and starting the system. The user will then be able to discover and
select modules to load and unload, make snapshots, quit, etc. Currently
I'm working on a Naiad module which installs the ClassBuilder (for
manipulating existing classes in the target). (Naiad is Spoon's module
system.)
After that I plan to:
- make a module which installs every last bit of 3.8 final, just to show
that one can recreate familiar old systems
- make modules which install the VM construction tools
- make a VM from a Spoon system with those modules in it
- throw away the VMs and object memories that I started with!
- make modules for other things I want to use (Quoth, Chronos, Weather
on Display, Tweak, etc. etc.)
Ideally, I'd like the new modules to contain well-factored and
highly-readable expressions of the ideas of the old subsystems, rather
than just blind repackagings, but we'll see... it's tempting to just
imprint things to save time. :) (For more about imprinting, see [1].)
thanks,
-C
[1]
http://lists.squeakfoundation.org/pipermail/spoon/2004-October/000061.html
--
Craig Latta
improvisational musical informaticist
www.netjam.org
Smalltalkers do: [:it | All with: Class, (And love: it)]