On 5/10/12 10:21 PM, James Peach wrote:
Hi all,
I just committed a prototype remap plugin to the jpeach/lua branch that lets
you write remap plugins in Lua. I'd say it's at proof of concept stage. It
seems to basically work but it's never taken any real load. The error handling
is pretty lackadaisical.
Here's an example that should give you a feel:
<https://git-wip-us.apache.org/repos/asf?p=trafficserver.git;a=blob_plain;f=plugins/lua/example.lua;hb=jpeach/lua>
Very cool. It's actually pretty fast too. An extremely simple plugin. such as
function remap(request)
url = request:url()
url.host = "origin.example.com"
url.path = "a/new/prefix" .. url.path
request:rewrite(url)
end
Is only about 30% less throughput (but about 80% higher latency) compared to
a static remap.config rule. Pretty reasonable though (that's over 100,000
req / sec with that Lua code).. Once the Lua code gets more complex, LuaJit
would be cool too :).
I'd appreciate any comments about the API and the general approach. I think the
most controversial aspect is that the plugin does not explicitly choose whether
the remap evaluation chain continues. Request redirects and rejections
terminate the chain; anything else allows it to continue.
Yeah, lets gets some mileage and tests with this version, and have some
discussions. Should we perhaps add a CWiki page, documenting the current
APIs and decisions, and add proposals for additions / changes there ?
It's not clear to me yet how to extend the remap case to the general plugin
case. Is the remap plugin useful enough to stand on it's own?
Yeah, it's a whole different beast. A remap API is good to start with. A
couple of things that might be important from the get-go, that I can think of:
1) Plugins has 4 different types of headers that they can work on (UA-req
header, Origin req-header, Origin resp-header and UA-resp header). Maybe
it'd be cool to make this more explicit also in the remap plugin APIs, so
that we only have one way of getting the headers? (Not all headers are
available at all stages through the SM though, for obvious reasons).
2) We can start populating the TS object with various functions that would
be of use. Some of them could even be useful for a remap plugin, for example
the APIs to set / get overridable configurations, statistics etc. Or perhaps
that should go into separate containers?
3) For the request:redirect method, should it not take a response code? So
that it can do either a 301 or a 302. I think it'd be cleaner (symmetry) if
it was e.g. request:redirect(301, url) (which makes it look the same as
reject). I also find it a bit confusing that the second argument to reject
can either be the response message or the response body?
4) For remap plugins, we have the notion of "instances" where one plugin has
a different run time environment for each remap rule using it. You obviously
use this for the Lua plugin. I'm thinking we should have something similar
for Lua scripts too? Perhaps have all @pparam's that's after the mandatory
script name getting passed in as a table to the remap() implementation in
the Lua script? This would let me do e.g.
map http://loki.ogre.com/bench http://something @plugin=lua.so
@pparam=loki.lua @pparam="bench"
map http://loki.ogre.com http://somethingelse @plugin=lusa.so
@pparam=loki.lua @pparam="all"
and in loki.lua:
function remap(request, params)
...
end
This helps alleviate the fact that we don't pass in the "To" and "From" URLs
to the plugin, in fact, this is much more generic and usable.
Cheers!
-- leif