From 9a80e9357c8e9feec6b4975c3b9b7ac76429bd3b Mon Sep 17 00:00:00 2001 From: Mikko Ahlroth Date: Sun, 29 Sep 2013 12:34:22 +0300 Subject: [PATCH] Add README, LICENSE, memory use plugin --- LICENSE | 20 +++++++++++++ README.md | 57 ++++++++++++++++++++++++++++++++++++ plugins/0020_autojoin.php | 10 +++---- plugins/9997_memoryusage.php | 11 +++++++ 4 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 LICENSE create mode 100644 README.md create mode 100644 plugins/9997_memoryusage.php diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..a07691a --- /dev/null +++ b/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright © 2013 Mikko Ahlroth + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..be7113d --- /dev/null +++ b/README.md @@ -0,0 +1,57 @@ +# 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. diff --git a/plugins/0020_autojoin.php b/plugins/0020_autojoin.php index c534735..3234d2e 100644 --- a/plugins/0020_autojoin.php +++ b/plugins/0020_autojoin.php @@ -6,7 +6,7 @@ $_autojoin_servers = //['irc.cc.tut.fi', 6667] ]; -$_user_info = +$_autojoin_user_info = [ 'nick' => 'BaseT', 'altnick' => 'AltBase', @@ -26,9 +26,9 @@ $_plugins['onload'][] = function() use ($_autojoin_servers, $_started, $_connect } }; -$_plugins['onconnect'][] = function($id, $host, $port) use (&$_write, &$_user_info) +$_plugins['onconnect'][] = function($id, $host, $port) use (&$_write, &$_autojoin_user_info) { - $_write($id, sprintf("NICK %s\r\n", $_user_info['nick'])); - $_write($id, sprintf("USER %s 8 * :%s\r\n", $_user_info['username'], - $_user_info['realname'])); + $_write($id, sprintf("NICK %s\r\n", $_autojoin_user_info['nick'])); + $_write($id, sprintf("USER %s 8 * :%s\r\n", $_autojoin_user_info['username'], + $_autojoin_user_info['realname'])); }; diff --git a/plugins/9997_memoryusage.php b/plugins/9997_memoryusage.php new file mode 100644 index 0000000..e7bb10a --- /dev/null +++ b/plugins/9997_memoryusage.php @@ -0,0 +1,11 @@ +