intruder 0.2.0 → 0.2.1

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 (4) hide show
  1. data/README.md +120 -10
  2. data/src/term.c +1 -1
  3. data/src/tuple.c +9 -3
  4. metadata +3 -3
data/README.md CHANGED
@@ -1,15 +1,119 @@
1
- **A little WIP again**
2
-
3
1
  What is it?
4
2
  ===========
5
3
 
6
4
  A ruby library with a C extension to interact with erlang processes.
7
- At the moment it's my fun project to get my feet wet with C. Stay tuned :)
5
+ There's not much more than the ability to connect a node to a erlang
6
+ process and then run some rpc calls.
7
+
8
+ Want to use it?
9
+ ==========
10
+
11
+ install it from gemcutter with `gem install intruder --source
12
+ http://gemcutter.org`.
13
+
14
+ Still interested?
15
+ ==========
16
+
17
+ Glad you asked...
18
+ First of all you need a node. A node is more or less your
19
+ representative in the erlang world. You need to give it a name and it
20
+ needs a cookie which basically manages your access rights.
21
+ So for example if you wan't to communicate with a RabbitMQ process,
22
+ you need to use the same magic cookie value as your RabbitMQ server
23
+ does. Usually the erlang cookie is stored in the home directory in a
24
+ hidden file called .erlang.cookie. Sometimes it can also be found in the
25
+ application directory of your erlang application. Whatever...
26
+
27
+ Let's try to get our feet wet and write a simple little echofunction
28
+ in erlang. Here's the content of the file echo.erl:
29
+
30
+ -module(echo).
31
+ -export([say/1]).
32
+
33
+ say(Any) ->
34
+ {ok, Any}.
35
+
36
+ Thats pretty basic stuff here. What we have here is a module called
37
+ "echo" with a function called "say" that just returns a tuple of ok plus whatever arguments it was
38
+ called with. Now open your erlang shell with `erl -sname funkyzeit`
39
+ in the same directory as your echo.erl file is located and type
40
+ `c(echo).` (including the dot) into the console. Now you have a node
41
+ named "funkyzeit" running which knows about a module called "echo".
42
+
43
+ But back to ruby. Open another console and fire up irb:
44
+
45
+ First we wan't to create the node (assuming that the .erlang.cookie
46
+ file is located at '~/.erlang.cookie').
47
+
48
+ require 'rubygems'
49
+ require 'intruder'
50
+ node = Intruder::Node.new('my_node', File.read(File.expand_path('~/.erlang.cookie')))
51
+
52
+ Great! Now connect that thing to the other erlang node we fired up
53
+ earlier (replace <myhost> with your actual hostname.... skip the
54
+ .local if you are a mac user).
55
+
56
+ node.connect('funkyzeit@myhost')
57
+
58
+ You should be connected to the other node now. Let's create the
59
+ arguments we gonna pass to the echo module now.
60
+
61
+ args = Intruder::Term.encode([[:a, :b, :c]])
62
+
63
+ Intruder::Term.encode is able to create Intruder Terms like lists,
64
+ atoms, and "strings" if you pass them in as arrays, atoms or strings
65
+ (or combinations of them). If you need a tuple or a binary you need to
66
+ create them with `Intruder::Binary.new("mybinaryvalue")` or
67
+ `Intruder::Tuple.new([:a, :b])` for now. Maybe I'll come up with a
68
+ cleverer solution for that later... Lets call the "say" method on the
69
+ "echo" module now. Therefore we create a proxy object for the erlang
70
+ module and let some super simple method missing magic call the
71
+ function on that proxy.
72
+
73
+ echo = node.mod('echo')
74
+ response = echo.say(args)
75
+
76
+ The response should be a tuple containing the atom 'ok' and our list
77
+ of atoms we created with the Term.encode function earlier. Let's
78
+ confirm that:
79
+
80
+ response
81
+ => {ok, [a, b]}
82
+ p response.class
83
+ => Intruder::Tuple
84
+ response[0].to_s
85
+ => "ok"
86
+ p response[1].class
87
+ => Intruder::List
88
+ p response[1][0]
89
+ => a
90
+
91
+ I hope that explains enough to get the idea...
92
+
93
+ Issues
94
+ ====
95
+
96
+ Well the obvious one is the lack of functionality. For my purpose,
97
+ being able to run rpc calls could already be enough, but there are way
98
+ more things to add that are expsed via the erl_interface / ei C
99
+ libraries.
100
+
101
+ Test coverage is... well, let's not talk about that.
102
+
103
+ Keeping nodes alive requires to constantly reply to ERL_TICK messages
104
+ that might be send by the remote node. To handle that I'm currently
105
+ using a "keep_alive" POSIX thread and mutexes and stuff. That's just
106
+ because I'm a bloody noob at those kind of things (frankly, they scare
107
+ me!). That might (hopefully) change soon.
108
+
109
+ .. insert more issues here ...
8
110
 
9
- Want to try?
111
+ Run an example?
10
112
  ============
11
113
 
12
- the test script makes an rpc call to a rabbitmq server and queries for its status.
114
+ the test script makes an rpc call to a rabbitmq server and queries for
115
+ its status (Note: the example assumes that you are running it from
116
+ within a checked out and compiled version).
13
117
 
14
118
  * checkout the source
15
119
  * `ruby extconf.rb`
@@ -43,14 +147,20 @@ the script should print something similar to this:
43
147
  Why that?
44
148
  =========
45
149
 
46
- because thats a fun project to learn c and I need it for another project of mine (namely: paukul/humpty)
150
+ because thats a fun project to learn c and I need it for humpty,
151
+ another project of mine (find it on github as well).
47
152
 
48
- What works already?
49
- ===================
153
+ But your C code sucks big time!
154
+ ====================
50
155
 
51
- description missing... yet :)
156
+ I know, I'm a C-n00b. Wan't to improve it? Contribute? Ah, Not
157
+ interested? ok then stfu :)
52
158
 
53
159
  Erlix?
54
160
  ======
55
161
 
56
- is great, I also took some stuff from them. Afaik, Erlix uses erl_interface for most of its operations. erl_interface is limited to one connection only, I needed something to open multiple connections to multiple queues. Erlix is able to do a LOT more than Intruder at the moment, make sure to check it out as well!
162
+ is great, I also took some stuff from them. Afaik, Erlix uses
163
+ erl_interface for most of its operations. erl_interface is limited to
164
+ one connection only, I needed something to open multiple connections
165
+ to multiple queues. If thats fine for you, Erlix is able to do a LOT
166
+ more than Intruder at the moment, make sure to check it out as well!
data/src/term.c CHANGED
@@ -77,7 +77,7 @@ VALUE rb_value_from_binary(INTRUDER_TERM *iterm) {
77
77
  VALUE rValue;
78
78
  iterm->type = INTRUDER_TYPE_BINARY;
79
79
  rValue = Data_Wrap_Struct(IntruderBinary, 0, free_intruder_term, iterm);
80
- return Qnil;
80
+ return rValue;
81
81
  }
82
82
 
83
83
  static ETERM *intruder_eterm_from_array(VALUE obj);
data/src/tuple.c CHANGED
@@ -39,11 +39,17 @@ VALUE intruder_tuple_init(VALUE self, VALUE arr) {
39
39
 
40
40
  VALUE intruder_tuple_member_at(VALUE self, VALUE position) {
41
41
  INTRUDER_TERM *iterm;
42
+ Data_Get_Struct(self, INTRUDER_TERM, iterm);
43
+
42
44
  ETERM *member;
43
45
  int iPosition = NUM2INT(position);
44
- Data_Get_Struct(self, INTRUDER_TERM, iterm);
45
- member = erl_element(iPosition+1, iterm->eterm);
46
- return rb_value_from_eterm(member);
46
+ int tuple_size = erl_size(iterm->eterm);
47
+ if (iPosition < 0 || tuple_size < iPosition+1) {
48
+ return Qnil;
49
+ } else {
50
+ member = erl_element(iPosition+1, iterm->eterm);
51
+ return rb_value_from_eterm(member);
52
+ }
47
53
  }
48
54
 
49
55
  VALUE intruder_tuple_length(VALUE self) {
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 0
9
- version: 0.2.0
8
+ - 1
9
+ version: 0.2.1
10
10
  platform: ruby
11
11
  authors:
12
12
  - Pascal Friederich
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-03-11 00:00:00 +00:00
17
+ date: 2010-03-11 00:00:00 +01:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency