ilios 0.2.1 → 0.3.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: 035cde2f726822e26aa111fc8998c14f68849cd2ad5ac90c738d0b4fde8fa87c
4
- data.tar.gz: e565f45883e0056d4b009790ca260dffbe3b42b2afc507d0cdd4bf30b765fab4
3
+ metadata.gz: b5dee1fc3383cb4e1c7ee917e6b582456b02ef3e1121ca62b65ad5f94e827706
4
+ data.tar.gz: c6f7a9a6ae097cc74a644ec2d1d4d1b8fadcfc09697db4a537ab6e500ed8e6ef
5
5
  SHA512:
6
- metadata.gz: 577089ba568337c8482f137df676d50959aca02a17e02b0978bafd3dd8fb9063c344f466a19e8c17f8e950e390f8513249b8f1c1862ad42d4917cd4ffba17978
7
- data.tar.gz: ecbf6f1f31990c9cc04a466ddd615725320157d91b1513417c3719830aad2b47909201626b1f73b504bfd1a2ef29fac8a012db060e327e3cef2cbaa870d82429
6
+ metadata.gz: 372a423c84b1a61457f2be6f7a7f639664d5854a0b274cb77936052e0ea2da29c5af61c36202d9363c9e7c1f4e39258480ecfe81e875f32bc3fad6c70b072b69
7
+ data.tar.gz: fa5a1d64b04fc51b1a831204af7d82154c72631f0276fee2ebfcf0641af3b82940664793c995365551312c5d8ad56ccc16fc640dbb9577410d8671c7c3d17d09
data/README.md CHANGED
@@ -16,12 +16,22 @@ If bundler is not being used to manage dependencies, install the gem by executin
16
16
  $ gem install ilios
17
17
  ```
18
18
 
19
+ ## Requirements
20
+
21
+ - cmake (in order to build the DataStax C/C++ Driver and libuv)
22
+
23
+ ## Supported
24
+
25
+ - Ruby 3.0 or later
26
+ - Cassandra 3.0 or later
27
+ - Linux and macOS platform
28
+
19
29
  ## Example
20
30
  ### Basic usage
21
31
 
22
32
  Create the keyspace in advance using the `cqlsh` command.
23
33
 
24
- ```sh
34
+ ```cql
25
35
  CREATE KEYSPACE IF NOT EXISTS ilios
26
36
  WITH REPLICATION = {
27
37
  'class' : 'SimpleStrategy',
@@ -73,6 +83,7 @@ end
73
83
  statement = Ilios::Cassandra.session.prepare(<<~CQL)
74
84
  SELECT * FROM ilios.example
75
85
  CQL
86
+ statement.idempotent = true
76
87
  statement.page_size = 25
77
88
  result = Ilios::Cassandra.session.execute(statement)
78
89
  result.each do |row|
@@ -14,7 +14,6 @@ static VALUE cassandra_connect(VALUE self)
14
14
  VALUE config;
15
15
  VALUE hosts;
16
16
  VALUE keyspace;
17
- char last_error[4096] = { 0 };
18
17
 
19
18
  cassandra_session_obj = CREATE_SESSION(cassandra_session);
20
19
 
@@ -39,29 +38,24 @@ static VALUE cassandra_connect(VALUE self)
39
38
 
40
39
  for (int i = 0; i < RARRAY_LEN(hosts); i++) {
41
40
  VALUE host = RARRAY_AREF(hosts, i);
42
-
43
- cass_cluster_set_contact_points(cassandra_session->cluster, ""); // Clear previous contact points
44
41
  cass_cluster_set_contact_points(cassandra_session->cluster, StringValueCStr(host));
45
- cassandra_session->session = cass_session_new();
46
- cassandra_session->connect_future = cass_session_connect_keyspace(cassandra_session->session, cassandra_session->cluster, StringValueCStr(keyspace));
47
- nogvl_future_wait(cassandra_session->connect_future);
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);
48
46
 
49
- if (cass_future_error_code(cassandra_session->connect_future) == CASS_OK) {
50
- return cassandra_session_obj;
51
- }
47
+ if (cass_future_error_code(cassandra_session->connect_future) != CASS_OK) {
48
+ char error[4096] = { 0 };
52
49
 
53
- strncpy(last_error, cass_error_desc(cass_future_error_code(cassandra_session->connect_future)), sizeof(last_error) - 1);
50
+ strncpy(error, cass_error_desc(cass_future_error_code(cassandra_session->connect_future)), sizeof(error) - 1);
54
51
  cass_future_free(cassandra_session->connect_future);
55
52
  cass_session_free(cassandra_session->session);
56
- cassandra_session->connect_future = NULL;
57
- cassandra_session->session = NULL;
53
+ cass_cluster_free(cassandra_session->cluster);
54
+ rb_raise(eConnectError, "Unable to connect: %s", error);
55
+ return Qnil;
58
56
  }
59
57
 
60
- cass_cluster_free(cassandra_session->cluster);
61
- cassandra_session->cluster = NULL;
62
-
63
- rb_raise(eConnectError, "Unable to connect: %s", last_error);
64
- return Qnil;
58
+ return cassandra_session_obj;
65
59
  }
66
60
 
67
61
  void Init_cassandra(void)
data/ext/ilios/extconf.rb CHANGED
@@ -11,6 +11,20 @@ have_func('malloc_size')
11
11
  CASSANDRA_CPP_DRIVER_INSTALL_PATH = File.expand_path('cpp-driver')
12
12
  LIBUV_INSTALL_PATH = File.expand_path('libuv')
13
13
 
14
+ def num_cpu_cores
15
+ cores =
16
+ begin
17
+ if RUBY_PLATFORM.include?('darwin')
18
+ Integer(`sysctl -n hw.ncpu`, 10) - 1
19
+ else
20
+ Integer(`nproc`, 10) - 1
21
+ end
22
+ rescue StandardError
23
+ 2
24
+ end
25
+ cores.positive? ? cores : 1
26
+ end
27
+
14
28
  unless find_executable('cmake')
15
29
  puts '--------------------------------------------------'
16
30
  puts 'Error: cmake is required to build this gem'
@@ -25,7 +39,7 @@ unless File.exist?(LIBUV_INSTALL_PATH)
25
39
  end
26
40
  end
27
41
 
28
- libuv_recipe = LibuvRecipe.new('libuv', Ilios::LIBUV_VERSION, make_command: 'make -j 3')
42
+ libuv_recipe = LibuvRecipe.new('libuv', Ilios::LIBUV_VERSION, make_command: "make -j #{num_cpu_cores}")
29
43
  libuv_recipe.files << {
30
44
  url: "https://github.com/libuv/libuv/archive/v#{Ilios::LIBUV_VERSION}.tar.gz"
31
45
  }
@@ -53,7 +67,7 @@ unless File.exist?(CASSANDRA_CPP_DRIVER_INSTALL_PATH)
53
67
  end
54
68
  end
55
69
 
56
- cassandra_recipe = CassandraRecipe.new('cpp-driver', Ilios::CASSANDRA_CPP_DRIVER_VERSION, make_command: 'make -j 3')
70
+ cassandra_recipe = CassandraRecipe.new('cpp-driver', Ilios::CASSANDRA_CPP_DRIVER_VERSION, make_command: "make -j #{num_cpu_cores}")
57
71
  cassandra_recipe.files << {
58
72
  url: "https://github.com/datastax/cpp-driver/archive/#{Ilios::CASSANDRA_CPP_DRIVER_VERSION}.tar.gz"
59
73
  }
data/ext/ilios/future.c CHANGED
@@ -212,6 +212,15 @@ static VALUE future_on_success(VALUE self)
212
212
 
213
213
  cassandra_future->on_success_block = rb_block_proc();
214
214
 
215
+ if (cass_future_ready(cassandra_future->future)) {
216
+ rb_mutex_unlock(cassandra_future->proc_mutex);
217
+ uv_sem_post(&cassandra_future->sem);
218
+ if (cass_future_error_code(cassandra_future->future) == CASS_OK) {
219
+ future_result_success_yield(cassandra_future);
220
+ }
221
+ return self;
222
+ }
223
+
215
224
  if (wakeup_thread) {
216
225
  future_queue_push(future_thread_pool_get(cassandra_future), self);
217
226
  }
@@ -250,6 +259,15 @@ static VALUE future_on_failure(VALUE self)
250
259
 
251
260
  cassandra_future->on_failure_block = rb_block_proc();
252
261
 
262
+ if (cass_future_ready(cassandra_future->future)) {
263
+ rb_mutex_unlock(cassandra_future->proc_mutex);
264
+ uv_sem_post(&cassandra_future->sem);
265
+ if (cass_future_error_code(cassandra_future->future) != CASS_OK) {
266
+ future_result_failure_yield(cassandra_future);
267
+ }
268
+ return self;
269
+ }
270
+
253
271
  if (wakeup_thread) {
254
272
  future_queue_push(future_thread_pool_get(cassandra_future), self);
255
273
  }
data/ext/ilios/ilios.h CHANGED
@@ -7,6 +7,7 @@
7
7
  #include <uv.h>
8
8
  #include "ruby.h"
9
9
  #include "ruby/thread.h"
10
+ #include "ruby/encoding.h"
10
11
 
11
12
  #define GET_SESSION(obj, var) TypedData_Get_Struct(obj, CassandraSession, &cassandra_session_data_type, var)
12
13
  #define GET_STATEMENT(obj, var) TypedData_Get_Struct(obj, CassandraStatement, &cassandra_statement_data_type, var)
data/ext/ilios/result.c CHANGED
@@ -80,7 +80,7 @@ static VALUE result_convert_row(const CassResult *result, const CassRow *row, si
80
80
  const CassValueType type = cass_value_type(value);
81
81
 
82
82
  cass_result_column_name(result, i, &name, &name_length);
83
- key = rb_str_new(name, name_length);
83
+ key = rb_enc_interned_str(name, name_length, rb_utf8_encoding());
84
84
 
85
85
  if (cass_value_is_null(value)) {
86
86
  rb_hash_aset(hash, key, Qnil);
@@ -21,6 +21,7 @@ void statement_default_config(CassandraStatement *cassandra_statement)
21
21
  {
22
22
  VALUE config = rb_cvar_get(mCassandra, id_cvar_config);
23
23
 
24
+ cass_statement_set_request_timeout(cassandra_statement->statement, NUM2INT(rb_hash_aref(config, sym_timeout_ms)));
24
25
  cass_statement_set_paging_size(cassandra_statement->statement, NUM2INT(rb_hash_aref(config, sym_page_size)));
25
26
  }
26
27
 
@@ -186,6 +187,23 @@ static VALUE statement_page_size(VALUE self, VALUE page_size)
186
187
  return self;
187
188
  }
188
189
 
190
+ /**
191
+ * Sets whether the statement is idempotent. Idempotent statements are able to be
192
+ * automatically retried after timeouts/errors and can be speculatively executed.
193
+ * The default is +false+.
194
+ *
195
+ * @param idempotent [Boolean] Whether the statement is idempotent.
196
+ * @return [Cassandra::Statement] self.
197
+ */
198
+ static VALUE statement_idempotent(VALUE self, VALUE idempotent)
199
+ {
200
+ CassandraStatement *cassandra_statement;
201
+
202
+ GET_STATEMENT(self, cassandra_statement);
203
+ cass_statement_set_is_idempotent(cassandra_statement->statement, RTEST(idempotent) ? cass_true : cass_false);
204
+ return self;
205
+ }
206
+
189
207
  static void statement_mark(void *ptr)
190
208
  {
191
209
  CassandraStatement *cassandra_statement = (CassandraStatement *)ptr;
@@ -224,4 +242,5 @@ void Init_statement(void)
224
242
 
225
243
  rb_define_method(cStatement, "bind", statement_bind, 1);
226
244
  rb_define_method(cStatement, "page_size=", statement_page_size, 1);
245
+ rb_define_method(cStatement, "idempotent=", statement_idempotent, 1);
227
246
  }
data/ilios.gemspec CHANGED
@@ -18,6 +18,8 @@ Gem::Specification.new do |spec|
18
18
 
19
19
  spec.metadata['homepage_uri'] = spec.homepage
20
20
  spec.metadata['source_code_uri'] = 'https://github.com/Watson1978/ilios'
21
+ spec.metadata['bug_tracker_uri'] = 'https://github.com/Watson1978/ilios/issues'
22
+ spec.metadata['documentation_uri'] = "https://www.rubydoc.info/gems/ilios/#{Ilios::VERSION}"
21
23
  # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
22
24
  spec.metadata['rubygems_mfa_required'] = 'true'
23
25
 
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.2.1'
4
+ VERSION = '0.3.0'
5
5
  public_constant :VERSION
6
6
 
7
7
  CASSANDRA_CPP_DRIVER_VERSION = '2.17.1'
data/sig/ilios.rbs CHANGED
@@ -1,4 +1,40 @@
1
1
  module Ilios
2
2
  VERSION: String
3
- # See the writing guide of rbs: https://github.com/ruby/rbs#guides
3
+
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
8
+
9
+ class Session
10
+ def prepare_async: (String) -> Ilios::Cassandra::Future
11
+ def prepare: (String) -> Ilios::Cassandra::Statement
12
+
13
+ def execute_async: (Ilios::Cassandra::Statement) -> Ilios::Cassandra::Future
14
+ def execute: (Ilios::Cassandra::Statement) -> Ilios::Cassandra::Result
15
+ end
16
+
17
+ class Statement
18
+ def bind: (Hash[Symbol, untyped] | Hash[String, untyped]) -> self
19
+ def page_size=: (Integer) -> self
20
+ def idempotent=: (true | false) -> self
21
+ end
22
+
23
+ class Future
24
+ def on_success: () { (Ilios::Cassandra::Result) -> void } -> self
25
+ def on_failure: () { () -> void } -> self
26
+ def await: () -> Ilios::Cassandra::Future
27
+ end
28
+
29
+ class Result
30
+ type row_type = Hash[String, untyped]
31
+
32
+ include Enumerable[row_type]
33
+
34
+ def each: () { (row_type) -> void } -> void |
35
+ () -> ::Enumerator[row_type, self]
36
+ def next_page: () -> Ilios::Cassandra::Result |
37
+ () -> nil
38
+ end
39
+ end
4
40
  end
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.2.1
4
+ version: 0.3.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-12 00:00:00.000000000 Z
11
+ date: 2023-11-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: mini_portile2
@@ -57,6 +57,8 @@ licenses:
57
57
  metadata:
58
58
  homepage_uri: https://github.com/Watson1978/ilios
59
59
  source_code_uri: https://github.com/Watson1978/ilios
60
+ bug_tracker_uri: https://github.com/Watson1978/ilios/issues
61
+ documentation_uri: https://www.rubydoc.info/gems/ilios/0.3.0
60
62
  rubygems_mfa_required: 'true'
61
63
  post_install_message:
62
64
  rdoc_options: []