beambridge 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +23 -0
  3. data/.rspec +2 -0
  4. data/Gemfile +4 -0
  5. data/History.txt +35 -0
  6. data/LICENSE +20 -0
  7. data/README.md +130 -0
  8. data/Rakefile +44 -0
  9. data/VERSION.yml +4 -0
  10. data/beambridge.gemspec +29 -0
  11. data/benchmarks/bench.rb +21 -0
  12. data/examples/echo/README.md +12 -0
  13. data/examples/echo/echo.erl +13 -0
  14. data/examples/echo/echo.rb +10 -0
  15. data/examples/gruff/gruff.erl +61 -0
  16. data/examples/gruff/gruff_provider.rb +30 -0
  17. data/examples/gruff/gruff_run.sh +19 -0
  18. data/examples/gruff/stat_run.sh +20 -0
  19. data/examples/gruff/stat_writer.erl +40 -0
  20. data/examples/simple/README.md +5 -0
  21. data/examples/simple/rerl.rb +110 -0
  22. data/examples/simple/rerl.sh +37 -0
  23. data/examples/tinderl/README.md +14 -0
  24. data/examples/tinderl/tinderl.erl +43 -0
  25. data/examples/tinderl/tinderl.rb +27 -0
  26. data/ext/decoder.c +398 -0
  27. data/ext/extconf.rb +11 -0
  28. data/lib/beambridge.rb +34 -0
  29. data/lib/beambridge/condition.rb +66 -0
  30. data/lib/beambridge/conditions/boolean.rb +11 -0
  31. data/lib/beambridge/conditions/hash.rb +13 -0
  32. data/lib/beambridge/conditions/static.rb +34 -0
  33. data/lib/beambridge/conditions/type.rb +17 -0
  34. data/lib/beambridge/constants.rb +36 -0
  35. data/lib/beambridge/decoder.rb +212 -0
  36. data/lib/beambridge/encoder.rb +164 -0
  37. data/lib/beambridge/errors/beambridge_error.rb +3 -0
  38. data/lib/beambridge/errors/decode_error.rb +3 -0
  39. data/lib/beambridge/errors/encode_error.rb +3 -0
  40. data/lib/beambridge/matcher.rb +21 -0
  41. data/lib/beambridge/port.rb +48 -0
  42. data/lib/beambridge/receiver.rb +69 -0
  43. data/lib/beambridge/types/function.rb +3 -0
  44. data/lib/beambridge/types/list.rb +3 -0
  45. data/lib/beambridge/types/new_function.rb +3 -0
  46. data/lib/beambridge/types/new_reference.rb +3 -0
  47. data/lib/beambridge/types/pid.rb +3 -0
  48. data/lib/beambridge/types/reference.rb +3 -0
  49. data/lib/beambridge/version.rb +3 -0
  50. data/spec/condition_spec.rb +72 -0
  51. data/spec/decode_spec.rb +143 -0
  52. data/spec/encode_spec.rb +152 -0
  53. data/spec/matcher_spec.rb +81 -0
  54. data/spec/port_spec.rb +34 -0
  55. data/spec/receiver_spec.rb +103 -0
  56. data/spec/spec_helper.rb +47 -0
  57. metadata +153 -0
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NTQwMTk5ZGE3MTQ3Y2M4M2NkYWVkMmIwZDg4ZTBhZWVkMmFmOGExNg==
5
+ data.tar.gz: !binary |-
6
+ M2Y2NGQwZWUyZDVlM2RlOTY3NzAxMTQzY2M0ZWQwYTQ5M2ViY2M5NA==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ OWIwZDViMGEyMjlkYmIzNGExMjY1MjE4ZTEzZjYwZDA0YzNkMGQ4ZTYwZDg0
10
+ N2VlNWUwMzdmOGU3MzEzMDRiOWZmMGQ1OWYyMmUwMjNiNTRlODAyOThmNjE1
11
+ NDNiNjg3NThjNzY0ODlkYmI0MGRkMjk2YjVlZGMwYmQyNWVmNGU=
12
+ data.tar.gz: !binary |-
13
+ NDdkMDc5NDIzMWMyZWJiNzk4OGRlMGI4ZWQ2MDEwYmZhNTEwYzQzMDk3N2Q1
14
+ Zjk4NzU1YjU0NTFmNjVjMWFhMjg0YzQ3MmJiNDhhNDQzNWIzNGQ3MmU2OGE3
15
+ NTFkMGQ0YjM2M2JlNjVhODA2OWI5ZDVjZjQ1MjhjZjZmOTEwMmE=
@@ -0,0 +1,23 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ ext/Makefile
14
+ ext/decoder.bundle
15
+ ext/decoder.o
16
+ *.beam
17
+ *.dump
18
+ .DS_Store
19
+ rdoc
20
+ spec/reports
21
+ test/tmp
22
+ test/version_tmp
23
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format documentation
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in beambridge.gemspec
4
+ gemspec
@@ -0,0 +1,35 @@
1
+ == 1.1.1 / 2009-10-28
2
+ * Bug Fixes
3
+ * Fix bignum encoding
4
+ * Prevent stack overflow for massive binaries in c decoder
5
+ * Optimize strings in c decoder
6
+
7
+ == 1.1.0 / 2009-10-08
8
+ * Minor Improvements
9
+ * Implement Bignum encoding
10
+ * Fix tests on Erlang R13B
11
+
12
+ == 1.0.2 / 2009-06-03
13
+ * Bug Fixes
14
+ * Fix decoding of atoms [github.com/bwbuchanan]
15
+ * Work around Ruby's reluctance to convert the empty string to
16
+ a symbol [github.com/bwbuchanan]
17
+
18
+ == 1.0.1 / 2009-05-03
19
+ * Bug Fixes
20
+ * Fix premature null byte termination on binary decode
21
+
22
+ == 1.0.0 / 2009-04-29
23
+ * Backward Incompatible Changes
24
+ * Implicit array call for f.when(:echo, String) must now be called as
25
+ f.when([:echo, String]) to eliminate ambiguity
26
+ * Implicit array call for f.send!(:ok, "foo") must now be called as
27
+ f.send!([:ok, "foo"]) to eliminate ambiguity
28
+ * The receive loop now defaults to using file descriptors 3 and 3
29
+ instead of STDIN and STDOUT. This prevents inadvertent output
30
+ statements from silently corrupting the transfer protocol.
31
+ * Erlang atoms 'true' and 'false' are now converted into Ruby booleans
32
+ * Erlectricity::Decoder.read_any_from -> Erlectricity::Decoder.decode
33
+ * Major Enhancements
34
+ * Calling `rake` now runs tests (with and without compiled C extensions)
35
+ * Package management is now done by Jeweler
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Scott Fleckenstein and Tom Preston-Werner
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,130 @@
1
+ # Beambridge #
2
+
3
+ https://github.com/mathieul/beambridge
4
+
5
+ Fork of Erlectricity by Scott Fleckenstein, Tom Preston-Werner (http://github.com/mojombo/erlectricity).
6
+
7
+ The original erlectricity gem doesn't seem to be supported and updated anymore,
8
+ no commit in 4 years, a pull request pending for the last 3 years.
9
+
10
+ So I've forked the repository origin of the pending pull request and did cherry pick
11
+ most of the pull request commits. And I had to rename the gem so I could publish it.
12
+
13
+ Development Status: port for 1.9.3, 2.0.x, 2.1.x in progress
14
+
15
+
16
+ Description
17
+ -----------
18
+
19
+ Beambridge allows a Ruby program to receive and respond to Erlang messages
20
+ sent over the Erlang binary protocol.
21
+
22
+
23
+ Install
24
+ -------
25
+
26
+ $ gem install beambridge
27
+
28
+
29
+ The Simplest Example
30
+ --------------------
31
+
32
+ ### Ruby side (echo.rb)
33
+
34
+ require 'beambridge'
35
+
36
+ receive do |f|
37
+ f.when([:echo, String]) do |text|
38
+ f.send!([:result, "You said: #{text}"])
39
+ f.receive_loop
40
+ end
41
+ end
42
+
43
+ ### Erlang side (echo.erl)
44
+
45
+ -module(echo).
46
+ -export([test/0]).
47
+
48
+ test() ->
49
+ Cmd = "ruby echo.rb",
50
+ Port = open_port({spawn, Cmd}, [{packet, 4}, nouse_stdio, exit_status, binary]),
51
+ Payload = term_to_binary({echo, <<"hello world!">>}),
52
+ port_command(Port, Payload),
53
+ receive
54
+ {Port, {data, Data}} ->
55
+ {result, Text} = binary_to_term(Data),
56
+ io:format("~p~n", [Text])
57
+ end.
58
+
59
+
60
+ Data Type Conversions and Matching
61
+ ----------------------------------
62
+
63
+ % Port is the port opened via open_port({spawn, Cmd}, [{packet, 4}, ...])
64
+ % Message is the Erlang term to encode and send to the port
65
+ send(Port, Message) ->
66
+ port_command(Port, term_to_binary(Message)).
67
+
68
+ # Each triplet below represents:
69
+ # (line 1) the Erlang call
70
+ # (line 2) the Ruby matcher
71
+ # (line 3) the Ruby output
72
+
73
+ send(Port, test).
74
+ f.when(:test) { p :ok }
75
+ # :ok
76
+
77
+ send(Port, {atom, symbol}).
78
+ f.when([:atom, Symbol]) { |sym| p sym }
79
+ # :symbol
80
+
81
+ send(Port, {number, 1}).
82
+ f.when([:number, Fixnum]) { |num| p num }
83
+ # 1
84
+
85
+ send(Port, {string, <<"foo">>}).
86
+ f.when([:string, String]) { |str| p str }
87
+ # "foo"
88
+
89
+ send(Port, {array, [1,2,3]}).
90
+ f.when([:array, Array]) { |arr| p arr }
91
+ # [1, 2, 3]
92
+
93
+ send(Port, {array, [<<"abc">>, <<"def">>]}).
94
+ f.when([:array, Array]) { |arr| p arr }
95
+ # ["abc", "def"]
96
+
97
+ send(Port, {hash, [{key,val}]}).
98
+ f.when([:hash, Erl.hash]) { |hash| p hash }
99
+ # {:key=>:val}
100
+
101
+ send(Port, {object, {1,{2},3,<<"four">>}}).
102
+ f.when([:object, Any]) { |any| p any }
103
+ # [1, [2], 3, "four"]
104
+
105
+
106
+ Contribute
107
+ ----------
108
+
109
+ If you'd like to hack on Beambridge, start by forking my repo on GitHub:
110
+
111
+ https://github.com/mathieul/beambridge
112
+
113
+ To get all of the dependencies, install the gem first. The best way to get
114
+ your changes merged back into core is as follows:
115
+
116
+ 1. Clone down your fork
117
+ 1. Create a topic branch to contain your change
118
+ 1. Hack away
119
+ 1. Add tests and make sure everything still passes by running `rake`
120
+ 1. If you are adding new functionality, document it in the README.md
121
+ 1. Do not change the version number, I will do that on my end
122
+ 1. If necessary, rebase your commits into logical chunks, without errors
123
+ 1. Push the branch up to GitHub
124
+ 1. Send me (mojombo) a pull request for your branch
125
+
126
+
127
+ Copyright
128
+ ---------
129
+
130
+ Copyright (c) 2009 Scott Fleckenstein and Tom Preston-Werner. See LICENSE for details.
@@ -0,0 +1,44 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ require "rake/testtask"
4
+
5
+ desc "Default: run unit tests."
6
+ task default: :test
7
+
8
+ desc "Test the beambridge plugin."
9
+ task :test do
10
+ require 'open3'
11
+ require 'fileutils'
12
+
13
+ puts "\nCleaning extension build files and running all specs in native ruby mode..."
14
+ `rm -f ext/*.bundle` && puts("rm -f ext/*.bundle")
15
+ `rm -f ext/*.o` && puts("rm -f ext/*.o")
16
+ Open3.popen3("ruby test/spec_suite.rb") do |stdin, stdout, stderr|
17
+ while !stdout.eof?
18
+ print stdout.read(1)
19
+ end
20
+ end
21
+
22
+ puts "\nRunning `make` to build extensions and rerunning decoder specs..."
23
+ Dir.chdir('ext') { `ruby extconf.rb` }
24
+ Dir.chdir('ext') { `make` }
25
+ Open3.popen3("ruby test/decode_spec.rb") do |stdin, stdout, stderr|
26
+ while !stdout.eof?
27
+ print stdout.read(1)
28
+ end
29
+ end
30
+ end
31
+
32
+ begin
33
+ require "rdoc/task"
34
+ desc "Generate documentation for the beambridge plugin."
35
+ RDoc::Task.new(:rdoc) do |rdoc|
36
+ rdoc.rdoc_dir = "rdoc"
37
+ rdoc.title = "Beambridge"
38
+ rdoc.options << "--line-numbers"
39
+ rdoc.rdoc_files.include("README*")
40
+ rdoc.rdoc_files.include("lib/**/*.rb")
41
+ end
42
+ rescue LoadError
43
+ puts "RDoc::Task is not supported on this platform"
44
+ end
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 1
3
+ :patch: 1
4
+ :major: 1
@@ -0,0 +1,29 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "beambridge/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "beambridge"
8
+ spec.version = Beambridge::VERSION
9
+ spec.authors = ["Scott Fleckenstein", "Tom Preston-Werner"]
10
+ spec.email = ["mathieul@gmail.com"]
11
+ spec.description = %q{Asset pipeline CLI to be executed from a different language.}
12
+ spec.summary = %q{A command to pre-process web assets using Ruby tools, intended to be called from a different language.}
13
+ spec.homepage = "https://github.com/mathieul/beambridge"
14
+ spec.license = "Scott Fleckenstein and Tom Preston-Werner"
15
+
16
+ # spec.required_ruby_version = "~> 1.9.3"
17
+
18
+ spec.files = `git ls-files`.split($/)
19
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
20
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
21
+ spec.require_paths = ["lib"]
22
+ spec.extensions = ["ext/extconf.rb"]
23
+
24
+ spec.extra_rdoc_files = ["LICENSE", "README.md"]
25
+
26
+ spec.add_development_dependency "rake"
27
+ spec.add_development_dependency "rspec"
28
+ spec.add_development_dependency "pry-nav"
29
+ end
@@ -0,0 +1,21 @@
1
+ $:.unshift(File.dirname(__FILE__) + '/../lib')
2
+
3
+ require 'beambridge'
4
+ require 'benchmark'
5
+
6
+ data = [:ok, [:foo, :bar, [99, "bottles", "of", "beer", 3.14], [true, false]]]
7
+ bert = Beambridge::Encoder.encode(data)
8
+
9
+ p bert
10
+
11
+ Benchmark.bm do|b|
12
+ b.report("Decoder") do
13
+ 100_000.times { Erl::Decoder.decode(bert) }
14
+ end
15
+ end
16
+
17
+ # user system total real
18
+ # C Decoder 0.400000 0.000000 0.400000 ( 0.425373)
19
+ # Ruby Decoder 30.250000 0.220000 30.470000 ( 32.140890)
20
+ #
21
+ # C decoder is 75.56x faster than Ruby decoder on this data
@@ -0,0 +1,12 @@
1
+ This is a simple echo server example showing off basic Erlectricity usage.
2
+
3
+ $ cd examples/echo
4
+ $ erl
5
+ Erlang (BEAM) emulator version 5.6.4 [source] [smp:2] [async-threads:0] [kernel-poll:false]
6
+
7
+ Eshell V5.6.4 (abort with ^G)
8
+ 1> c(echo).
9
+ {ok,echo}
10
+ 2> echo:test().
11
+ <<"You said: hello world!">>
12
+ ok
@@ -0,0 +1,13 @@
1
+ -module(echo).
2
+ -export([test/0]).
3
+
4
+ test() ->
5
+ Cmd = "ruby echo.rb",
6
+ Port = open_port({spawn, Cmd}, [{packet, 4}, nouse_stdio, exit_status, binary]),
7
+ Payload = term_to_binary({echo, <<"hello world!">>}),
8
+ port_command(Port, Payload),
9
+ receive
10
+ {Port, {data, Data}} ->
11
+ {result, Text} = binary_to_term(Data),
12
+ io:format("~p~n", [Text])
13
+ end.
@@ -0,0 +1,10 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[../../lib])
2
+
3
+ require 'beambridge'
4
+
5
+ receive do |f|
6
+ f.when([:echo, String]) do |text|
7
+ f.send!([:result, "You said: #{text}"])
8
+ f.receive_loop
9
+ end
10
+ end
@@ -0,0 +1,61 @@
1
+ -module(gruff).
2
+ -export([start/0, stop/0, plot/4]).
3
+
4
+ start() ->
5
+ spawn(fun() ->
6
+ register(gruff, self()),
7
+ process_flag(trap_exit, true),
8
+ Cmd = "ruby ./gruff_provider.rb",
9
+ Port = open_port({spawn, Cmd}, [{packet, 4}, nouse_stdio, exit_status, binary]),
10
+ port_loop(Port)
11
+ end).
12
+
13
+ stop() -> gruff ! stop.
14
+
15
+ plot(Name, Font, Data, Labels) ->
16
+ gruff ! {plot, self(), Name, Font, Data, Labels},
17
+ receive
18
+ {result, Bin} -> Bin
19
+ end.
20
+
21
+ send_data(_Port, []) -> ok;
22
+ send_data(Port, [{Name, Points}|Rest]) ->
23
+ Data = {data, Name, Points},
24
+ Port ! {self(), {command, term_to_binary(Data)}},
25
+ send_data(Port, Rest).
26
+
27
+ send_labels(Port, Labels) ->
28
+ Data = {labels, Labels},
29
+ Port ! {self(), {command, term_to_binary(Data)}}.
30
+
31
+ port_loop(Port) ->
32
+ receive
33
+ {plot, Caller, Name, Font, Data, Labels} ->
34
+ PlotData = term_to_binary({plot, Name, 'Line', Font}),
35
+ Port ! {self(), {command, PlotData}},
36
+
37
+ send_data(Port, Data),
38
+ send_labels(Port, Labels),
39
+
40
+ EndData = term_to_binary('end'),
41
+ Port ! {self(), {command, EndData}},
42
+ Result = get_result(Port),
43
+ Caller ! {result, Result },
44
+
45
+ port_loop(Port);
46
+
47
+ stop ->
48
+ Port ! {self(), close},
49
+ receive
50
+ {Port, closed} -> exit(normal)
51
+ end
52
+ end.
53
+
54
+ get_result(Port) ->
55
+ receive
56
+ {Port, {data, Data}} ->
57
+ {result, Bin} = binary_to_term(Data),
58
+ Bin;
59
+ {'EXIT', Port, Reason} ->
60
+ exit({port_terminated,Reason})
61
+ end.
@@ -0,0 +1,30 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[../../lib])
2
+
3
+ require 'beambridge'
4
+ require 'gruff'
5
+
6
+ receive do |f|
7
+ f.when([:plot, String, Symbol, String]) do |name, style, font|
8
+ graph = Gruff.const_get(style).new
9
+ graph.title = name
10
+ graph.font = font
11
+ graph.legend_font_size = 10
12
+
13
+ f.receive do |g|
14
+ g.when([:data, Symbol, Array]) do |name, points|
15
+ graph.data name, points
16
+ g.receive_loop
17
+ end
18
+
19
+ g.when([:labels, Erl.hash]) do |label_data|
20
+ graph.labels = label_data
21
+ g.receive_loop
22
+ end
23
+
24
+ g.when(:end) { :ok }
25
+ end
26
+
27
+ f.send!([:result, graph.to_blob])
28
+ f.receive_loop
29
+ end
30
+ end