Using Wub for an HTTP REST API...

43 views
Skip to first unread message

Georgios Petasis

unread,
Oct 7, 2011, 10:44:26 AM10/7/11
to Wub Discussion, peta...@yahoo.gr
Hi all,

I want to use Wub to create an HTTP (or HTTPS) REST service to a Tcl
application, and I have a few points I want to clarify.

I have read in the wiki page, that Wub is multi-threaded, and
approaches Apache in performance. While Apaches' performance is good
to have, but is Wub multi-threaded?

Because I have seen that you can specify an OO object as a domain, How
is this feasible with multiple threads?

Another issue is HTTPS: how easy is it to support it?

Also, is it easy to filter out requests, a parameter of which is not a
"valid" key, at the authentication stage, so as my OO object that
implements a domain never sees the request?

Regards,

George

Colin McCormack

unread,
Oct 7, 2011, 5:58:59 PM10/7/11
to wub-dis...@googlegroups.com, Georgios Petasis, peta...@yahoo.gr
On 08/10/11 01:44, Georgios Petasis wrote:
> Hi all,
>
> I want to use Wub to create an HTTP (or HTTPS) REST service to a Tcl
> application, and I have a few points I want to clarify.
>
> I have read in the wiki page, that Wub is multi-threaded, and
> approaches Apache in performance. While Apaches' performance is good
> to have, but is Wub multi-threaded?

No, Wub is not multithreaded. It uses coroutines and events to respond
to HTTP requests and generate responses.

> Because I have seen that you can specify an OO object as a domain, How
> is this feasible with multiple threads?

Direct domain uses an object instance (or a namespace) to process
requests, yes.

Well, if you had multiple threads you wanted to use to service requests,
there is a Threaded domain which is intended to help in that - its main
role is to maintain a pool of threads and proxy requests to elements of it.

It would be advisable to place some elements of your application in
processing threads, if the application is computationally intensive, and
there are no (or few) opportunities to re-enter the event loop.

There's also a domain (called Coco) for constructing a coroutine per
client connection and having it supervise such backend threads.
Coroutines are also ok for maintaining state.

> Another issue is HTTPS: how easy is it to support it?

TLS works, there's also a complete CA based on openssl shipped with
Wub. I seem to recall HTTPS over TLS is simple enough.

> Also, is it easy to filter out requests, a parameter of which is not a
> "valid" key, at the authentication stage, so as my OO object that
> implements a domain never sees the request?

It's possible, there are some facilities to preprocess HTTP requests
after they're parsed and before they're dispatched, but except for
saving a bit of code, I can't really see much point. Perhaps TclOO will
give you such a facility more easily - filter methods or somesuch?

Colin.

Georgios Petasis

unread,
Oct 7, 2011, 6:56:53 PM10/7/11
to wub-dis...@googlegroups.com
Στις 8/10/2011 00:58, ο/η Colin McCormack έγραψε:
> On 08/10/11 01:44, Georgios Petasis wrote:
>> Hi all,
>>
>> I want to use Wub to create an HTTP (or HTTPS) REST service to a Tcl
>> application, and I have a few points I want to clarify.
>>
>> I have read in the wiki page, that Wub is multi-threaded, and
>> approaches Apache in performance. While Apaches' performance is good
>> to have, but is Wub multi-threaded?
>
> No, Wub is not multithreaded. It uses coroutines and events to respond
> to HTTP requests and generate responses.
This is what I also thought, but the wiki page writes somewhere that it
has been re-written to be multi-threaded.

>
>> Because I have seen that you can specify an OO object as a domain, How
>> is this feasible with multiple threads?
>
> Direct domain uses an object instance (or a namespace) to process
> requests, yes.
>
> Well, if you had multiple threads you wanted to use to service
> requests, there is a Threaded domain which is intended to help in that
> - its main role is to maintain a pool of threads and proxy requests to
> elements of it.
Well actually I want to thread my domain, as it will be a lengthy
calculation (minutes per request).
I think it will be much easier to do this now that I know Wub is not
multithreaded.
>

> It would be advisable to place some elements of your application in
> processing threads, if the application is computationally intensive,
> and there are no (or few) opportunities to re-enter the event loop.
Yes. My app enters frequently the event loop, but better to use threads
to serve more requests.

>
> There's also a domain (called Coco) for constructing a coroutine per
> client connection and having it supervise such backend threads.
> Coroutines are also ok for maintaining state.
I am not sure I understand what coroutines are :-)

>
>> Another issue is HTTPS: how easy is it to support it?
>
> TLS works, there's also a complete CA based on openssl shipped with
> Wub. I seem to recall HTTPS over TLS is simple enough.
>
>> Also, is it easy to filter out requests, a parameter of which is not a
>> "valid" key, at the authentication stage, so as my OO object that
>> implements a domain never sees the request?
>
> It's possible, there are some facilities to preprocess HTTP requests
> after they're parsed and before they're dispatched, but except for
> saving a bit of code, I can't really see much point. Perhaps TclOO
> will give you such a facility more easily - filter methods or somesuch?
>
> Colin.
>
Thank you for your time.

George

Colin McCormack

unread,
Oct 7, 2011, 8:31:16 PM10/7/11
to wub-dis...@googlegroups.com, Georgios Petasis
On 08/10/11 09:56, Georgios Petasis wrote:
> Στις 8/10/2011 00:58, ο/η Colin McCormack έγραψε:
>> On 08/10/11 01:44, Georgios Petasis wrote:
>>> Hi all,
>>>
>>> I want to use Wub to create an HTTP (or HTTPS) REST service to a Tcl
>>> application, and I have a few points I want to clarify.
>>>
>>> I have read in the wiki page, that Wub is multi-threaded, and
>>> approaches Apache in performance. While Apaches' performance is good
>>> to have, but is Wub multi-threaded?
>>
>> No, Wub is not multithreaded. It uses coroutines and events to
>> respond to HTTP requests and generate responses.
> This is what I also thought, but the wiki page writes somewhere that
> it has been re-written to be multi-threaded.

I did (early on) try rewriting Wub so the protocol engine was
multithreaded, this turned out to be less efficient and less responsive
than merely processing protocol in the foreground thread, but in an
event-driven manner. In the wild, it appears, requests take multiple
packets, those packets arrive in an unpredictable manner with a fair
degree of latency between them. This means that the foreground thread
has lots of time to service lots of parts of lots of HTTP protocol
bundles, so the event-driven mechanism works well to keep them all
serviced - particularly since the parsing part is fairly simple string
manipulation.

It is also worth bearing in mind that Wub is a toolkit with lots of
support libraries. It comes with a default assembly/configuration which
I know works, but which can be freely rearranged.

One part of the tool kit (Httpd.tcl) merely handles decoding and
dispatch of HTTP requests, and the delivery of responses in-order. It
then calls out to a *different* and completely repluggable module for
'dispatch', which is the process of routing a request to some code which
will handle it and return a result. The dispatch module can be
rewritten or replaced if you want. Additionally, and by the way, the
Httpd module itself can be rewritten or replaced (there is, for example,
a mechanism for plugging wibble in instead of Httpd.tcl, and interfacing
it and its dispatch mechanism to the rest of the toolkit - although I
wouldn't recommend it, as wibble is not properly HTTP1.1 compliant.)

Another part of the tool kit (the part in Domains/) is a bunch of
modules which will plug into the dispatch component interface (API)
exported and supported by Httpd to provide semantics which turn requests
into responses. These domains give you lots of different flavours of
processing for given requests. The Direct domain directs requests onto
object method or namespace proc calls after converting HTTP GET
parameters into Tcl arguments. Coco domain maps requests onto
coroutines created upon initial connection, so the coroutine body can
consume and transform requests ad hoc. File maps requests onto a
filesystem, returning named file content, named directory content and
named script invocation results into HTTP responses. Mason is like a
File domain on steroids - with extra semantics provided by special files
in the filesystem. CGI maps requests onto cgi processes.

There are special purpose domains like OAuth, Tiny (for tiny urls,)
ReCAPTCHA, FossilProxy, jQ etc for wrapping 'round other facilities and
providing services.

There are experimental and sketch domains like Simplico, Sinorca, Sql
(encodes full SQL queries in the GET part, providing content from a tdbc
db.)

The interface is pretty simple: You get a request as a Tcl dict, you
transform it into a response dict (using, usually, the facilities in
Http and Html utility packages) and return that. You can also suspend
processing of a request, so Httpd will continue to service the pipeline,
until a result becomes available, at which time you resume the
processing of that request with the result.

There's also a *big* pile of Utilities (in Utilities/) which provide all
kinds of stuff - cookie handling, form generation and processing,
generating HTML tables, sending email, etc etc.

>>> Because I have seen that you can specify an OO object as a domain, How
>>> is this feasible with multiple threads?
>>
>> Direct domain uses an object instance (or a namespace) to process
>> requests, yes.
>>
>> Well, if you had multiple threads you wanted to use to service
>> requests, there is a Threaded domain which is intended to help in
>> that - its main role is to maintain a pool of threads and proxy
>> requests to elements of it.
> Well actually I want to thread my domain, as it will be a lengthy
> calculation (minutes per request).
> I think it will be much easier to do this now that I know Wub is not
> multithreaded.

I would use a pool of threads, initiate some asynchronous threaded
operation from within the domain (perhaps a Direct domain, particularly
if I was expecting to handle a lot of parameters) and suspend the
request [Httpd Suspend $request] until the asynchronous process
completed, at which point I would probably have *it* call [::Httpd
Resume $result] with the calculation wrapped up as a response derived
from the original $request, and it would all just happen. In fact,
Threaded domain may well do most of what is needed for that, depending
on how much you want to do in the thread, and how much in the
dispatch-part of handling.

>>
>> It would be advisable to place some elements of your application in
>> processing threads, if the application is computationally intensive,
>> and there are no (or few) opportunities to re-enter the event loop.
> Yes. My app enters frequently the event loop, but better to use
> threads to serve more requests.

Certainly if it's a long-lived computation.

>
>>
>> There's also a domain (called Coco) for constructing a coroutine per
>> client connection and having it supervise such backend threads.
>> Coroutines are also ok for maintaining state.
> I am not sure I understand what coroutines are :-)

You can think of them as cooperative lightweight threads. Not likely to
help if you have lots of computation to perform. More likely to help if
you have to call out to other networked services, and lightly transform
the results of that.

Colin.

Reply all
Reply to author
Forward
0 new messages