On 01/06/2016 06:10 PM, Roberto De Ioris wrote:
>
> Hi, first of all mounting and apps are absolutely separated concepts, an
> app is an "entry point" in your server code (like a function pointer).
First ... thanks for your time and careful explanation !

phyy, that part i got right, that a good start :-)
> Once you have a created an app it gets an id (a signed integer starting
> from 0).
>
> Dealing with app-ids (as a number) is unpractical so you can "mount" them
> (or "map" if you prefer) to a "string". As we generally deal with HTTP in
> uWSGI, the common pattern is to mount in uri (like /foo or /bar), but you
> can generally assign whatever name you want.
So the name of the app, is just a 1:1 value related to the id (a map as
you wrote), no routing info are found here only a name as a string ?
> Now, you are dealing with C++, so i suppose you have a function pointer as
> the entry point (something you expose with extern "C" in your code)
Yes, I use wrapping to C++11 function template to C functions (when this
works it will be public on github). This works nicely for the std
request function, so that part was not that hard.
> If you expose the mount_app hook in your plugin, the function will be
> called for each mount option:
>
> mount = /foo=hello_world
> mount = /bar=simple_func
>
> will cal your hook 2 times:
>
> int yourplugin_mount_app(char *mountpoint, char *something) {
>         // check for maximum number of apps
>         if (uwsgi_apps_cnt >= uwsgi.max_apps) {
>                 return -1;
>         }
>         // get the id for your app
>         int id = uwsgi_apps_cnt;
>         // get a pointer to your function
>         void *ptr = dlsym(something, ...);
>         // be sure to have a final \0 on mountpoint string
>         struct uwsgi_app *wi = uwsgi_add_app(id, modifier1, mountpoint,
> mountpoint_len, ptr, ptr);
I could use "something" and "something_len" here instead (sorry, realize
a repeat myself, I really just need to be sure)
>
>         // the loading time is basically 0 in c/c++ so we can hardcode them
>         wi->started_at = uwsgi_now();
>         wi->startup_time = 0;
>
>         // ensure app is initialized on all workers (even without a master)
>         uwsgi_emulate_cow_for_apps(id);
>         return id;
> }
>
> as you can see uwsgi_add_app() last two arguments are the same. This is
> because i did not find something additional to pass, but you can use it
> for whatever you want
This makes sense, even though I have done it in another way, but I still
have a few questions :

 * why are you registering the app using the mount point, could you have
done it on "something" elements instead ?
 * ptr in your example is the "callable" and "interpreter" what uwsgi
just pass along together with app request ?
 * I really thought that wi->request_subhandler was the handler of app
requests, if it is not, then what is it then for ?
> now in your request() handler you can get the app with:
>
> wsgi_req->app_id = uwsgi_get_app_id(wsgi_req, wsgi_req->appid,
> wsgi_req->appid_len, modifier1);
Ok, so the mount logic mathes the "path mount point" and map it to a
appid string, but not the integer app_id but its string name, so I have
to lookup this to get the integer id ?

I can see where we are getting at, and I can follow the logic in the
python code now ... thanks.

It would have been nice if we only got the app_id integer, directly as I
guess the mount / route logic already know this (it gets the id from the
mount_app callback), but then again there may be a reason the makes
perfectly sense at some level :-) ?
> and if it is >= 0
>
> struct uwsgi_app *wi = &uwsgi_apps[wsgi_req->app_id];
>
> and in wi->interpreter or wi->callable you have the pointer of your function
Ok, if I can get this far i know what to do ...
> Well, i think it should be enough for starting :)
This was extremely useful info, thanks, it is much more easy too skim
through your python code now :-)
> Remember that once you have defined mountpoints, you need to add some
> "routing rule", the simple one is --manage-script-name that maps
> SCRIPT_NAME to the mountpoint, but you can set complex rule with the
> internal routing framework:
>
> route = ^/foo setapp:/foo
>
So this "route" is an extended version of mount ?

The manage-script-name, will work even if I test using curl and http-socket ?

The simple mount string is a simple match and a "something" string that
the plugin can interpret as it seems fit ? The "something" is the name
of the python module to load in the python module, and I could use it to
identify some apps/functionality in by module (jsonrpc, rest ...), to
make the mapping happens ?

Thanks for this, I hope you may be able to answer the last few questions
equally clear :-)

/BL
_______________________________________________
uWSGI mailing list
[email protected]
http://lists.unbit.it/cgi-bin/mailman/listinfo/uwsgi

Reply via email to