A few notes:
- Callables: IMHO here we should find a clean way to specify modules to
be called on remote nodes.
Might a tuple {Node, Mod, Handler} work?
- Why use {ewgi_context, Request, _Response} instead of simply
{Request, Response}
>
>> I do not think that there will be so many elements in the header that
>> performance would be an issue even if using a simple key-value list ( if you
>> also have direct access to the primary ones ) but of course having an own
>> api, so that it is possible to change the implementation, is a good thing in
>> case you need that.
>> Also some parts maybe more efficient if atoms instead of strings are used?
>> {'GET',...} instead of {"GET", ..} ?
>
> Yes, I agree that atoms may be more useful in certain situations.
> Let's examine common requests and modify the spec as necessary.
I agree too.
>> Using records? Maybe, but you will get compile dependencies to .hrl files.
>> If the number of elements in the tuple are kept small and most of the Header
>> goes into the key-value bag it may not be necessary.
>
> My first crack at changing the spec has some heavyweight tuples.
> Perhaps your suggestion for reducing the size could make records less
> necessary.
>
IMHO we coud move the remote_* and the server_*
>> Your streaming solution looks very elegant and functional :-). If I
>> understood Filippos comment I beleive one argument (fun/1) could be added to
>> use the same RequestResponse tuple in the call to that if for instance the
>> disc got full during upload and transmission needs to be interrupted, right
>> - or was it the Status in the Response that should change? Should the
>> streaming fun also return a value on RequestResponse format? This could open
>> for some interesting solutions, same interface everywhere...
>
> That's an interesting idea. Take a look at the 'read_input' EWGI
> variable in the request. I made use of a callback mechanism which is
> similar to continuation-passing style. I haven't really treated error
> conditions fully in the spec yet, but I would like to as that's where
> Erlang really soars. ;)
>
Yes I was thinking to the same interface also for streams: they get
ReqResponse and returns the same.
For errors my idea was to simply manage it through the status code, but
the solution as is in the specs is much better.
cheers,
filippo
>
>> - Why use {ewgi_context, Request, _Response} instead of simply
>> {Request, Response}
>
> It maintains compatibility with the records (for convenience).
Ok.
>
>> IMHO we coud move the remote_* and the server_*
>
> Should we put them into a separate part of the record or put them into
> the key-value bag?
Yes I was thinking to put them in the bag. Just to have a smaller
request tuple.
>
> Some additional things I want to work out are:
>
> * What data structure should the HTTP header and EWGI data bags be?
> I initially started by implementing a dict, but since the number
> of pairs in each is likely to be quite small, a property list might
> perform better?
The interface of proplists IMHO is cleaner, but this is a matter of
taste and if you already have a dict in place that's fine for me :-).
As long as we have an api to look into it we can also change the
implementation later.
Another thing to consider is if we should use atoms or strings as keys
in the bag.
We changed from atoms to strings in the past because, as you pointed
out, and if I remember well :-), atoms might be exposed to an attack
where a malicious user sending requests with different http headers
might exhaust the atoms.
>
> * What data structure should the "error" property in the Response be?
> Python uses output from sys.exc_info(). Perhaps we should use the
> form of the output from erlang:get_stacktrace/0, which is [{Module,
> Function, Arity | Args}].
Yes I agree. We should do like in python: suggest to use a try/catch in
the application and in case of error return erlang:get_stacktrace/0
What do we do with the stack trace in the server implementation?
We call error_logger:error_report/1
We might also consider some options to specify a custom error logger.
What do you think?
I'd use the bag concept for the less used fields.
What about:
-record(ewgi_request, {
request_method, %% atom: 'GET', 'POST', etc
script_name,
path_info,
ewgi=#ewgi_spec{},
http_headers=#ewgi_http_headers{},
path_translated,
query_string,
others %bag
}).
The content-type / lenght might go in the headers the rest in the bag.
Would this be too slow?
Yes!
Hunter Morris wrote:
> On Oct 9, 5:13 pm, Filippo Pacini <filippo.pac...@gmail.com> wrote:
>> I gave a look at the specification. I think this is the right way to do it.
>>
>> A few notes:
>> - Callables: IMHO here we should find a clean way to specify modules to
>> be called on remote nodes.
>> Might a tuple {Node, Mod, Handler} work?
>
> Do you mean calling them using the rpc module?
Ok.
>
>> - Why use {ewgi_context, Request, _Response} instead of simply
>> {Request, Response}
>
> It maintains compatibility with the records (for convenience).
Yes I was thinking to put them in the bag. Just to have a smaller
>
>> IMHO we coud move the remote_* and the server_*
>
> Should we put them into a separate part of the record or put them into
> the key-value bag?
request tuple.
The interface of proplists IMHO is cleaner, but this is a matter of
>
> Some additional things I want to work out are:
>
> * What data structure should the HTTP header and EWGI data bags be?
> I initially started by implementing a dict, but since the number
> of pairs in each is likely to be quite small, a property list might
> perform better?
taste and if you already have a dict in place that's fine for me :-).
As long as we have an api to look into it we can also change the
implementation later.
Another thing to consider is if we should use atoms or strings as keys
in the bag.
We changed from atoms to strings in the past because, as you pointed
out, and if I remember well :-), atoms might be exposed to an attack
where a malicious user sending requests with different http headers
might exhaust the atoms.
Yes I agree. We should do like in python: suggest to use a try/catch in
>
> * What data structure should the "error" property in the Response be?
> Python uses output from sys.exc_info(). Perhaps we should use the
> form of the output from erlang:get_stacktrace/0, which is [{Module,
> Function, Arity | Args}].
the application and in case of error return erlang:get_stacktrace/0
What do we do with the stack trace in the server implementation?
We call error_logger:error_report/1
We might also consider some options to specify a custom error logger.
What do you think?
We might define a callable as one of:
- a function in the same module- a function in another module
- a parametrized module M (in this case we call M:handle)
- a Module, and Function on a remote node. How do we specify this
case?
{Node, Mod, Fun} as you say might conflict with the above.
Parameterized modules gives a lot of flexibility so HIMO we should
find a way to fit them in the specs.
> Good point. Any application would have to be careful and convert only from aGoogling quickly I didn't find much. Maybe we should ask the erlang-
> set of matching strings to predefined atoms if they are to be used. How is
> atoms garbage collected today, there has been some improvements here lately
> if I remember right.
questions mailing list.
> I am not sure how the error property is going to be used. Can't errors beSometimes handling the error where it occurs is easier for debugging.
> handled with try catch only - or that is maybe your suggestion?
So my suggestion (Hunter actually :-)) was to use of the try/catch in
the application handle.
>I agree with this.
> I also think that the Status part of the response should be grouped into one
> tuple as before - this makes it possible to use the predefined macros. It is
> not so easy to do it if they are the first and second element in a longer
> tuple.
>> Concerning streaming - if the MessageBody part of the response always wouldIMVHO this would complicate the build up of the response without many
> be on the form {iolist(), Extra }, were the second element could be a stream
> (fun/1) or undefined (or any future addons to the spec...) would this make
> the API simpler? Or more complicated? It would anyway mean that a callable
> and streaming fun could both work with the same Response structure.
>
advantages.
I don't see much space for changes in the body part in the future.
Unless HTTP changes significantly :-).
best regards,
filippo
If later someone asks support for these features we'll look for a way to
fit them nicely in the specs.
Best regards,
filippo