Hi Anton,
Two rather long questions:
1. Wouldn't it be nicer if piqic generated behaviour's rather than header files with -spec's?
Since R15B you can specify typed callbacks. In my opinion it would be more elegant for piqic to generate a `foo_module_piqi_impl.erl` (vs. `*.HRL`) which would contain exactly the same things as the header file, except for `-spec` replaced by -callback`. It could even contain a default "stub" implementation as in the `foo_module_default_impl.erl`.
Pros:
* "morally" the right thing -- your callback module implements the RPC methods, so it implements the specified behaviour, consistent with OTP philosophy, etc.
* Dialyzer will be happy.
* At least some versions of `edoc` fail currently if you include the `.hrl` file, because it expects spec's next to the function definition.
* A small PITA will be fixed: the current HRL file imports the `foo_module_piqi.hrl` file, which means that if you have some other header which wants to depend on the types defined in the `user_piqi.hrl` you can't import both of these into a common module.
* in the future Erlang will probably support optional callbacks (such as `gen_server:format_status/2`), you could for now export them as "$(behaviour-name)_optional" or so, though currently there are no optional callbacks in piqi-rpc.
Cons:
* breaks support for pre-R15B. You could continue generating HRL files for that use case.
* can't really think of anything else
If you agree with this, I think I would be able to provide a patch for it.
2. You mentioned long ago that piqi 0.6.0 would add support for RPC method hooks. I don't seem to find any further information regarding this.
I suppose it did not happen? Do you have any further plans for this?
Actually, IMHO you shouldn't implement this, because that's not the responsibility of piqi-rpc. People can always add whatever custom hooks they want as part of the implementation module. But I am now working on a generic hook mechanism (on top of piqi RPC), so just wanted to check whether there's anything already out there.
The only problematic case is when you want to pass/retrieve transport-specific data (such as HTTP headers). Support for that could be improved, but I would argue it's best if this is simply passed/returned as an extra `transport_data` term from the implementation module, rather than as some kind of external hook, because in some cases this is some method-and-input specific data, rather than generic headers.
So e.g. you could have two functions of different arities for each method: one which only inputs/outputs the deserialised request data and one which also has as an extra argument of type `{transport_type(), [tranport_data()]}` and responds with `[transport_data()]`, so e.g.
Input = {#foo_module_method_input{}, {http, [
{http_headers, [
{<<"Accept-Language">>, ...},
{<<"Cookie">>, ...}
}},
...
}
And the response could be:
Output = {{ok, #foo_module_method_output{}}, [{http_headers, [{<<"Age">>, 11}]}]}.
But it's hard to say if this is the cleanest / most generic solution.
Anyway, sorry for the long email and thanks for bringing us piqi!
--
Ignas