ilios 0.2.2 → 0.3.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: da0825a11d636371afff56064fc1ddb2b0fd84aaf0ba4df4e97332c86c1fbbb4
4
- data.tar.gz: feb98bba30efe3721863a14bb0908dc5142f816e22a518e664a70aa404b28fbb
3
+ metadata.gz: b5dee1fc3383cb4e1c7ee917e6b582456b02ef3e1121ca62b65ad5f94e827706
4
+ data.tar.gz: c6f7a9a6ae097cc74a644ec2d1d4d1b8fadcfc09697db4a537ab6e500ed8e6ef
5
5
  SHA512:
6
- metadata.gz: 98a3734820e16361379119139df42a51e003789cc29e8afb1a9d18632143490cadf9c42db6a5b888d7ef0c2f9d7d6a3838b02cdc55d03b659c23fecda8648065
7
- data.tar.gz: 66905094f787fda845e1aa4bff7131a2e666df4530f74726034a8b6b9c2467e0243eb77f5b472136bebf8749ad58df2e134f7d7044814d3bbd5195ec0b80c293
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
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.metadata['homepage_uri'] = spec.homepage
20
20
  spec.metadata['source_code_uri'] = 'https://github.com/Watson1978/ilios'
21
21
  spec.metadata['bug_tracker_uri'] = 'https://github.com/Watson1978/ilios/issues'
22
- spec.metadata['documentation_uri'] = 'https://www.rubydoc.info/gems/ilios'
22
+ spec.metadata['documentation_uri'] = "https://www.rubydoc.info/gems/ilios/#{Ilios::VERSION}"
23
23
  # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
24
24
  spec.metadata['rubygems_mfa_required'] = 'true'
25
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.2'
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.2
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-13 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
@@ -58,7 +58,7 @@ metadata:
58
58
  homepage_uri: https://github.com/Watson1978/ilios
59
59
  source_code_uri: https://github.com/Watson1978/ilios
60
60
  bug_tracker_uri: https://github.com/Watson1978/ilios/issues
61
- documentation_uri: https://www.rubydoc.info/gems/ilios
61
+ documentation_uri: https://www.rubydoc.info/gems/ilios/0.3.0
62
62
  rubygems_mfa_required: 'true'
63
63
  post_install_message:
64
64
  rdoc_options: []