New Region Modules

= Why =

The current RegionModule system's API is in part inconsistent and doesn't really support region-restarts and adding/removing regions on the fly during a region-server run. E.g., the API says Initialise is called for every region (in every region-module), after that, PostInitialise is called for every region-module. When a new region is added, what should happen?
 * Don't call Initialise: Then the region-module isn't initialised for that region, which leads to missing functionality.
 * Call Initialise: Then PostInitialise was called too early. Actually, PostInitialise can not be called at all, because you can add a region after that anytime.

What should happen if a region is restarted? What should happen if a region is removed?

= What =

The new region-module system is based on three interfaces: ISharedRegionModule, INonSharedRegionModule and IRegionModuleBase, which is the base interface for the other two.

public interface IRegionModuleBase {     string Name { get; } void Initialise(IConfigSource source); void Close; void AddRegion(Scene scene); void RegionLoaded(Scene scene); void RemoveRegion(Scene scene); }

public interface ISharedRegionModule : IRegionModuleBase {     void PostInitialise; }

public interface INonSharedRegionModule : IRegionModuleBase { }


 * Loading the region-modules' classes happens via Mono.Addins on server-start.
 * Instantiating the region-modules happens...
 * for ISharedRegionModules once after loading (on server start)
 * for INonSharedRegionModules after creation of the Scene object.
 * You can cleanup when a region is removed.
 * You can cleanup before the server shuts down.


 * Note:
 * A PostInitialise for a INonSharedRegionModule doesn't make a lot of sense, as we don't have a certain point from which on we won't call Initialise on a INonSharedRegionModule again. Every time a new region is added (on restart, too), a new instance is created and Initialise is called on that instance, so the intended semantics of PostInitialise will never apply.

= Details =

Creating a region module assembly
Include using Mono.Addins; in your file. You will need to include Mono.Addins.dll in your project.

Then you will need to add several attributes to your assembly and the extension classes in the assembly for Mono.Addins to recognize the .dll file as containing valid addins.

Put the following anywhere in your library, just above the namespace declaration on one of the files. This needs to be included in just one file of your dll. [assembly: Addin("MyAddin", "0.1")] [assembly: AddinDependency("OpenSim", "0.5")]

For each RegionModule class use the attribute, just above its declaration:

[Extension(Path="/OpenSim/RegionModules",NodeName="RegionModule")]

Note that the directive Addin is the only one here that takes variable parameters. Use your own name for "MyAddin", and define your version. Leave all other OpenSim-related parameters as shown.

Start of region-server

 * Region-server starts, the classes of all region-modules are loaded in no particular order
 * For every ISharedRegionModule, one instance is created and Initialise is called.
 * For every ISharedRegionModule instance, PostInitialise is called.
 * The Scenes are instantiated, one by one:
 * For every Scene
 * for every INonSharedRegionModule, a new instance is created and Initialise called.
 * for every INonSharedRegionModule and ISharedRegionModule, AddRegion(scene) is called. The modules are associated to the Scene (for deletion on remove)
 * for every INonSharedRegionModule and ISharedRegionModule, RegionLoaded(scene) is called (you can access the methods in other modules of that scene via scene.RequestModuleInterface here).

Adding a region

 * for every INonSharedRegionModule, a new instance is created and Initialise called.
 * for every INonSharedRegionModule and ISharedRegionModule, AddRegion(scene) is called. The modules are associated to the Scene (for deletion on remove)
 * for every INonSharedRegionModule and ISharedRegionModule, RegionLoaded(scene) is called.

Removing a region

 * For every INonSharedRegionModule of the scene and every ISharedRegionModule, RemoveRegion(scene) is called
 * For the INonSharedRegionModules, Close is called
 * Every module reference of the scene is removed from the scene. No references should be left after that; the INonSharedRegionModules could be garbage collected now. even so runtime will keep a lot of resources, modules can be trully unloaded

Restarting a region
Restarting happens as a sequence of "Removing a region", followed by a "Adding a region". As usual, avatars that are in that region when it restarts are kicked.

Due to the realities on .net/mono, region restart is a fail. Even if our code did it right, and still does not, .net will not do it, keeping some resources in usage, etc

Shutdown of the region-server

 * For every scene, perform the "Removing a region" step:
 * RemoveRegion is called for all scenes and modules, Close is called for all the INonSharedRegionModules
 * Close is called for all the ISharedRegionModule. The ISharedRegionModule could now be garbage-collected.

= Notes =


 * RemoveRegion/Close is for cleaning up. Things you added in Initialise/AddRegion should be removed in Close/RemoveRegion again, respectively.
 * The modules are loaded via Mono.Addins. This means, you can build your own assemblies with region modules, and by putting them into the  /bin folder, they will be loaded automatically. Make sure the correct attributes are set for the addin to be loaded correctly
 * clear enough? Or should we add a spelled out example? HomerHorwitz 18:21, 12 May 2009 (UTC)

= TODOs =
 * Configuration about which modules should be loaded.
 * we already have the enabled = true/false OpenSim.ini config option for most region modules --- DrScofield 09:53, 26 January 2009 (UTC)
 * which is a horribly ad hoc solution - we really do need a better way of controlling this imho --- Justincc 20:26, 28 January 2009 (UTC)
 * agree with Justin. A module shouldn't be responsible for turning itself off, it should never get loaded in the first place --SeanDague 21:51, 28 January 2009 (UTC)