Westie / OUTRAGEbot

OUTRAGEbot PHP based IRC bot: Development repository
6 stars 9 forks source link

Usage of namespaces? #4

Closed Drachenkaetzchen closed 13 years ago

Drachenkaetzchen commented 13 years ago

Hi,

I'm thinking of re-writing the OUTRAGEbot to make use of namespaces. This would solve several issues, especially that one with the "not-so-perfect" script loader. Users could simply define the fully qualified class name as script, e.g. OUTRAGEbot\Scripts\AutoInvite. That would also give the benefit that user-defined scripts are possible by using a simple class loader - and the script can be kept outside of the git tree.

How about that?

cheers, timo

Westie commented 13 years ago

I was thinking of using namespaces when I started to re-code OUTRAGEbot from scratch, but I decided not to go down that route because, well, at that time I really didn't totally understand namespaces.

Also, regarding the retention scripts in the git tree - I had done this so it would be easier for me to manage, or so I thought. I suppose it would be easier to create another repository for the scripts - then I can create a site to showcase them (and include only two or so scripts in the main dist) - perhaps I could make a module/script to download scripts!

I find the "not-so-perfect" script loader quite an achievement, where achievement means bronze star in hackness. Due to the pitfalls of PHP not being good enough to rename classes during execution, so I had to either choose runkit or re-name the script via regular expression when it was loaded. I'm not a lover of runkit (when it's in the core, yes, it'll be included) so regex was the way to go.

Could you give an example of how NS-style scripts would work? Would it be something along these lines?

namespace \OUTRAGEbot\Script\SampleScript;

class SampleScript extends \Script
{
        # code here
}

Or would it just be class Script or something - I'd quite like to hide some of the things I do in the background to make the resultant code cleaner, I suppose.

Regards, Westie

Drachenkaetzchen commented 13 years ago

Well, namespaces are some kind of "grouping". With PHP 5.3 widely deployed, there's no reason not to use them. Namespaces also improve interoperability between scripts; e.g. if I wish to connect the bot and some other PHP system, I don't need to care about class name conflicts, as classes are in their own namespace.

I can take care of the re-write to namespaces, I just wanted to check with you. For example of namespaces, you can check out my PartKeepr project which is completely based on namespaces.

I'm not sure why you do the regexp stuff; it looks like some kind of caching - but I'm sure it can be avoided to make the code more readable!

Westie commented 13 years ago

Will interoperability remain with the scripts though?

If I load a script that's compatible with c30e37d8f3e42438c8ff359a97038bb3b367dc58, will it still work with the namespaces - without any modifications necessary?

That's my main query.

And the regular expression on script loading - that's there so, when the bot is online and running and I want to update a script, I don't have to put the bot offline and restart it - the getScriptIdentifier method checks if the script file's been updated, and if so, change the name of the script and load it into memory. No collisions between any script or any other class.

Well, that's unless someone willingly and manually names their class SampleSc_4e1d7eca60f6a - that would just be stupid.

Westie commented 13 years ago

Sorry, if you didn't understand the language of the post - if scripts made prior to namespacing will work the same, then yeah - namespace it.

:)

Drachenkaetzchen commented 13 years ago

Ah I see! Well, that's a tough one. I'll think about that a bit - but I'm not sure if there's a "clean" way to dynamically re-load changed source files (or - in that case - modified classes). The main reason I suggested namespaces was to:

a) Avoid problems with duplicate names (e.g. if Project A uses the class "RSS" and Project B also uses the class "RSS", it would give conflicts) b) Make it easy to refer to scripts kept outside of the repository

For a), if the classes are dynamically re-named on load, that would be no problem at all, since (as far as I've understood) scripts are never loaded directly, i.e. the class "RSS" will never appear as "RSS" on runtime.

For b), there could be an option within the ini file to tell the bot where to find additional classes.

However, regarding the dynamic "reloading" of classes - that would work for the script classes themselves, but if any external classes are used (think of: external RSS parser or more advanced stuff), that could give heavy problems. I wonder if separate processes would be an option, where the bot simply creates a separate process for each script class in use. The bot would still be running, but could simply kill the process for a specific script and having it reload - that would solve any class loading foo.

Westie commented 13 years ago

You could always regex the namespace!

By the way, can namespaces be inherited? Probably not, but oh well...

Regarding having the scripts in different processes, you'd want to create some sort of socket based communication system between the socket and the core? I suppose that could work, but wouldn't having all those sockets create a huge amount of overhead?

I can take this two ways:

a) I run OUTRAGEbot on two networks from one instance. I usually have about 15 scripts on there, so that would be at least 30 local sockets, and 30 instances of PHP too. At least when the script has a fatal error, it doesn't kill the bot. But still, that's a lot of PHP instances.

b) Each network has its own script engine, which all scripts run in that process. When the script engine crashes, the bot can detect which one caused the crash and not load it.

I take it you're on about b)?

Remember we can't use pcntl_fork - if one child process dies, the whole bot dies. And I'm not happy with that... :(

Drachenkaetzchen commented 13 years ago

By the way, can namespaces be inherited? Probably not, but oh well...

You can't "inherit" namespaces (wouldn't make much sense), but contained classes. Classes within namespaces can do everything you can do with classes without namespaces.

Regarding performance: PHP really isn't that slow. Overhead will be there, but not that much from my experience.

Westie commented 13 years ago

So, I've got no idea whether I want the namespace idea - here's how I see it.

We could convert the entire code to namespaces and:

a) allow the user to choose the namespace themselves or by: b) using the regular expression for making the script names unique, make it part of \OUTRAGEbot\Scripts\ScriptName automatically, so it'd be something like

namespace \OUTRAGEbot\Scripts\SampleScript;
use \OUTRAGEbot\whatever_is_needed;

class SampleSc_4e1d7eca60f6a extends \OUTRAGEbot\Script
{
        # code here
}

Yeah, that looks good. Also, it'll ensure that the old code works a treat!

So yeah, go ahead.

I'll think of a way of containerising the script instances in another process effectively.