ilios 0.3.2 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -14
- data/ext/ilios/cluster.c +250 -0
- data/ext/ilios/future.c +3 -0
- data/ext/ilios/ilios.c +5 -17
- data/ext/ilios/ilios.h +14 -12
- data/ext/ilios/session.c +17 -5
- data/ext/ilios/statement.c +1 -5
- data/lib/ilios/version.rb +1 -1
- data/lib/ilios.rb +0 -36
- data/sig/ilios.rbs +10 -3
- metadata +4 -4
- data/ext/ilios/cassandra.c +0 -64
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eb732bdcf04d5150f8294a8338ee88f0cb25b45fa103262fa609c66d7ab3bcd4
|
4
|
+
data.tar.gz: 6d9806c6187c7bff25edfa9ca7bba20da49a55f08caa65a6306fb3a0b9255b81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c55c0599ca523bf7bf9864ac9e7f34d1dbfb65bbaea0beba6fe9bfaff23a5e2cd288659fe531652a795e6cf913a1575e5a4645dcf0e3635352bbf2ca0c82acaa
|
7
|
+
data.tar.gz: 2f9c1ef1d6d5fce24903cde814ffb652f84fe922c792459f10d981a03767376697bde1e20401e3843e1b7efb7e8f51c9f3ff372e4bb21c85338487dd2d73d035
|
data/README.md
CHANGED
@@ -58,13 +58,13 @@ Then, you can run the following code.
|
|
58
58
|
```ruby
|
59
59
|
require 'ilios'
|
60
60
|
|
61
|
-
Ilios::Cassandra.
|
62
|
-
|
63
|
-
|
64
|
-
|
61
|
+
cluster = Ilios::Cassandra::Cluster.new
|
62
|
+
cluster.keyspace('ilios')
|
63
|
+
cluster.hosts(['127.0.0.1'])
|
64
|
+
session = cluster.connect
|
65
65
|
|
66
66
|
# Create the table
|
67
|
-
statement =
|
67
|
+
statement = session.prepare(<<~CQL)
|
68
68
|
CREATE TABLE IF NOT EXISTS ilios.example (
|
69
69
|
id bigint,
|
70
70
|
message text,
|
@@ -73,10 +73,10 @@ statement = Ilios::Cassandra.session.prepare(<<~CQL)
|
|
73
73
|
) WITH compaction = { 'class' : 'LeveledCompactionStrategy' }
|
74
74
|
AND gc_grace_seconds = 691200;
|
75
75
|
CQL
|
76
|
-
|
76
|
+
session.execute(statement)
|
77
77
|
|
78
78
|
# Insert the records
|
79
|
-
statement =
|
79
|
+
statement = session.prepare(<<~CQL)
|
80
80
|
INSERT INTO ilios.example (
|
81
81
|
id,
|
82
82
|
message,
|
@@ -90,16 +90,16 @@ CQL
|
|
90
90
|
message: 'Hello World',
|
91
91
|
created_at: Time.now,
|
92
92
|
})
|
93
|
-
|
93
|
+
session.execute(statement)
|
94
94
|
end
|
95
95
|
|
96
96
|
# Select the records
|
97
|
-
statement =
|
97
|
+
statement = session.prepare(<<~CQL)
|
98
98
|
SELECT * FROM ilios.example
|
99
99
|
CQL
|
100
100
|
statement.idempotent = true
|
101
101
|
statement.page_size = 25
|
102
|
-
result =
|
102
|
+
result = session.execute(statement)
|
103
103
|
result.each do |row|
|
104
104
|
p row
|
105
105
|
end
|
@@ -115,17 +115,17 @@ end
|
|
115
115
|
`Ilios::Cassandra::Session#prepare` and `Ilios::Cassandra::Session#execute` are provided as synchronous API.
|
116
116
|
|
117
117
|
```ruby
|
118
|
-
statement =
|
118
|
+
statement = session.prepare(<<~CQL)
|
119
119
|
SELECT * FROM ilios.example
|
120
120
|
CQL
|
121
|
-
result =
|
121
|
+
result = session.execute(statement)
|
122
122
|
```
|
123
123
|
|
124
124
|
### Asynchronous API
|
125
125
|
`Ilios::Cassandra::Session#prepare_async` and `Ilios::Cassandra::Session#execute_async` are provided as asynchronous API.
|
126
126
|
|
127
127
|
```ruby
|
128
|
-
prepare_future =
|
128
|
+
prepare_future = session.prepare_async(<<~CQL)
|
129
129
|
INSERT INTO ilios.example (
|
130
130
|
id,
|
131
131
|
message,
|
@@ -142,7 +142,7 @@ prepare_future.on_success { |statement|
|
|
142
142
|
message: 'Hello World',
|
143
143
|
created_at: Time.now,
|
144
144
|
})
|
145
|
-
result_future =
|
145
|
+
result_future = session.execute_async(statement)
|
146
146
|
result_future.on_success { |result|
|
147
147
|
p result
|
148
148
|
p "success"
|
data/ext/ilios/cluster.c
ADDED
@@ -0,0 +1,250 @@
|
|
1
|
+
#include "ilios.h"
|
2
|
+
|
3
|
+
static void cluster_mark(void *ptr);
|
4
|
+
static void cluster_destroy(void *ptr);
|
5
|
+
static size_t cluster_memsize(const void *ptr);
|
6
|
+
static void cluster_compact(void *ptr);
|
7
|
+
|
8
|
+
const rb_data_type_t cassandra_cluster_data_type = {
|
9
|
+
"Ilios::Cassandra::Cluster",
|
10
|
+
{
|
11
|
+
cluster_mark,
|
12
|
+
cluster_destroy,
|
13
|
+
cluster_memsize,
|
14
|
+
cluster_compact,
|
15
|
+
},
|
16
|
+
0, 0,
|
17
|
+
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
|
18
|
+
};
|
19
|
+
|
20
|
+
static VALUE cluster_allocator(VALUE klass)
|
21
|
+
{
|
22
|
+
CassandraCluster *cassandra_cluster;
|
23
|
+
return CREATE_CLUSTER(cassandra_cluster);
|
24
|
+
}
|
25
|
+
|
26
|
+
/**
|
27
|
+
* Creates a new cluster.
|
28
|
+
*
|
29
|
+
* @return [Cassandra::Cluster] A new cluster.
|
30
|
+
*/
|
31
|
+
static VALUE cluster_initialize(VALUE self)
|
32
|
+
{
|
33
|
+
CassandraCluster *cassandra_cluster;
|
34
|
+
|
35
|
+
GET_CLUSTER(self, cassandra_cluster);
|
36
|
+
cassandra_cluster->cluster = cass_cluster_new();
|
37
|
+
|
38
|
+
return self;
|
39
|
+
}
|
40
|
+
|
41
|
+
/**
|
42
|
+
* Connects a session.
|
43
|
+
*
|
44
|
+
* @return [Cassandra::Session] A new session object.
|
45
|
+
* @raise [RuntimeError] If no host is specified to connect in +config+ method.
|
46
|
+
* @raise [Cassandra::ConnectError] If the connection fails for any reason.
|
47
|
+
*/
|
48
|
+
static VALUE cluster_connect(VALUE self)
|
49
|
+
{
|
50
|
+
CassandraSession *cassandra_session;
|
51
|
+
CassandraCluster *cassandra_cluster;
|
52
|
+
VALUE cassandra_session_obj;
|
53
|
+
const char *keyspace = "";
|
54
|
+
|
55
|
+
GET_CLUSTER(self, cassandra_cluster);
|
56
|
+
if (cassandra_cluster->keyspace) {
|
57
|
+
keyspace = StringValueCStr(cassandra_cluster->keyspace);
|
58
|
+
}
|
59
|
+
|
60
|
+
cassandra_session_obj = CREATE_SESSION(cassandra_session);
|
61
|
+
cassandra_session->cluster_obj = self;
|
62
|
+
cassandra_session->session = cass_session_new();
|
63
|
+
cassandra_session->connect_future = cass_session_connect_keyspace(cassandra_session->session, cassandra_cluster->cluster, keyspace);
|
64
|
+
nogvl_future_wait(cassandra_session->connect_future);
|
65
|
+
|
66
|
+
if (cass_future_error_code(cassandra_session->connect_future) != CASS_OK) {
|
67
|
+
char error[4096] = { 0 };
|
68
|
+
|
69
|
+
strncpy(error, cass_error_desc(cass_future_error_code(cassandra_session->connect_future)), sizeof(error) - 1);
|
70
|
+
rb_raise(eConnectError, "Unable to connect: %s", error);
|
71
|
+
return Qnil;
|
72
|
+
}
|
73
|
+
|
74
|
+
return cassandra_session_obj;
|
75
|
+
}
|
76
|
+
|
77
|
+
/**
|
78
|
+
* Sets the contact points.
|
79
|
+
*
|
80
|
+
* @param hosts [Array<String>] An array of contact points.
|
81
|
+
* @return [Cassandra::Cluster] self.
|
82
|
+
*/
|
83
|
+
static VALUE cluster_hosts(VALUE self, VALUE hosts)
|
84
|
+
{
|
85
|
+
CassandraCluster *cassandra_cluster;
|
86
|
+
|
87
|
+
GET_CLUSTER(self, cassandra_cluster);
|
88
|
+
|
89
|
+
Check_Type(hosts, T_ARRAY);
|
90
|
+
if (RARRAY_LEN(hosts) == 0) {
|
91
|
+
rb_raise(rb_eArgError, "No host exists.");
|
92
|
+
}
|
93
|
+
|
94
|
+
for (int i = 0; i < RARRAY_LEN(hosts); i++) {
|
95
|
+
VALUE host = RARRAY_AREF(hosts, i);
|
96
|
+
cass_cluster_set_contact_points(cassandra_cluster->cluster, StringValueCStr(host));
|
97
|
+
}
|
98
|
+
|
99
|
+
return self;
|
100
|
+
}
|
101
|
+
|
102
|
+
/**
|
103
|
+
* Sets the port number.
|
104
|
+
* Default is +9042+.
|
105
|
+
*
|
106
|
+
* @param port [Integer] A port number.
|
107
|
+
* @return [Cassandra::Cluster] self.
|
108
|
+
*/
|
109
|
+
static VALUE cluster_port(VALUE self, VALUE port)
|
110
|
+
{
|
111
|
+
CassandraCluster *cassandra_cluster;
|
112
|
+
|
113
|
+
GET_CLUSTER(self, cassandra_cluster);
|
114
|
+
cass_cluster_set_port(cassandra_cluster->cluster, NUM2INT(port));
|
115
|
+
|
116
|
+
return self;
|
117
|
+
}
|
118
|
+
|
119
|
+
/**
|
120
|
+
* Sets the keyspace.
|
121
|
+
*
|
122
|
+
* @param keyspace [Integer] A keyspace.
|
123
|
+
* @return [Cassandra::Cluster] self.
|
124
|
+
*/
|
125
|
+
static VALUE cluster_keyspace(VALUE self, VALUE keyspace)
|
126
|
+
{
|
127
|
+
CassandraCluster *cassandra_cluster;
|
128
|
+
|
129
|
+
StringValue(keyspace);
|
130
|
+
|
131
|
+
GET_CLUSTER(self, cassandra_cluster);
|
132
|
+
cassandra_cluster->keyspace = keyspace;
|
133
|
+
|
134
|
+
return self;
|
135
|
+
}
|
136
|
+
|
137
|
+
/**
|
138
|
+
* Sets the timeout for connecting to a node.
|
139
|
+
* Default is +5000+ milliseconds.
|
140
|
+
*
|
141
|
+
* @param timeout_ms [Integer] A connect timeout in milliseconds.
|
142
|
+
* @return [Cassandra::Cluster] self.
|
143
|
+
*/
|
144
|
+
static VALUE cluster_connect_timeout(VALUE self, VALUE timeout_ms)
|
145
|
+
{
|
146
|
+
CassandraCluster *cassandra_cluster;
|
147
|
+
|
148
|
+
GET_CLUSTER(self, cassandra_cluster);
|
149
|
+
cass_cluster_set_connect_timeout(cassandra_cluster->cluster, NUM2UINT(timeout_ms));
|
150
|
+
|
151
|
+
return self;
|
152
|
+
}
|
153
|
+
|
154
|
+
/**
|
155
|
+
* Sets the timeout for waiting for a response from a node.
|
156
|
+
* Default is +12000+ milliseconds.
|
157
|
+
*
|
158
|
+
* @param timeout_ms [Integer] A request timeout in milliseconds.
|
159
|
+
* @return [Cassandra::Cluster] self.
|
160
|
+
*/
|
161
|
+
static VALUE cluster_request_timeout(VALUE self, VALUE timeout_ms)
|
162
|
+
{
|
163
|
+
CassandraCluster *cassandra_cluster;
|
164
|
+
|
165
|
+
GET_CLUSTER(self, cassandra_cluster);
|
166
|
+
cass_cluster_set_request_timeout(cassandra_cluster->cluster, NUM2UINT(timeout_ms));
|
167
|
+
|
168
|
+
return self;
|
169
|
+
}
|
170
|
+
|
171
|
+
/**
|
172
|
+
* Sets the timeout for waiting for DNS name resolution.
|
173
|
+
* Default is +2000+ milliseconds.
|
174
|
+
*
|
175
|
+
* @param timeout_ms [Integer] A request timeout in milliseconds.
|
176
|
+
* @return [Cassandra::Cluster] self.
|
177
|
+
*/
|
178
|
+
static VALUE cluster_resolve_timeout(VALUE self, VALUE timeout_ms)
|
179
|
+
{
|
180
|
+
CassandraCluster *cassandra_cluster;
|
181
|
+
|
182
|
+
GET_CLUSTER(self, cassandra_cluster);
|
183
|
+
cass_cluster_set_resolve_timeout(cassandra_cluster->cluster, NUM2UINT(timeout_ms));
|
184
|
+
|
185
|
+
return self;
|
186
|
+
}
|
187
|
+
|
188
|
+
/**
|
189
|
+
* Enable constant speculative executions with the supplied settings.
|
190
|
+
*
|
191
|
+
* @param constant_delay_ms [Integer]
|
192
|
+
* @param max_speculative_executions [Integer]
|
193
|
+
* @return [Cassandra::Cluster] self.
|
194
|
+
*/
|
195
|
+
static VALUE cluster_constant_speculative_execution_policy(VALUE self, VALUE constant_delay_ms, VALUE max_speculative_executions)
|
196
|
+
{
|
197
|
+
CassandraCluster *cassandra_cluster;
|
198
|
+
|
199
|
+
if (NUM2LONG(constant_delay_ms) < 0 || NUM2INT(max_speculative_executions) < 0) {
|
200
|
+
rb_raise(rb_eArgError, "Bad parameters.");
|
201
|
+
}
|
202
|
+
|
203
|
+
GET_CLUSTER(self, cassandra_cluster);
|
204
|
+
cass_cluster_set_constant_speculative_execution_policy(cassandra_cluster->cluster, NUM2LONG(constant_delay_ms), NUM2INT(max_speculative_executions));
|
205
|
+
|
206
|
+
return self;
|
207
|
+
}
|
208
|
+
|
209
|
+
static void cluster_mark(void *ptr)
|
210
|
+
{
|
211
|
+
CassandraCluster *cassandra_cluster = (CassandraCluster *)ptr;
|
212
|
+
rb_gc_mark_movable(cassandra_cluster->keyspace);
|
213
|
+
}
|
214
|
+
|
215
|
+
static void cluster_destroy(void *ptr)
|
216
|
+
{
|
217
|
+
CassandraCluster *cassandra_cluster = (CassandraCluster *)ptr;
|
218
|
+
|
219
|
+
if (cassandra_cluster->cluster) {
|
220
|
+
cass_cluster_free(cassandra_cluster->cluster);
|
221
|
+
}
|
222
|
+
xfree(cassandra_cluster);
|
223
|
+
}
|
224
|
+
|
225
|
+
static size_t cluster_memsize(const void *ptr)
|
226
|
+
{
|
227
|
+
return sizeof(CassandraCluster);
|
228
|
+
}
|
229
|
+
|
230
|
+
static void cluster_compact(void *ptr)
|
231
|
+
{
|
232
|
+
CassandraCluster *cassandra_cluster = (CassandraCluster *)ptr;
|
233
|
+
|
234
|
+
cassandra_cluster->keyspace = rb_gc_location(cassandra_cluster->keyspace);
|
235
|
+
}
|
236
|
+
|
237
|
+
void Init_cluster(void)
|
238
|
+
{
|
239
|
+
rb_define_alloc_func(cCluster, cluster_allocator);
|
240
|
+
rb_define_method(cCluster, "initialize", cluster_initialize, 0);
|
241
|
+
rb_define_method(cCluster, "connect", cluster_connect, 0);
|
242
|
+
rb_define_method(cCluster, "hosts", cluster_hosts, 1);
|
243
|
+
rb_define_method(cCluster, "port", cluster_port, 1);
|
244
|
+
rb_define_method(cCluster, "keyspace", cluster_keyspace, 1);
|
245
|
+
rb_define_method(cCluster, "connect_timeout", cluster_connect_timeout, 1);
|
246
|
+
rb_define_method(cCluster, "request_timeout", cluster_request_timeout, 1);
|
247
|
+
rb_define_method(cCluster, "resolve_timeout", cluster_resolve_timeout, 1);
|
248
|
+
rb_define_method(cCluster, "constant_speculative_execution_policy", cluster_constant_speculative_execution_policy, 2);
|
249
|
+
|
250
|
+
}
|
data/ext/ilios/future.c
CHANGED
@@ -32,8 +32,11 @@ const rb_data_type_t cassandra_future_data_type = {
|
|
32
32
|
static void future_thread_pool_init(future_thread_pool *pool)
|
33
33
|
{
|
34
34
|
pool->queue = rb_funcall(cQueue, id_new, 0);
|
35
|
+
rb_gc_register_mark_object(pool->queue);
|
36
|
+
|
35
37
|
for (int i = 0; i < THREAD_MAX; i++) {
|
36
38
|
pool->thread[i] = rb_thread_create(future_result_yielder_thread, (void*)pool);
|
39
|
+
rb_gc_register_mark_object(pool->thread[i]);
|
37
40
|
}
|
38
41
|
}
|
39
42
|
|
data/ext/ilios/ilios.c
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
VALUE mIlios;
|
4
4
|
VALUE mCassandra;
|
5
|
+
VALUE cCluster;
|
5
6
|
VALUE cSession;
|
6
7
|
VALUE cStatement;
|
7
8
|
VALUE cResult;
|
@@ -12,19 +13,11 @@ VALUE eStatementError;
|
|
12
13
|
|
13
14
|
VALUE cQueue;
|
14
15
|
|
15
|
-
VALUE id_cvar_config;
|
16
|
-
VALUE id_shuffle;
|
17
16
|
VALUE id_to_time;
|
18
17
|
VALUE id_new;
|
19
18
|
VALUE id_push;
|
20
19
|
VALUE id_pop;
|
21
20
|
VALUE sym_unsupported_column_type;
|
22
|
-
VALUE sym_keyspace;
|
23
|
-
VALUE sym_hosts;
|
24
|
-
VALUE sym_timeout_ms;
|
25
|
-
VALUE sym_constant_delay_ms;
|
26
|
-
VALUE sym_max_speculative_executions;
|
27
|
-
VALUE sym_page_size;
|
28
21
|
|
29
22
|
#if defined(HAVE_MALLOC_USABLE_SIZE)
|
30
23
|
#include <malloc.h>
|
@@ -65,8 +58,11 @@ static void ilios_free(void *ptr)
|
|
65
58
|
|
66
59
|
void Init_ilios(void)
|
67
60
|
{
|
61
|
+
rb_ext_ractor_safe(true);
|
62
|
+
|
68
63
|
mIlios = rb_define_module("Ilios");
|
69
64
|
mCassandra = rb_define_module_under(mIlios, "Cassandra");
|
65
|
+
cCluster = rb_define_class_under(mCassandra, "Cluster", rb_cObject);
|
70
66
|
cSession = rb_define_class_under(mCassandra, "Session", rb_cObject);
|
71
67
|
cStatement = rb_define_class_under(mCassandra, "Statement", rb_cObject);
|
72
68
|
cResult = rb_define_class_under(mCassandra, "Result", rb_cObject);
|
@@ -77,21 +73,13 @@ void Init_ilios(void)
|
|
77
73
|
|
78
74
|
cQueue = rb_const_get(rb_cThread, rb_intern("Queue"));
|
79
75
|
|
80
|
-
id_cvar_config = rb_intern("@@config");
|
81
|
-
id_shuffle = rb_intern("shuffle");
|
82
76
|
id_to_time = rb_intern("to_time");
|
83
77
|
id_new = rb_intern("new");
|
84
78
|
id_push = rb_intern("push");
|
85
79
|
id_pop = rb_intern("pop");
|
86
80
|
sym_unsupported_column_type = ID2SYM(rb_intern("unsupported_column_type"));
|
87
|
-
sym_keyspace = ID2SYM(rb_intern("keyspace"));
|
88
|
-
sym_hosts = ID2SYM(rb_intern("hosts"));
|
89
|
-
sym_timeout_ms = ID2SYM(rb_intern("timeout_ms"));
|
90
|
-
sym_constant_delay_ms = ID2SYM(rb_intern("constant_delay_ms"));
|
91
|
-
sym_max_speculative_executions = ID2SYM(rb_intern("max_speculative_executions"));
|
92
|
-
sym_page_size = ID2SYM(rb_intern("page_size"));
|
93
81
|
|
94
|
-
|
82
|
+
Init_cluster();
|
95
83
|
Init_session();
|
96
84
|
Init_statement();
|
97
85
|
Init_result();
|
data/ext/ilios/ilios.h
CHANGED
@@ -9,10 +9,14 @@
|
|
9
9
|
#include "ruby/thread.h"
|
10
10
|
#include "ruby/encoding.h"
|
11
11
|
|
12
|
+
#define DEFAULT_PAGE_SIZE 10000
|
13
|
+
|
14
|
+
#define GET_CLUSTER(obj, var) TypedData_Get_Struct(obj, CassandraCluster, &cassandra_cluster_data_type, var)
|
12
15
|
#define GET_SESSION(obj, var) TypedData_Get_Struct(obj, CassandraSession, &cassandra_session_data_type, var)
|
13
16
|
#define GET_STATEMENT(obj, var) TypedData_Get_Struct(obj, CassandraStatement, &cassandra_statement_data_type, var)
|
14
17
|
#define GET_RESULT(obj, var) TypedData_Get_Struct(obj, CassandraResult, &cassandra_result_data_type, var)
|
15
18
|
#define GET_FUTURE(obj, var) TypedData_Get_Struct(obj, CassandraFuture, &cassandra_future_data_type, var)
|
19
|
+
#define CREATE_CLUSTER(var) TypedData_Make_Struct(cCluster, CassandraCluster, &cassandra_cluster_data_type, var)
|
16
20
|
#define CREATE_SESSION(var) TypedData_Make_Struct(cSession, CassandraSession, &cassandra_session_data_type, var)
|
17
21
|
#define CREATE_STATEMENT(var) TypedData_Make_Struct(cStatement, CassandraStatement, &cassandra_statement_data_type, var)
|
18
22
|
#define CREATE_RESULT(var) TypedData_Make_Struct(cResult, CassandraResult, &cassandra_result_data_type, var)
|
@@ -26,9 +30,13 @@ typedef enum {
|
|
26
30
|
typedef struct
|
27
31
|
{
|
28
32
|
CassCluster* cluster;
|
29
|
-
|
33
|
+
VALUE keyspace;
|
34
|
+
} CassandraCluster;
|
35
|
+
typedef struct
|
36
|
+
{
|
30
37
|
CassSession* session;
|
31
|
-
|
38
|
+
CassFuture* connect_future;
|
39
|
+
VALUE cluster_obj;
|
32
40
|
} CassandraSession;
|
33
41
|
|
34
42
|
typedef struct
|
@@ -60,6 +68,7 @@ typedef struct
|
|
60
68
|
bool already_waited;
|
61
69
|
} CassandraFuture;
|
62
70
|
|
71
|
+
extern const rb_data_type_t cassandra_cluster_data_type;
|
63
72
|
extern const rb_data_type_t cassandra_session_data_type;
|
64
73
|
extern const rb_data_type_t cassandra_statement_data_type;
|
65
74
|
extern const rb_data_type_t cassandra_result_data_type;
|
@@ -67,6 +76,7 @@ extern const rb_data_type_t cassandra_future_data_type;
|
|
67
76
|
|
68
77
|
extern VALUE mIlios;
|
69
78
|
extern VALUE mCassandra;
|
79
|
+
extern VALUE cCluster;
|
70
80
|
extern VALUE cSession;
|
71
81
|
extern VALUE cStatement;
|
72
82
|
extern VALUE cResult;
|
@@ -77,21 +87,13 @@ extern VALUE eStatementError;
|
|
77
87
|
|
78
88
|
extern VALUE cQueue;
|
79
89
|
|
80
|
-
extern VALUE id_cvar_config;
|
81
|
-
extern VALUE id_shuffle;
|
82
90
|
extern VALUE id_to_time;
|
83
91
|
extern VALUE id_new;
|
84
92
|
extern VALUE id_push;
|
85
93
|
extern VALUE id_pop;
|
86
94
|
extern VALUE sym_unsupported_column_type;
|
87
|
-
|
88
|
-
extern
|
89
|
-
extern VALUE sym_timeout_ms;
|
90
|
-
extern VALUE sym_constant_delay_ms;
|
91
|
-
extern VALUE sym_max_speculative_executions;
|
92
|
-
extern VALUE sym_page_size;
|
93
|
-
|
94
|
-
extern void Init_cassandra(void);
|
95
|
+
|
96
|
+
extern void Init_cluster(void);
|
95
97
|
extern void Init_session(void);
|
96
98
|
extern void Init_statement(void);
|
97
99
|
extern void Init_result(void);
|
data/ext/ilios/session.c
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
#include "ilios.h"
|
2
2
|
|
3
|
+
static void session_mark(void *ptr);
|
3
4
|
static void session_destroy(void *ptr);
|
4
5
|
static size_t session_memsize(const void *ptr);
|
6
|
+
static void session_compact(void *ptr);
|
5
7
|
|
6
8
|
const rb_data_type_t cassandra_session_data_type = {
|
7
9
|
"Ilios::Cassandra::Session",
|
8
10
|
{
|
9
|
-
|
11
|
+
session_mark,
|
10
12
|
session_destroy,
|
11
13
|
session_memsize,
|
12
|
-
|
14
|
+
session_compact,
|
13
15
|
},
|
14
16
|
0, 0,
|
15
17
|
RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
|
@@ -121,6 +123,12 @@ static VALUE session_execute(VALUE self, VALUE statement)
|
|
121
123
|
return cassandra_result_obj;
|
122
124
|
}
|
123
125
|
|
126
|
+
static void session_mark(void *ptr)
|
127
|
+
{
|
128
|
+
CassandraSession *cassandra_session = (CassandraSession *)ptr;
|
129
|
+
rb_gc_mark_movable(cassandra_session->cluster_obj);
|
130
|
+
}
|
131
|
+
|
124
132
|
static void session_destroy(void *ptr)
|
125
133
|
{
|
126
134
|
CassandraSession *cassandra_session = (CassandraSession *)ptr;
|
@@ -131,9 +139,6 @@ static void session_destroy(void *ptr)
|
|
131
139
|
if (cassandra_session->connect_future) {
|
132
140
|
cass_future_free(cassandra_session->connect_future);
|
133
141
|
}
|
134
|
-
if (cassandra_session->cluster) {
|
135
|
-
cass_cluster_free(cassandra_session->cluster);
|
136
|
-
}
|
137
142
|
xfree(cassandra_session);
|
138
143
|
}
|
139
144
|
|
@@ -142,6 +147,13 @@ static size_t session_memsize(const void *ptr)
|
|
142
147
|
return sizeof(CassandraSession);
|
143
148
|
}
|
144
149
|
|
150
|
+
static void session_compact(void *ptr)
|
151
|
+
{
|
152
|
+
CassandraSession *cassandra_session = (CassandraSession *)ptr;
|
153
|
+
|
154
|
+
cassandra_session->cluster_obj = rb_gc_location(cassandra_session->cluster_obj);
|
155
|
+
}
|
156
|
+
|
145
157
|
void Init_session(void)
|
146
158
|
{
|
147
159
|
rb_undef_alloc_func(cSession);
|
data/ext/ilios/statement.c
CHANGED
@@ -19,10 +19,7 @@ const rb_data_type_t cassandra_statement_data_type = {
|
|
19
19
|
|
20
20
|
void statement_default_config(CassandraStatement *cassandra_statement)
|
21
21
|
{
|
22
|
-
|
23
|
-
|
24
|
-
cass_statement_set_request_timeout(cassandra_statement->statement, NUM2INT(rb_hash_aref(config, sym_timeout_ms)));
|
25
|
-
cass_statement_set_paging_size(cassandra_statement->statement, NUM2INT(rb_hash_aref(config, sym_page_size)));
|
22
|
+
cass_statement_set_paging_size(cassandra_statement->statement, DEFAULT_PAGE_SIZE);
|
26
23
|
}
|
27
24
|
|
28
25
|
static int hash_cb(VALUE key, VALUE value, VALUE statement)
|
@@ -235,7 +232,6 @@ static void statement_compact(void *ptr)
|
|
235
232
|
cassandra_statement->session_obj = rb_gc_location(cassandra_statement->session_obj);
|
236
233
|
}
|
237
234
|
|
238
|
-
|
239
235
|
void Init_statement(void)
|
240
236
|
{
|
241
237
|
rb_undef_alloc_func(cStatement);
|
data/lib/ilios/version.rb
CHANGED
data/lib/ilios.rb
CHANGED
@@ -2,39 +2,3 @@
|
|
2
2
|
|
3
3
|
require 'ilios.so'
|
4
4
|
require 'ilios/version'
|
5
|
-
|
6
|
-
module Ilios
|
7
|
-
module Cassandra
|
8
|
-
# The default options.
|
9
|
-
@@config = {
|
10
|
-
keyspace: 'ilios',
|
11
|
-
hosts: ['127.0.0.1'],
|
12
|
-
timeout_ms: 5_000,
|
13
|
-
constant_delay_ms: 15_000,
|
14
|
-
max_speculative_executions: 2,
|
15
|
-
page_size: 10_000
|
16
|
-
}
|
17
|
-
|
18
|
-
#
|
19
|
-
# Configures the option for connection or execution.
|
20
|
-
# The default value will be overridden by the specified option.
|
21
|
-
#
|
22
|
-
# @param config [Hash] A hash object contained the options.
|
23
|
-
#
|
24
|
-
def self.config=(config)
|
25
|
-
@@config = @@config.merge(config)
|
26
|
-
end
|
27
|
-
|
28
|
-
#
|
29
|
-
# Connects a session to the keyspace specified in +config+ method.
|
30
|
-
# The session object will be memorized by each threads.
|
31
|
-
#
|
32
|
-
# @return [Cassandra::Session] The session object.
|
33
|
-
# @raise [RuntimeError] If no host is specified to connect in +config+ method.
|
34
|
-
# @raise [Cassandra::ConnectError] If the connection fails for any reason.
|
35
|
-
#
|
36
|
-
def self.session
|
37
|
-
Thread.current[:ilios_cassandra_session] ||= connect
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
data/sig/ilios.rbs
CHANGED
@@ -2,9 +2,16 @@ module Ilios
|
|
2
2
|
VERSION: String
|
3
3
|
|
4
4
|
module Cassandra
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
class Cluster
|
6
|
+
def connect: () -> Ilios::Cassandra::Session
|
7
|
+
def hosts: (Array[String]) -> self
|
8
|
+
def port: (Integer) -> self
|
9
|
+
def keyspace: (String) -> self
|
10
|
+
def connect_timeout: (Integer) -> self
|
11
|
+
def request_timeout: (Integer) -> self
|
12
|
+
def resolve_timeout: (Integer) -> self
|
13
|
+
def constant_speculative_execution_policy: (Integer, Integer) -> self
|
14
|
+
end
|
8
15
|
|
9
16
|
class Session
|
10
17
|
def prepare_async: (String) -> Ilios::Cassandra::Future
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ilios
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Watson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-12-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: mini_portile2
|
@@ -51,7 +51,7 @@ files:
|
|
51
51
|
- README.md
|
52
52
|
- Rakefile
|
53
53
|
- docker-compose.yml
|
54
|
-
- ext/ilios/
|
54
|
+
- ext/ilios/cluster.c
|
55
55
|
- ext/ilios/extconf.rb
|
56
56
|
- ext/ilios/future.c
|
57
57
|
- ext/ilios/ilios.c
|
@@ -71,7 +71,7 @@ metadata:
|
|
71
71
|
homepage_uri: https://github.com/Watson1978/ilios
|
72
72
|
source_code_uri: https://github.com/Watson1978/ilios
|
73
73
|
bug_tracker_uri: https://github.com/Watson1978/ilios/issues
|
74
|
-
documentation_uri: https://www.rubydoc.info/gems/ilios/0.
|
74
|
+
documentation_uri: https://www.rubydoc.info/gems/ilios/0.4.1
|
75
75
|
rubygems_mfa_required: 'true'
|
76
76
|
post_install_message:
|
77
77
|
rdoc_options: []
|
data/ext/ilios/cassandra.c
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
#include "ilios.h"
|
2
|
-
|
3
|
-
/**
|
4
|
-
* Connects a session to the keyspace specified in +config+ method.
|
5
|
-
*
|
6
|
-
* @return [Cassandra::Session] A new session object.
|
7
|
-
* @raise [RuntimeError] If no host is specified to connect in +config+ method.
|
8
|
-
* @raise [Cassandra::ConnectError] If the connection fails for any reason.
|
9
|
-
*/
|
10
|
-
static VALUE cassandra_connect(VALUE self)
|
11
|
-
{
|
12
|
-
CassandraSession *cassandra_session;
|
13
|
-
VALUE cassandra_session_obj;
|
14
|
-
VALUE config;
|
15
|
-
VALUE hosts;
|
16
|
-
VALUE keyspace;
|
17
|
-
|
18
|
-
cassandra_session_obj = CREATE_SESSION(cassandra_session);
|
19
|
-
|
20
|
-
cassandra_session->cluster = cass_cluster_new();
|
21
|
-
cass_cluster_set_protocol_version(cassandra_session->cluster, CASS_PROTOCOL_VERSION_V4);
|
22
|
-
|
23
|
-
config = rb_cvar_get(self, id_cvar_config);
|
24
|
-
cass_cluster_set_request_timeout(cassandra_session->cluster, NUM2UINT(rb_hash_aref(config, sym_timeout_ms)));
|
25
|
-
cass_cluster_set_constant_speculative_execution_policy(cassandra_session->cluster, NUM2LONG(rb_hash_aref(config, sym_constant_delay_ms)), NUM2INT(rb_hash_aref(config, sym_max_speculative_executions)));
|
26
|
-
|
27
|
-
keyspace = rb_hash_aref(config, sym_keyspace);
|
28
|
-
hosts = rb_hash_aref(config, sym_hosts);
|
29
|
-
|
30
|
-
Check_Type(hosts, T_ARRAY);
|
31
|
-
if (RARRAY_LEN(hosts) == 0) {
|
32
|
-
rb_raise(rb_eRuntimeError, "No hosts configured");
|
33
|
-
}
|
34
|
-
if (RARRAY_LEN(hosts) > 1) {
|
35
|
-
// To distribute connections
|
36
|
-
hosts = rb_funcall(hosts, id_shuffle, 0);
|
37
|
-
}
|
38
|
-
|
39
|
-
for (int i = 0; i < RARRAY_LEN(hosts); i++) {
|
40
|
-
VALUE host = RARRAY_AREF(hosts, i);
|
41
|
-
cass_cluster_set_contact_points(cassandra_session->cluster, StringValueCStr(host));
|
42
|
-
}
|
43
|
-
cassandra_session->session = cass_session_new();
|
44
|
-
cassandra_session->connect_future = cass_session_connect_keyspace(cassandra_session->session, cassandra_session->cluster, StringValueCStr(keyspace));
|
45
|
-
nogvl_future_wait(cassandra_session->connect_future);
|
46
|
-
|
47
|
-
if (cass_future_error_code(cassandra_session->connect_future) != CASS_OK) {
|
48
|
-
char error[4096] = { 0 };
|
49
|
-
|
50
|
-
strncpy(error, cass_error_desc(cass_future_error_code(cassandra_session->connect_future)), sizeof(error) - 1);
|
51
|
-
cass_future_free(cassandra_session->connect_future);
|
52
|
-
cass_session_free(cassandra_session->session);
|
53
|
-
cass_cluster_free(cassandra_session->cluster);
|
54
|
-
rb_raise(eConnectError, "Unable to connect: %s", error);
|
55
|
-
return Qnil;
|
56
|
-
}
|
57
|
-
|
58
|
-
return cassandra_session_obj;
|
59
|
-
}
|
60
|
-
|
61
|
-
void Init_cassandra(void)
|
62
|
-
{
|
63
|
-
rb_define_module_function(mCassandra, "connect", cassandra_connect, 0);
|
64
|
-
}
|