ilios 0.3.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 97cd17ec9e27eba88f4200dc050417934daa8820a8c6621b47ffa0e76d4f38be
4
- data.tar.gz: '0508e6e770984ba635caa2a587a69a7a2a0b7eedab2016dfa1292480ddf81ea6'
3
+ metadata.gz: 9a0eec8f797b5f1c0cd369a5f43f004d6acf3a27870580689ede24d637035d35
4
+ data.tar.gz: 7ca5100a6125c8b6069597b4c23b26ce5313fc0222a625f9e17933ec73270562
5
5
  SHA512:
6
- metadata.gz: b882a9744b4cde1c74429c6a4ab3bc8de0338ac0e7b56a9bd657ad0c843a35c77deaa884e2a898c5b5ae5a4dff5c8d8aadfce30a4000dbf4df103e7376bd3b1c
7
- data.tar.gz: 66757dbdfc249e68613f1ace36092520b8efad5d82db1f41a15ba8b0b2226502abd6bb288a9e7a73d6e82f7c0491bb2f86de3e977b4556cced7ae50c4feff439
6
+ metadata.gz: c200386bf0f73dc3adea1cf56abb3778e2b968ae14309841e15e0c11f52778b663c4271e0119bea9b472a94b137c62adaa2f2a118ea89bfe2d2c8eff64ff6ca0
7
+ data.tar.gz: 152eadf8000d73569e604d9c681b9e410c15a066c947c196ba66619fc776f3089a489a9363967766ee87c4ac05421960b628994e9e581e94ddf883b04810db86
data/README.md CHANGED
@@ -20,14 +20,14 @@ This gem's installer will install the DataStax C/C++ Driver to the appropriate l
20
20
  However, if you prefer to install the DataStax C/C++ Driver manually, you can do so by executing:
21
21
 
22
22
  ```sh
23
- $ bundle config set --local build.ilios --with-cpp-driver-dir=/path/to/cassandra-cpp-driver-installed-dir
23
+ $ bundle config set --local build.ilios --with-cassandra-driver-dir=/path/to/cassandra-cpp-driver-installed-dir
24
24
  $ bundle add ilios
25
25
  ```
26
26
 
27
27
  or
28
28
 
29
29
  ```sh
30
- $ gem install ilios -- --with-cpp-driver-dir=/path/to/cassandra-cpp-driver-installed-dir
30
+ $ gem install ilios -- --with-cassandra-driver-dir=/path/to/cassandra-cpp-driver-installed-dir
31
31
  ```
32
32
 
33
33
  ## Requirements
@@ -58,13 +58,13 @@ Then, you can run the following code.
58
58
  ```ruby
59
59
  require 'ilios'
60
60
 
61
- Ilios::Cassandra.config = {
62
- keyspace: 'ilios',
63
- hosts: ['127.0.0.1'],
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 = Ilios::Cassandra.session.prepare(<<~CQL)
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
- Ilios::Cassandra.session.execute(statement)
76
+ session.execute(statement)
77
77
 
78
78
  # Insert the records
79
- statement = Ilios::Cassandra.session.prepare(<<~CQL)
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
- Ilios::Cassandra.session.execute(statement)
93
+ session.execute(statement)
94
94
  end
95
95
 
96
96
  # Select the records
97
- statement = Ilios::Cassandra.session.prepare(<<~CQL)
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 = Ilios::Cassandra.session.execute(statement)
102
+ result = session.execute(statement)
103
103
  result.each do |row|
104
104
  p row
105
105
  end
@@ -115,7 +115,7 @@ end
115
115
  `Ilios::Cassandra::Session#prepare` and `Ilios::Cassandra::Session#execute` are provided as synchronous API.
116
116
 
117
117
  ```ruby
118
- statement = Ilios::Cassandra.session.prepare(<<~CQL)
118
+ statement = session.prepare(<<~CQL)
119
119
  SELECT * FROM ilios.example
120
120
  CQL
121
121
  result = Ilios::Cassandra.session.execute(statement)
@@ -125,7 +125,7 @@ result = Ilios::Cassandra.session.execute(statement)
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 = Ilios::Cassandra.session.prepare_async(<<~CQL)
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 = Ilios::Cassandra.session.execute_async(statement)
145
+ result_future = session.execute_async(statement)
146
146
  result_future.on_success { |result|
147
147
  p result
148
148
  p "success"
@@ -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/extconf.rb CHANGED
@@ -9,20 +9,6 @@ require 'native-package-installer'
9
9
  have_func('malloc_usable_size')
10
10
  have_func('malloc_size')
11
11
 
12
- unless find_executable('cmake')
13
- puts '--------------------------------------------------'
14
- puts 'Error: cmake is required to build this gem'
15
- puts '--------------------------------------------------'
16
- raise
17
- end
18
-
19
- if RUBY_PLATFORM.include?('darwin') && !find_executable('install_name_tool')
20
- puts('------------------------------------------------------')
21
- puts('Error: install_name_tool is required to build this gem')
22
- puts('------------------------------------------------------')
23
- raise
24
- end
25
-
26
12
  def num_cpu_cores
27
13
  cores =
28
14
  begin
@@ -156,6 +142,21 @@ if (dir = with_config('--with-cassandra-driver-dir'))
156
142
  $CPPFLAGS += " -I#{dir}/include"
157
143
  $LDFLAGS += " -L#{dir}/lib -Wl,-rpath,#{dir}/lib -lcassandra"
158
144
  else
145
+
146
+ unless find_executable('cmake')
147
+ puts '--------------------------------------------------'
148
+ puts 'Error: cmake is required to build this gem'
149
+ puts '--------------------------------------------------'
150
+ raise
151
+ end
152
+
153
+ if RUBY_PLATFORM.include?('darwin') && !find_executable('install_name_tool')
154
+ puts('------------------------------------------------------')
155
+ puts('Error: install_name_tool is required to build this gem')
156
+ puts('------------------------------------------------------')
157
+ raise
158
+ end
159
+
159
160
  LibuvInstaller.install
160
161
  CassandraDriverInstaller.install
161
162
  end
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
- Init_cassandra();
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
- CassFuture* connect_future;
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
- extern VALUE sym_keyspace;
88
- extern VALUE sym_hosts;
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
- NULL,
11
+ session_mark,
10
12
  session_destroy,
11
13
  session_memsize,
12
- NULL,
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);
@@ -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
- VALUE config = rb_cvar_get(mCassandra, id_cvar_config);
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
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Ilios
4
- VERSION = '0.3.1'
4
+ VERSION = '0.4.0'
5
5
  public_constant :VERSION
6
6
 
7
7
  CASSANDRA_CPP_DRIVER_VERSION = '2.17.1'
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
- def self.config=: (Hash[Symbol, untyped]) -> void
6
- def self.session: () -> Ilios::Cassandra::Session
7
- def self.connect: () -> Ilios::Cassandra::Session
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.3.1
4
+ version: 0.4.0
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-27 00:00:00.000000000 Z
11
+ date: 2023-12-07 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/cassandra.c
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.3.1
74
+ documentation_uri: https://www.rubydoc.info/gems/ilios/0.4.0
75
75
  rubygems_mfa_required: 'true'
76
76
  post_install_message:
77
77
  rdoc_options: []
@@ -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
- }