posix-mqueue 0.0.1 → 0.0.2
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.
- 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