58 lines
2.7 KiB
Markdown
58 lines
2.7 KiB
Markdown
|
# BaseT
|
|||
|
|
|||
|
BaseT is a proof of concept stream handler I wrote on a whim. I was wondering if
|
|||
|
you can reload code in PHP without using runkit or separate processes and so this
|
|||
|
design was born. The aim was to write a quick IRC bot but the base code is so
|
|||
|
generic it can probably handle any line based streams. A few example plugins are
|
|||
|
included.
|
|||
|
|
|||
|
The reloading works by putting all code in anonymous functions (this
|
|||
|
forbids the use of classes, constants and similar structures in plugins) and
|
|||
|
just re-including all the plugin files upon a reload. There are a few builtin
|
|||
|
hooks to attach code to and you can add your own, because you can also reload
|
|||
|
core code in the utils.php file. Note that there is no error handling so any
|
|||
|
fatal error – like a parse error during reload – will crash the whole thing.
|
|||
|
|
|||
|
## Memory performance
|
|||
|
|
|||
|
I am not familiar with PHP internals regarding the loading of code for closures,
|
|||
|
namely will PHP actually delete code attached to a closure when the last reference
|
|||
|
to its variable is gone, so I cannot say there are no memory leaks. My empirical
|
|||
|
testing suggests that the memory use jumps up and down after reloads, but eventually
|
|||
|
grows slightly after many reloads. You can try to follow memory use with the plugin
|
|||
|
9997_memoryusage.php.
|
|||
|
|
|||
|
## Requirements
|
|||
|
|
|||
|
BaseT should work on PHP 5.3+. It uses signals to force a reload so you'll need
|
|||
|
the pcntl extension, unless you delete the functions at the end of utils.php (and
|
|||
|
the declare at the top of main.php).
|
|||
|
|
|||
|
## Usage
|
|||
|
|
|||
|
The main loop of the program will exit if there are no streams to handle, so you
|
|||
|
need to write a plugin to open a stream when the program is started. You can check
|
|||
|
$_started to see if the program is starting up for the first time. The plugin
|
|||
|
0020_autojoin.php will have an example of this.
|
|||
|
|
|||
|
To reload code, send the program a SIGUSR1. The currently executing code will be
|
|||
|
interrupted, the reload will be scheduled to happen on the next iteration of the
|
|||
|
main loop and your code execution will be resumed. Note that an incoming signal
|
|||
|
can interrupt vital functions in your code and break things, so you may want to
|
|||
|
block signal handling at some points.
|
|||
|
|
|||
|
When writing plugins, you need to watch out for name clashes with variables, it's
|
|||
|
probably best to prefix your variables with a plugin identifier to avoid that.
|
|||
|
Plugins are included in ascending filename sort order so you can use numbers to
|
|||
|
order them the way you want.
|
|||
|
|
|||
|
## This is a terrible way to write a program
|
|||
|
|
|||
|
I know, this was mostly a proof of concept on reloading code and a fun little
|
|||
|
thing to write. This is not what PHP was made for so don't expect great performance
|
|||
|
or stability (though it looks relatively stable with a small amount of plugins).
|
|||
|
|
|||
|
## License
|
|||
|
|
|||
|
MIT, look at the LICENSE file.
|