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

Reply via email to