[crossfire] Moving server towards a modularized system?

tchize tchize at myrealbox.com
Tue Jan 24 04:28:34 CST 2006


Le Mardi 24 Janvier 2006 07:38, Mark Wedel a écrit :
> 
>   True, but a plugin for object actions would be a pretty critical piece of code 
> - you just can't disable the players from applying all items (or not compile 
> that bit) and have a working system.
> 

'Using object' is a core feature imho, while the behaviour of a specific object or object type when applied should be left to appropriate plugin

I agree but with following reserve:
 - you are assuming 1 module is managing the apply while it would probably be 1 module is managing 
   a defined range of object type (eg: applying handles, applying readables, applying wearables) and it could
   be interresting at some point to remove module for a specific category of items, like removing magic items management 
   (applying , recharge, other stuffs) if you dedice you don't want spells in your server.
 - A developper could be interrested in removing parts of the server for testing purpose. If i have a specific
   problem loading a given map and i don't know if it's because of objects inside map, or because of map loading
   code, I could easily disable lots of plugins to get only core + maploading code + protocol and check if the problem
   is still there. Sure you couldn't do much ingame, but it is interresting for developping purpose. This also help you isolate 
   your code. If core+your module+maybe a tester module (which could, for example, fake a user connection and load a test map)
   isn't enough to have your module working in test environment, then you might need to consider your module has 
   other dependencies. 


>   Now the counter is that you'd just disable it for the specific bad object 
> type, but then, if one plugin is covering 30 object types, that still isn't much 
> an option.

Additional reason not to group together spells, monsters, alchemy and random map!

> 
>   IMO, compiling/not compiling something isn't an issue - if something is so 
> broken that it doesn't even compile, it should be fixed ASAP or be removed.

Yes, assuming it's easily fixable (does not take 3 days of work). 

> 
>   the issue would more likely be disabling them once problems start, which would 
> be same regardless of method used, but registered callbacks are probably easier.
> 

Well removing a .so or .dll from a dir is also easy.

> 
>   Well, you can't have a single list of all the set_type_callbacks() unless all 
> the functions are in the same module.
> 
>   For most plugins, that probably isn't a problem - if one were to think of the 
> random map code, it really only needs to register one callback, so big deal. 
> OTOH, the random map code is already pretty well modularized, so I don't see 
> much point to convert that to plugin logic.

I suppose you are refering to the problem of storing callback informations in mapfile 
(because at runtime a pointer is just a pointer, you would just need to update it if module
is reloaded, already the case in current plugin code). 
That could be done using pluginname+declared plugin callback name. It's implementation 
details. For item type it's even easier as it's not stored in file. It's the plugin which declares
at load time it want to have given listeners on given types.

> 
>   I think the term plugin vs module probably needs to be clarified, as well as 
> clarification what approach we are really taking.

If you don't put the modules in plugins (at least what we could modularize from current 
server code) you would have two things
 - 1) code to manage hard linked modules (eg arrays of module callbacks to explores and so on)
 - 2) code to manage additionnal behaviour which could be requested by plugins (be it python, animator or another one)

That mean during modularization process, at each place we consider splitting appart code in modules we have to handle separetly
 - main server module
 - plugin managment code

This is twice the effort during the modularization process.

> 
>   To me, module is like the .a files currently used (random maps, socket, etc) - 
> code is logically grouped in one place, but linked in at compile time.

This isn't enough for modules. Of course modules can be gathered .a and gathered a link time.
But you also need to clearly separate them. Currently it has nothing of modularized. A piece of code in
random map can call functions present in the socket, a piece of code in weather can call functions in maploader.
Same for piece of code in protocol which makes call to maploader.c

You could do modules in .a (and even suggest current plugins be converted to .a and gathered at link time, 
you would only lose the runtime reloading facilities). But you must ensure each module has it's separate .h files. Also, you
must ensure you don't have cyclic modules dependencies and ensure you use only modules you depend on 
(that is only include .h of modules you depend on)

To me, be it link time modules (.a) or runtime modules (.so), the work to do is the same, except this
- plugin will need a bit of 'load library code' mainly already present in code
- in .a it will be difficult to enforce strict separation in the future.

>   I guess for the object code handling, I'm more inclined to do a module type 
> approach - that code is already compiled in, and I don't see much in the way of 
> compelling advantage to making it an actual plugin - the code can be made a lot 
> easier to maintain and find stuff without making it an actual plugin.

Plugin is a way of modularization like another. To me it is the less cumbersome.

> 
>   That said, I can certainly see the need for plugins.  It just becomes harder 
> to figure out what approach works best for what.
> 

If you have modularization in form 'plugin +sth else' you have to do twice the job as 
plugin will mainly need to plug at same places the modules will need to interact.

> 
>   Imagine a case where object A is applied.  plugin for A is called.
> 
>   As part of what A does, it applies object B.  So plugin for B needs to be 
> called.  A real world case right now is things like altars that push buttons 
> that perhaps activate something else.
> 
>   If the plugin code is not properly re-entrant, this fails..

If current server code is not reentrant, at most places, it fails also, even in non multithreaded environments :)
But it can be stated in plugin specification that each callback is presumed to be reentrant safe.

> 
>   Right now, with the limited use of plugins, this isn't much a problem.  But if 
> a lot more stuff moves to plugins, we may run into that issue sooner and not later.

If a plugin is forced to be 'thead safe' this mean each manipulation of plugin global data must 
be surrounded by mutex. This mean even if server is not yet multithreaded, we would have the plugins 
(or .a modules) have dependecies on threading libraries :)

> 
>   The current code can of course have the same problems.  query_name() has a 
> pretty horrible hack.
> 

Yes!

>   multithreading certainly is a different issue, but I think relative to current 
> code, the current hacks are well known and in place to make things work.

They are 'known to work' but certainly not safe!

> 
>   I don't really know if the plugin code will have any of the problems I 
> mention.  It it just something that should be investigated/programmed correctly 
> so it isn't a problem.
> 

Damn i should read mail 'til the end before defending my position. Consider 
answer as hypothetical solutions to hypothetical problems then :p

--
Tchize



More information about the crossfire mailing list