MOO-cows Mailing List Archive

[Subject Prev][Subject Next][Thread Prev][Thread Next][Subject Index][Thread Index]

Re: plug-in interface



Oh my--did I hear an invitation to insert my thoughts into a discussion?

Erik wrote, responding to Nick:
>> Some enhancements that might make this system adaptable to a wider
>> variety of plug-ins include the ability to "register" a function to be
>> called in the server main loop
> Can you (or someone else) give some examples of what this would be used
> for?  That would help in coming up with a good design.

I'll take this one.

I've envisioned plug-in modules doing a wide array of things.  Some examples, 
ranging in ambitiousness, might include: adding simple built-in functions (a 
la bf_list_assoc), FUP, adding a network implementation, adding a data type, 
adding the source-level debugging facilities.

Some things that plug-in modules might want to do, from the programmer's 
perspective, might be:
- register a built-in function
- call externally visible (non-"static") functions in the core source
- access externally visible (non-"static") global variables in core source
- *modify* functions in the core source (cause a different function to be
  called)
- insert a function call into the main loop, to allow periodic processing
  (a network or file-utilty plug-in might want an opportunity to check
  for i/o readiness every second)
- have functions in the library called at certain points in startup,
  checkpoint, and shutdown (for example, a plug-in that performed the
  processing functions normally in the startup script, or which caused
  checkpoint files to be gzipped)

> Just to address a concern that might come up: I don't have any
> intention of making dynamic loading a prerequisite operating system
> feature for MOO.  As far as I'm concerned, the API for dynamic loading
> should be pretty much the same as that for static extensions.  So you
> will be able to "plug in" your plug-in at compile time if you can't do
> it at load time.

I think a good design would allow the most conventional extension modules 
(adding a set of built-ins) to be used either as compiled-in modules or as 
run-time loaded plug-ins from the same code base.

> Actually it might make sense just to have the config file's name and
> location specified in the command line, just as the database file is.

Perhaps plug-ins could be specified on the command line with first a 
specification of the plug in, and then a single parameter for the plug-in 
(probably used to specify a config file), like:

moo -p fup fup.cfg -p fooplugin fooplugin.cfg foo.db foo.db.new 7777

An alternative would be to store the config information in the database file 
itself.  In this case you'd probably want to have a config-only mode (or add 
it to emergency wizard mode, or compile a separate binary, or whatever) for 
modifying it so you don't have to start up the whole system just to tweak a 
flag.

> My assumption is that there is a set of modules that is loaded at startup.
> This can happen _before_ the database is loaded, so there's no issue of
> corrupt data unless you start up the server _without_ a data type that
> you included last time.  I think this is sufficient (provided there's
> a way to recover if you do eliminate a data type).

More generally, there may be a set of times at which it would be convenient 
for some entry function to be called, like at startup, after database load, 
just before program termination, etc.

One thing to keep in mind is that "dynamically-loadable library" tends to be 
synonomous with "shared library", although the two aspects are substantially 
different.  Plug-in modules will most likely need an opportunity to 
initialize, and later release, per-process (per-MOO) data structures.  In the 
case of Windows, the operating system does provide this opportunity, but the 
plug-in may want certain information (e.g. version info) that could only be 
provided by a defined hook in the plug-in interface.

Michael wrote, responding to Erik:
>On Wed, 16 Jul 1997, Erik Ostrom wrote:
>> 3. It's possible that we don't want new functionality to keep on filling
>> up the global built-in function namespace forever.  It's been suggested
>> that plug-ins could take the form of "native objects" or "native methods"--
>> that is, from the database side, using a new function would look like
>> a verb call, but it would be implemented in C (or some other native-
>> compiled language).  This may be orthogonal to plug-in design, but it's
>> probably worth thinking about some.
> This would be cool -- then native verbs could subsume the concept of 
> builtins (which work poorly in an OO paradigm, in my opinion), and we 
> could do away with the strange bf_protect mechanism as well.  It would 
> unify the builin/plugin mechanisms into a single modular concept.  Have a 
> verb flag 'n' indicating a verb is natively implemented.  Map all currently 
> existing builtin functions to (for example) $builtin:the_bf_name.  If 
> someone wants to wrap or protect a bf, then it's a simple matter of 
> moving the native verb elsewhere and making the original $builtin:verb 
> non-native.

If I'm not mistaken, Cold allows something similar.  In this case, the 
database should maintain information about plug-ins (the association from a 
verb to a "native" method), rather than having a separate config file or 
command-line parameters for the "plug-in"s.  This seems to me like an 
effective way to manage namespaces.  With plug-ins the issues of colliding 
built-in names become more serious than they are now (at the moment, if you 
had extension modules with conflicting names, you could just do a trivial 
source edit; if you instead had a plug-in module and no source, you could be 
very unhappy.)


Some other thoughts:

1. Plug-ins should provide for version control, at least to the point of "I am 
server version 1.8.0p6, can you work with me?"  A system where both the plug-
in and the server have the opportunity to "approve" a combination would 
probably be most flexible.  Also, there should be the opportunity to provide 
extended version information to the database users; I believe that Nick 
advanced a proposal in the regards a while ago.

2. A natural thing to think about along with putting extension modules in 
shared libraries is to put the core code in a shared library as well.  This 
can be more efficient if multiple MOOs are running (if code in the exectable 
is not shared across processes but shared library code is) and can also make 
sharing functions in the core code easier.  The largest barrier to this that I 
see is the large number of global and static variables; there needs to be a 
copy of this data for each process using the shared library.

3. While we are on the topic of making it easier to add things to the server, 
how about making it easier to create built-ins that suspend?  I can see 
several ways this would be useful, i/o functions like a non-blocking 
open_network_connection() or non-blocking file-access functions being the most 
obvious.


  --Chris                           cunkel@umich.edu
    ResComp Senior Network Support Technician (SNST)
    Home Page: http://www-personal.engin.umich.edu/~cunkel/
    This signature no verb.


Follow-Ups:
Home | Subject Index | Thread Index