posix-mqueue 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/README.md +28 -2
- data/Rakefile +6 -0
- data/ext/{extconf.rb → posix/extconf.rb} +1 -1
- data/ext/{mqueue.c → posix/mqueue.c} +45 -24
- data/lib/posix/mqueue/version.rb +1 -1
- data/posix-mqueue.gemspec +2 -2
- data/test/mqueue_test.rb +55 -0
- data/test/test_helper.rb +1 -1
- metadata +7 -7
- data/lib/posix/mqueue.rb +0 -6
- data/test/test_mqueue.rb +0 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4684343b93a70e5ade31414a548044a4bdd67180
|
4
|
+
data.tar.gz: 03463a0abb8c142b7832812a04915e98ddfdc825
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4996b7a36d757fc0f47961309a6b804c927de5ead7ff204914153f69e70a409f5e0a4d81761ac4d605b27182ccea259a6f71c6cfcdbf22237e22bb602ec0e371
|
7
|
+
data.tar.gz: 2083fe220f4b7e3e9ba22a8a9f42a965546d0f8e2bc2f26ef500ca5d409980e1766775dc136ccd8079481e6c41649ccbe8e87fd03bb999c458bba46a71ca3bb8
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,5 +1,31 @@
|
|
1
|
-
#
|
1
|
+
# posix-mqueue
|
2
2
|
|
3
|
-
Minimal wrapper around the [POSIX message queue](pmq).
|
3
|
+
Minimal wrapper around the [POSIX message queue](pmq). The POSIX message queue
|
4
|
+
offers:
|
5
|
+
|
6
|
+
* Persistence. Push messages while nothing is listening.
|
7
|
+
* Simplicity. Nothing to set up. Built into Linux.
|
8
|
+
* IPC. Blazingly fast communication between processes on the same machine.
|
9
|
+
* Blocking and non-blocking. Listeners block until a message arrives on the
|
10
|
+
queue. No polling. Sending messages doesn't block.
|
11
|
+
|
12
|
+
Add `gem 'posix-mqueue'` to your favorite Gemfile.
|
13
|
+
|
14
|
+
Still WIP. Not stable. Not everything works as promised.
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
```ruby
|
19
|
+
m = POSIX::Mqueue.new("/whatever")
|
20
|
+
m.send "hello"
|
21
|
+
puts m.receive
|
22
|
+
# => "hello"
|
23
|
+
|
24
|
+
fork { POSIX::Mqueue.new("/whatever").send("world") }
|
25
|
+
|
26
|
+
# Blocks until the forked process pushes to the queue
|
27
|
+
m.receive
|
28
|
+
# => "world"
|
29
|
+
```
|
4
30
|
|
5
31
|
[pmq]: http://man7.org/linux/man-pages/man7/mq_overview.7.html
|
data/Rakefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
#include <ruby.h>
|
2
|
+
#include <ruby/util.h>
|
2
3
|
|
3
4
|
#include <mqueue.h>
|
4
5
|
#include <fcntl.h>
|
@@ -7,20 +8,11 @@
|
|
7
8
|
#include <stdlib.h>
|
8
9
|
#include <stdio.h>
|
9
10
|
|
10
|
-
mqd_t
|
11
|
-
rb_mqueue_fd(const char *queue, const struct mq_attr *attr) {
|
12
|
-
mqd_t fd = mq_open("/mqueue", O_CREAT | O_RDWR, S_IRWXU | S_IRWXO | S_IRWXG, attr);
|
13
|
-
|
14
|
-
if (fd == (mqd_t)-1) {
|
15
|
-
rb_sys_fail("fak rubby");
|
16
|
-
}
|
17
|
-
|
18
|
-
return fd;
|
19
|
-
}
|
20
|
-
|
21
11
|
typedef struct {
|
22
12
|
mqd_t fd;
|
23
13
|
struct mq_attr attr;
|
14
|
+
size_t queue_len;
|
15
|
+
char *queue;
|
24
16
|
}
|
25
17
|
mqueue_t;
|
26
18
|
|
@@ -35,13 +27,15 @@ mqueue_free(void* ptr)
|
|
35
27
|
{
|
36
28
|
mqueue_t* data = ptr;
|
37
29
|
mq_close(data->fd);
|
30
|
+
xfree(data->queue);
|
38
31
|
xfree(ptr);
|
39
32
|
}
|
40
33
|
|
41
34
|
static size_t
|
42
35
|
mqueue_memsize(const void* ptr)
|
43
36
|
{
|
44
|
-
|
37
|
+
const mqueue_t* data = ptr;
|
38
|
+
return sizeof(mqueue_t) + sizeof(char) * data->queue_len;
|
45
39
|
}
|
46
40
|
|
47
41
|
static const rb_data_type_t
|
@@ -58,7 +52,26 @@ static VALUE
|
|
58
52
|
posix_mqueue_alloc(VALUE klass)
|
59
53
|
{
|
60
54
|
mqueue_t* data;
|
61
|
-
|
55
|
+
VALUE obj = TypedData_Make_Struct(klass, mqueue_t, &mqueue_type, data);
|
56
|
+
|
57
|
+
data->fd = -1;
|
58
|
+
data->queue = NULL;
|
59
|
+
data->queue_len = 0;
|
60
|
+
|
61
|
+
return obj;
|
62
|
+
}
|
63
|
+
|
64
|
+
VALUE posix_mqueue_unlink(VALUE self)
|
65
|
+
{
|
66
|
+
mqueue_t* data;
|
67
|
+
|
68
|
+
TypedData_Get_Struct(self, mqueue_t, &mqueue_type, data);
|
69
|
+
|
70
|
+
if (mq_unlink(data->queue) == -1) {
|
71
|
+
rb_sys_fail("Message queue unlinking failed");
|
72
|
+
}
|
73
|
+
|
74
|
+
return Qtrue;
|
62
75
|
}
|
63
76
|
|
64
77
|
VALUE posix_mqueue_send(VALUE self, VALUE message)
|
@@ -69,15 +82,14 @@ VALUE posix_mqueue_send(VALUE self, VALUE message)
|
|
69
82
|
TypedData_Get_Struct(self, mqueue_t, &mqueue_type, data);
|
70
83
|
|
71
84
|
if (!RB_TYPE_P(message, T_STRING)) {
|
72
|
-
rb_raise(rb_eTypeError, "
|
85
|
+
rb_raise(rb_eTypeError, "Message must be a string");
|
73
86
|
}
|
74
87
|
|
75
|
-
// FIXME: is rstring_len with or without \0?
|
76
88
|
// TODO: Custom priority
|
77
89
|
err = mq_send(data->fd, RSTRING_PTR(message), RSTRING_LEN(message), 10);
|
78
90
|
|
79
91
|
if (err < 0) {
|
80
|
-
rb_sys_fail("
|
92
|
+
rb_sys_fail("Message sending failed");
|
81
93
|
}
|
82
94
|
|
83
95
|
return Qtrue;
|
@@ -103,7 +115,7 @@ VALUE posix_mqueue_receive(VALUE self)
|
|
103
115
|
err = mq_receive(data->fd, buf, buf_size, NULL);
|
104
116
|
|
105
117
|
if (err < 0) {
|
106
|
-
rb_sys_fail("
|
118
|
+
rb_sys_fail("Message retrieval failed");
|
107
119
|
}
|
108
120
|
|
109
121
|
str = rb_str_new(buf, err);
|
@@ -117,20 +129,28 @@ VALUE posix_mqueue_initialize(VALUE self, VALUE queue)
|
|
117
129
|
// TODO: Modify these options from initialize arguments
|
118
130
|
// TODO: Set nonblock and handle error in #push
|
119
131
|
struct mq_attr attr = {
|
120
|
-
.mq_flags = 0,
|
121
|
-
.mq_maxmsg =
|
122
|
-
.mq_msgsize = 512,
|
123
|
-
.mq_curmsgs = 0
|
132
|
+
.mq_flags = 0, // Flags, 0 or O_NONBLOCK
|
133
|
+
.mq_maxmsg = 10, // Max messages in queue
|
134
|
+
.mq_msgsize = 512, // Max message size (bytes)
|
135
|
+
.mq_curmsgs = 0 // # currently in queue
|
124
136
|
};
|
125
137
|
|
126
138
|
mqueue_t* data;
|
127
139
|
TypedData_Get_Struct(self, mqueue_t, &mqueue_type, data);
|
128
140
|
|
141
|
+
if (data->fd != -1) {
|
142
|
+
// This would cause a memleak otherwise
|
143
|
+
rb_raise(rb_eRuntimeError, "Illegal reinitialization");
|
144
|
+
}
|
145
|
+
|
129
146
|
data->attr = attr;
|
147
|
+
data->queue_len = RSTRING_LEN(queue);
|
148
|
+
data->queue = ruby_strdup(StringValueCStr(queue));
|
149
|
+
data->fd = mq_open(data->queue, O_CREAT | O_RDWR, S_IRWXU | S_IRWXO | S_IRWXG, &data->attr);
|
130
150
|
|
131
|
-
|
132
|
-
|
133
|
-
|
151
|
+
if (data->fd == (mqd_t)-1) {
|
152
|
+
rb_sys_fail("Failed opening the message queue");
|
153
|
+
}
|
134
154
|
|
135
155
|
return self;
|
136
156
|
}
|
@@ -143,5 +163,6 @@ void Init_mqueue()
|
|
143
163
|
rb_define_method(mqueue, "initialize", posix_mqueue_initialize, 1);
|
144
164
|
rb_define_method(mqueue, "send", posix_mqueue_send, 1);
|
145
165
|
rb_define_method(mqueue, "receive", posix_mqueue_receive, 0);
|
166
|
+
rb_define_method(mqueue, "unlink", posix_mqueue_unlink, 0);
|
146
167
|
}
|
147
168
|
|
data/lib/posix/mqueue/version.rb
CHANGED
data/posix-mqueue.gemspec
CHANGED
@@ -16,8 +16,8 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.files = `git ls-files`.split($/)
|
17
17
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
-
spec.require_paths = ["lib"]
|
20
|
-
spec.extensions = ["ext/extconf.rb"]
|
19
|
+
spec.require_paths = ["lib", "ext"]
|
20
|
+
spec.extensions = ["ext/posix/extconf.rb"]
|
21
21
|
|
22
22
|
spec.add_development_dependency "bundler", "~> 1.3"
|
23
23
|
spec.add_development_dependency "rake"
|
data/test/mqueue_test.rb
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class MqueueTest < MiniTest::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@queue_name = "/test-queue"
|
6
|
+
@queue = POSIX::Mqueue.new(@queue_name)
|
7
|
+
end
|
8
|
+
|
9
|
+
def teardown
|
10
|
+
@queue.unlink
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_send_and_receive_single_message
|
14
|
+
@queue.send "hello"
|
15
|
+
assert_equal "hello", @queue.receive
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_send_and_receive_multiple_messages
|
19
|
+
@queue.send "hello"
|
20
|
+
@queue.send "world"
|
21
|
+
|
22
|
+
assert_equal "hello", @queue.receive
|
23
|
+
assert_equal "world", @queue.receive
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_receiver_blocks
|
27
|
+
@queue.send "hello"
|
28
|
+
|
29
|
+
assert_equal "hello", @queue.receive
|
30
|
+
|
31
|
+
fork { POSIX::Mqueue.new(@queue_name).send("world") }
|
32
|
+
|
33
|
+
assert_equal "world", @queue.receive
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_multiple_queues
|
37
|
+
@queue.send "hello"
|
38
|
+
|
39
|
+
other = POSIX::Mqueue.new("/other-test-queue")
|
40
|
+
other.send "world"
|
41
|
+
|
42
|
+
assert_equal "world", other.receive
|
43
|
+
assert_equal "hello", @queue.receive
|
44
|
+
|
45
|
+
other.unlink
|
46
|
+
end
|
47
|
+
|
48
|
+
# def test_send_raises_exception_instead_of_blocking
|
49
|
+
# 10.times { @queue.send "walrus" }
|
50
|
+
|
51
|
+
# assert_raises Exception do
|
52
|
+
# @queue.send "hi"
|
53
|
+
# end
|
54
|
+
# end
|
55
|
+
end
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: posix-mqueue
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Simon Eskildsen
|
@@ -43,7 +43,7 @@ email:
|
|
43
43
|
- sirup@sirupsen.com
|
44
44
|
executables: []
|
45
45
|
extensions:
|
46
|
-
- ext/extconf.rb
|
46
|
+
- ext/posix/extconf.rb
|
47
47
|
extra_rdoc_files: []
|
48
48
|
files:
|
49
49
|
- .gitignore
|
@@ -51,13 +51,12 @@ files:
|
|
51
51
|
- LICENSE.txt
|
52
52
|
- README.md
|
53
53
|
- Rakefile
|
54
|
-
- ext/extconf.rb
|
55
|
-
- ext/mqueue.c
|
56
|
-
- lib/posix/mqueue.rb
|
54
|
+
- ext/posix/extconf.rb
|
55
|
+
- ext/posix/mqueue.c
|
57
56
|
- lib/posix/mqueue/version.rb
|
58
57
|
- posix-mqueue.gemspec
|
58
|
+
- test/mqueue_test.rb
|
59
59
|
- test/test_helper.rb
|
60
|
-
- test/test_mqueue.rb
|
61
60
|
homepage: ''
|
62
61
|
licenses:
|
63
62
|
- MIT
|
@@ -66,6 +65,7 @@ post_install_message:
|
|
66
65
|
rdoc_options: []
|
67
66
|
require_paths:
|
68
67
|
- lib
|
68
|
+
- ext
|
69
69
|
required_ruby_version: !ruby/object:Gem::Requirement
|
70
70
|
requirements:
|
71
71
|
- - '>='
|
@@ -83,5 +83,5 @@ signing_key:
|
|
83
83
|
specification_version: 4
|
84
84
|
summary: posix-mqueue is a simple wrapper around the mqueue(7). It only works on Linux.
|
85
85
|
test_files:
|
86
|
+
- test/mqueue_test.rb
|
86
87
|
- test/test_helper.rb
|
87
|
-
- test/test_mqueue.rb
|
data/lib/posix/mqueue.rb
DELETED