intruder 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +120 -10
- data/src/term.c +1 -1
- data/src/tuple.c +9 -3
- 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
|
-
|
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
|
-
|
111
|
+
Run an example?
|
10
112
|
============
|
11
113
|
|
12
|
-
the test script makes an rpc call to a rabbitmq server and queries for
|
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
|
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
|
-
|
49
|
-
|
153
|
+
But your C code sucks big time!
|
154
|
+
====================
|
50
155
|
|
51
|
-
|
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
|
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
|
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
|
-
|
45
|
-
|
46
|
-
|
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
|
-
-
|
9
|
-
version: 0.2.
|
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 +
|
17
|
+
date: 2010-03-11 00:00:00 +01:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|