Starting off with ewgi

0 views
Skip to first unread message

Davide Marquês

unread,
Aug 30, 2009, 4:22:06 PM8/30/09
to ewgi
Hi all, :)

Again I repeated the nasty habit of hacking code before getting to
know to community. My bad, won't happen again. :)
I tried out ewgi, ewgi_examples and smak with yaws and found some
issues that were easy to fix - so I did (please consider this my
github pull request :)).

The main obstacle in "getting" ewgi was figuring out how the
middleware is connected in the "real world". I got that they're just
functions chained together, but all the projects mentioned above are
lacking good examples on how this "should" be done.

Looking at smak authentication (basic and cookie) I found it hard to
separate between the creation of middleware and the chaining process.
Some itches:
- middleware sometimes needs additional arguments upon creation;
- how do we handle errors that pop up when:
- creating middleware
- running middleware
- new modules can offer functions that _create_ middleware or _run_
middleware

Enough bitching. :) I did see that a standard way of doing things
exists (handle/1 for running the middleware and
ewgi_application:module_mw/1 to create the corresponding wrapper) but
it's not widespread.
Dmitrii's suggestions (http://groups.google.com/group/ewgi/
browse_thread/thread/f9042018cb27baa3?pli=1) also seem nice but I
haven't quite groked them yet:
-module(middleware_module)
run(Ctx, App) ->
Ctx1 = modify_request(Ctx), %% optional
Ctx2 = App(Ctx1),
Ctx3 = modify_response(Ctx2), %% optional
Ctx.
%% or
%% run(Ctx, App, AdditionalModuleOptions)

I'd pick up on this last line and suggest that we use that 3rd
argument everywhere for passing initial arguments to the middleware.
This would enable rewritting/calling the ewgi_examples as:
- ewgi_stream_file:serve_file(Ctx, File) as ewgi_stream_file:run(Ctx,
[File]);
- ewgi_hello:hello_app(Ctx) as ewgi_hello:run(Ctx, []);
- ewgi_index:handle(Ctx) as ewgi_index:run(Ctx, []);
- ewgi_post:post_app(Ctx) as ewgi_post:run(Ctx, [NoPostApp,
FailPostApp, OkPostApp])
thus making all app modules look the same! :)

A related change would be necessary in ewgi_application:
module_mw(Module, Args) ->
F = fun(Context) ->
Module:run(Context, Args)
end,
F.

After that I believe things would become much easier (for newcomers at
least).
Any comments are welcome! :)

Cheers,
Davide :)

Hunter Morris

unread,
Sep 1, 2009, 4:47:07 AM9/1/09
to ew...@googlegroups.com
2009/8/30 Davide Marquês <nes...@gmail.com>:

>
> Hi all, :)
>
> Again I repeated the nasty habit of hacking code before getting to
> know to community. My bad, won't happen again. :)
> I tried out ewgi, ewgi_examples and smak with yaws and found some
> issues that were easy to fix - so I did (please consider this my
> github pull request :)).

Excellent, thank you! Please continue hacking. The ewgi community is
admittedly quite small at the moment, so an email will do just fine.

> The main obstacle in "getting" ewgi was figuring out how the
> middleware is connected in the "real world". I got that they're just
> functions chained together, but all the projects mentioned above are
> lacking good examples on how this "should" be done.

I agree. We are (slowly) working on getting some solid "real-world"
examples out there for people to understand. If you produce any (even
small) projects while hacking around, please feel free to send them to
the list and we will consider adding them/you to the ewgi_examples
project.

Great suggestion. It also frees us from the potential perils of
parameterised modules.

Thanks again and welcome to the group,
Hunter

Davide Marquês

unread,
Sep 2, 2009, 7:28:00 PM9/2/09
to ew...@googlegroups.com
Hi again! :)

On Tue, Sep 1, 2009 at 9:47 AM, Hunter Morris <hunter...@gmail.com> wrote:

2009/8/30 Davide Marquês <nes...@gmail.com>:
>
> Hi all, :)
>
> Again I repeated the nasty habit of hacking code before getting to
> know to community. My bad, won't happen again. :)
> I tried out ewgi, ewgi_examples and smak with yaws and found some
> issues that were easy to fix - so I did (please consider this my
> github pull request :)).

Excellent, thank you!  Please continue hacking.  The ewgi community is
admittedly quite small at the moment, so an email will do just fine.

I applied the changes I talked about in ewgi and ewgi_examples and added some features. :)
Repositories:
http://github.com/davide/ewgi/tree/master
http://github.com/davide/ewgi_examples/tree/master

The full changelog is:
 - ewgi_examples now use run/2;
 - added the Args parameter to the functions in ewgi_application;
 - ewgi_stream_file would fail if the webserver spawned a process to read the file (fixed by moving file:open/2 to the head of the stream);
 - added support for chunked transfer encoding in Yaws;
 - added a script and config files for Yaws.

> The main obstacle in "getting" ewgi was figuring out how the
> middleware is connected in the "real world". I got that they're just
> functions chained together, but all the projects mentioned above are
> lacking good examples on how this "should" be done.

My issue with connecting middleware remains. :)
In beepbeep's documentation there are references to a "chain of components" but I feel that we should look at it like a "graph of components" instead.
The example that got me thinking about this was my version of ewgi_post where the exit paths for the computation got clearly identified:
run(Ctx, [NoPostApp, FailedPostApp, SuccessPostApp, MaxLength]) ->
  Parser = post_parse_middleware(MaxLength, SuccessPostApp, FailedPostApp),
  case ewgi_api:request_method(Ctx) of
    'GET' ->
      NoPostApp(Ctx);
    'POST' ->
      Parser(Ctx)
  end.

This approach seems relevant in that it frees the "next component in the chain" from having to check whether the previous component succeeded or not.
For each possible path we'll have a different application/"exit port" (looking at it from a data flow programming perspective).
I still don't know how I'd hook it all up but perhaps a single module that defines and binds all applications together is enough.
How do you do it in your projects?

Tomorrow I'll try this approach with some of the smak middleware and see how it goes.
 
I agree.  We are (slowly) working on getting some solid "real-world"
examples out there for people to understand.  If you produce any (even
small) projects while hacking around, please feel free to send them to
the list and we will consider adding them/you to the ewgi_examples
project.

Will do! :)

Thanks again and welcome to the group,
Hunter
Thanks! It's cool to see some familiar faces (hi guys)! :)

Cheers,
Davide :)
Reply all
Reply to author
Forward
0 new messages