Commit Graph

175 Commits

Author SHA1 Message Date
Steve Cohen
fd8600815d Booleans can have integer default values (#143)
Booleans can have 1 and 0 as default values. This converts them into
true and false, so we can deal with them properly.

Fixes #142
2017-01-03 14:18:47 -08:00
Jon Parise
9cd1d502a1 Rename service_module_name/2 to just module_name/2 (#141)
This avoids a bit of "stutter" because we always call this function via
the Service module namespace (e.g. `Service.module_name`).
2017-01-03 14:18:25 -08:00
Steve Cohen
910172c58f Server improvements (#139)
* Server improvements

The server's start_link didn't actually start_link. I've changed this to
bring the server's supervision into the user's application.

Also, we weren't properly cleaning up after server errors, so now I just crash.
2017-01-03 12:44:41 -08:00
Preston Guillory
c51fb22918 Allow 'default required' fields to be nil (#137)
* Allow 'default required' fields to be nil

We discovered that other Thrift implementations we use internally do not
serialize unset 'default required' fields. This change brings our
implementation's behavior in line with the others.

* Test that optional fields are serialized
2017-01-03 12:39:47 -08:00
Jon Parise
207a81356d Small improvements to the binary protocol type IDs (#132)
1. Fix the `type_id` typespec to use the correct value range.
2. Add a formal `@stop` type identifier (0) and use it below.
2017-01-03 09:32:22 -08:00
Dan Swain
5273c677b7 Handle empty and non-empty default containers (#135)
* Handle empty list and set defaults
2017-01-03 09:09:26 -08:00
Jon Parise
26c6f97df1 Always treat struct field IDs as ::16-signed (#133)
We were using using `::size(16)` in many cases, which is an unsigned
integer value. The specification says this should be a signed value.
2017-01-02 20:54:27 -08:00
Steve Cohen
96ed239ed9 Better exception handling (#131)
Not all exceptions have a message; they all play well with Exception.message though.
2017-01-02 20:53:12 -08:00
Steve Cohen
f2cb210282 Enum and union behaviours (#130)
* Added Enums and unions to behvaiour
2017-01-02 19:44:32 -08:00
Dan Swain
67a85df415 Merge pull request #128 from dantswain/syntax_errors
Raise a meaningful exception on parse errors
2017-01-02 22:16:13 -05:00
Dan Swain
e11eaabde1 More PR feedback 2017-01-02 22:12:09 -05:00
Dan Swain
852f7d9971 Merge branch 'thrift_tng' into syntax_errors 2017-01-02 22:10:34 -05:00
Jon Parise
579f4fd101 Minor improvements to the Thrift compile task (#129)
- Our command line options now more closely mimic the Apache Thrift
  compiler's. We support both long and "short" option formats.
- The compile task's output now simply prints "Compiling N files", which
  is the Elixir 1.3+ output convention. Use the `--verbose` command line
  option to see per-file output.
- The compiler task's unit test helper code has been simplified a bit.
2017-01-02 17:53:16 -08:00
Preston Guillory
8c81e90c5d Enforce field requiredness during serialization (#127)
Enforce field requiredness during serialization

The IDL spec [1] states that required fields must always be written during
serialization. There are also "default required" fields, i.e. fields specified
neither as required or optional. Apparently they also should always be written,
though there are exceptions to which the spec alludes but about which it does
not deign to elaborate.

[1]: https://thrift.apache.org/docs/idl#field-requiredness
2017-01-02 17:26:13 -08:00
Preston Guillory
35af4fea49 Require atom for StructGenerator.generate label (#125)
Require atom for StructGenerator.generate label

Previously its argument type was inconsistent, being sometimes a string and
other times an atom.
2017-01-02 16:21:04 -08:00
Jon Parise
fb2dfee7db Bump our minimum Elixir version to 1.3 (#126)
This gives us the ability to use 1.3+ APIs as we develop our 2.0 branch.
Many other libraries (Absinthe, Dialyxir) also have a 1.3+ requirement.

Also, Elixir 1.4 is imminent, so add that to our testing matrix too.
2017-01-02 14:32:46 -08:00
Steve Cohen
cb372ecb07 Binary Framed server (#116)
* Binary Framed server

This is the implementation of the binary thrift framed server. It features
a configurable acceptor pool and generates code to make serialization and
deserialization automatic.
2017-01-02 14:06:55 -08:00
Dan Swain
4a7c45516a Dialzyer, handle lexer error line numbers, test to its own file 2017-01-02 15:31:43 -05:00
Dan Swain
2fcad89460 Raise a meaningful exception on parse errors 2017-01-01 21:53:25 -05:00
Jon Parise
604f5b5b33 The Thrift compiler task now uses Thrift.Generator (#124)
Our :thrift compiler is now implemented in terms of our Elixir code
generation framework. This drops our dependency on the Apache Thrift
compiler binary.

The new Thrift.Generator.targets/1 function is used to determine the
full set of generated output files for a given input .thrift file. This
ensures that we only generate Elixir source code for stale outputs.

It can now do everything that `thrift.generate` could do, so we can
retire the latter.
2016-12-31 17:02:47 -08:00
Jon Parise
aec78ba97d Fix main reference to the README document (#123)
This appears to be case-sensitive, and I wasn't noticing because the
macOS's file system isn't.

Also, remove the Apache License batch from the README because it doesn't
render that well as part of the generated documentation. We may want to
remove the other badges later too if we continue to use the README as a
key part of our Hex-published docs.
2016-12-31 11:46:14 -08:00
Jon Parise
d5991de479 Add missing :union data type (#119)
Also, improve container patterns and recognize :message_begin as
a serialize/2 type.
2016-12-31 09:50:49 -08:00
Jon Parise
1f5462bba8 Remove the Apache Thrift Erlang runtime library (#122)
We still have a copy under test/support/src/ that's used by our
integration tests, but we otherwise no longer have any need to ship a
copy of Apache Thrift Erlang runtime.
2016-12-31 09:02:51 -08:00
Preston Guillory
a631ff73e7 Shorten binary expression in test (#121) 2016-12-30 23:12:18 -08:00
Steve Cohen
5ed03b4f27 Fix typedefs with container types (#118)
* Fix typedefs with container typees
2016-12-30 16:27:12 -08:00
Jon Parise
fa4d091fdb Update packaging to reflect our 2.0.0-dev status (#117) 2016-12-30 16:09:25 -08:00
Jon Parise
3814fb862b More docs and typespecs for the Binary module (#113) 2016-12-30 15:23:17 -08:00
Jon Parise
098fa068f5 Clean up public Thrift.Parser documentation (#115)
This primarily hides internal-only documentation but also includes some
minor doc and typespec cleanup.
2016-12-30 15:20:34 -08:00
Jon Parise
0517ba9485 Restructure env-specific builds paths (#114)
Define :test-specific (instead of :prod-specific) lists of build paths.
This fixes an issue where :dev builds would include test code and things
like `mix docs` would parse and document tests.

Because our benchmarks also use test code (e.g. ParserUtils), that
command is runs in the :test environment.
2016-12-30 14:34:17 -08:00
Jon Parise
54e163c311 Add Preston to the maintainers list (#109) 2016-12-30 13:13:01 -08:00
Dan Swain
1af7c4ee1d Clean up some dialyzer warnings (#110)
Mostly this was just configuring dialyzer.  The jsx version update is to
clear a dialyzer crash that the old version caused.
2016-12-30 13:12:41 -08:00
Jon Parise
a774cc968c Protocols -> Protocol in the module namespace (#108)
The singular convention is more common in the Elixir ecosystem. This
matches our singular "Generator" namespace name, too.
2016-12-30 12:41:59 -08:00
Jon Parise
a1efe75d0f Simplify the binary type ID mapping (#106)
We previously defined a @types map that was used to generate function
matches for each known type. Because we only use @types for that one
purpose, it's simpler and more readable to just write out the function
heads explicitly.

This change also renames `int_type` to `type_id` for consistency with
the typespec name.
2016-12-30 12:04:23 -08:00
Jon Parise
0550bcdfcc Tidier serialize/2 function clause formatting (#107) 2016-12-30 12:02:35 -08:00
Jon Parise
a335ce5dff Remove the default serialize/2 match for nil (#105)
The way we serialize `nil` is context-specific and should be handled by
the more specific type-aware clauses below.
2016-12-30 10:06:03 -08:00
Jon Parise
793ff8f20c Use pattern matching to serialize bool values (#104)
This eliminates the private bool_to_int/1 function and lets us return
constant binary result values directly.

We also strictly match on just the true and false atoms.

There is a nominal performance improvement, but nothing significant.
2016-12-30 09:28:49 -08:00
Jon Parise
5a6504aa6b Move skip_field/2 to the Binary protocol module (#103)
We were previously generating private copies of the "skip" functions in
each generated struct module. These functions are generic and have been
moved to the top-level Binary protocol module instead. The reduces the
size of the generated modules by a nice amount.

We only skip unrecognized fields so this code shouldn't be called very
often. In practice, however, we can't predict how often this case will
arise, so the performance of these function is important. Fortunately,
this change doesn't introduce a measurable performance cost.

Lastly, this change adds Binary module documentation and some initial
typespecs.
2016-12-29 21:58:53 -08:00
Jon Parise
ed0ee43c1d Remove Enum.reverse/1 calls from MapSet creation
Sets are inherently unordered so there's no reason to pass ordered lists
to MapSet.new/1. This change results in a minor performance improvement.
2016-12-29 17:14:18 -08:00
Preston Guillory
ba2f03d59d Remove UnionSerializationBenchmark (#101)
The changes to ParserUtils were fumbled and broke BinaryProtocolBenchmark,
which is the more valuable benchmark. UnionSerializationBenchmark was used to
check the performance impact of a particular commit and isn't really worth
maintaining.
2016-12-29 14:10:37 -08:00
Jon Parise
206d8d11ee Merge branch 'master' into thrift_tng 2016-12-29 10:42:33 -08:00
Steve Cohen
4695aaed34 Behaviour module generation (#99)
* Behaviour module generation

For the server side, I imagine that the user would specify a handler
module and pass it into the service. Then it would be called with the
appropriate arguments.
I thought it might be nice to have a behaviour for these modules that
users could be implement.

Behaviours here are fully typed with the correct success types.
2016-12-29 10:42:28 -08:00
Jon Parise
faed878956 Merge branch 'master' into thrift_tng 2016-12-29 09:46:06 -08:00
Preston Guillory
ceceea9a66 Improve iolist optimization (#94)
* Improve iolist optimization

The new function `optimize_iolist` combines the old `merge_binaries` and
`simplify_iolist` functions. It also improves on them slightly, for instance by
terminating iolists with a binary instead of the empty list, and by more
consistently combining adjacent binaries.

* Document iolist optimization steps
2016-12-29 09:28:39 -08:00
Jon Parise
cd95abad2e Simplify the Travis build matrix (#87) 2016-12-29 09:18:26 -08:00
Jon Parise
06d2d75680 Only build dialyxir in :dev
Also, exclude it from the list of runtime applications because it has no
runtime component.
2016-12-29 07:59:34 -08:00
Jon Parise
e79b711818 Add the u field to ParserUtil's User support 2016-12-28 18:01:44 -08:00
Jon Parise
6963b315db Add _bench.exs suffixes to benchfella scripts (#96)
This allows the `mix bench` command to automatically discover its test
scripts.

Also, we only need to build benchfella in :dev and not :test.
2016-12-28 16:35:15 -08:00
Preston Guillory
5a23bea4c6 Specialize boolean field serializer (#93)
It was producing a redundant case statement.

  case foo do
    nil -> <<>>
    _ ->
      [<<2, id::size(16)>>, case foo do
        nil   -> <<0>>
        false -> <<0>>
        _     -> <<1>>
      end]
  end

The new output is simpler, both in the number of case statements and in the
structure of the iolist returned.

  case foo do
    nil   -> <<>>
    false -> <<2, id::size(16), 0>>
    _     -> <<2, id::size(16), 1>>
  end
2016-12-28 15:15:14 -08:00
Steve Cohen
3316411fa1 More robust handling of void return types (#92)
* More robust handling of void return types

The erlang server replies to void responses with <<12, 0, 0, 0, 0>>
which is an empty struct and the stop byte from the respone
struct. Other implementations just reply with the stop byte from the
response struct. We can now parse both.

I also fixed a bug that would occur if the sequence ids or messages
would mismatch. I added tests for all cases.

* Formatting is more consistent
2016-12-28 13:45:56 -08:00
Preston Guillory
0fbee81867 Wrap long lines (#91) 2016-12-28 09:02:33 -08:00