ilios 0.1.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.
data/ext/ilios/ilios.c ADDED
@@ -0,0 +1,107 @@
1
+ #include "ilios.h"
2
+
3
+ VALUE mIlios;
4
+ VALUE mCassandra;
5
+ VALUE cSession;
6
+ VALUE cStatement;
7
+ VALUE cResult;
8
+ VALUE cFuture;
9
+ VALUE eConnectError;
10
+ VALUE eExecutionError;
11
+ VALUE eStatementError;
12
+
13
+ VALUE cQueue;
14
+
15
+ VALUE id_cvar_config;
16
+ VALUE id_shuffle;
17
+ VALUE id_to_time;
18
+ VALUE id_abort_on_exception_set;
19
+ VALUE id_new;
20
+ VALUE id_push;
21
+ VALUE id_pop;
22
+ VALUE sym_unsupported_column_type;
23
+ VALUE sym_keyspace;
24
+ VALUE sym_hosts;
25
+ VALUE sym_timeout_ms;
26
+ VALUE sym_constant_delay_ms;
27
+ VALUE sym_max_speculative_executions;
28
+ VALUE sym_page_size;
29
+
30
+ #if defined(HAVE_MALLOC_USABLE_SIZE)
31
+ #include <malloc.h>
32
+ #elif defined(HAVE_MALLOC_SIZE)
33
+ #include <malloc/malloc.h>
34
+ #endif
35
+
36
+ static ssize_t ilios_malloc_size(void *ptr)
37
+ {
38
+ #if defined(HAVE_MALLOC_USABLE_SIZE)
39
+ return malloc_usable_size(ptr);
40
+ #elif defined(HAVE_MALLOC_SIZE)
41
+ return malloc_size(ptr);
42
+ #endif
43
+ }
44
+
45
+ static void *ilios_malloc(size_t size)
46
+ {
47
+ rb_gc_adjust_memory_usage(size);
48
+ return malloc(size);
49
+ }
50
+
51
+ static void *ilios_realloc(void *ptr, size_t size)
52
+ {
53
+ ssize_t before_size = ilios_malloc_size(ptr);
54
+ rb_gc_adjust_memory_usage(size - before_size);
55
+ return realloc(ptr, size);
56
+ }
57
+
58
+ static void ilios_free(void *ptr)
59
+ {
60
+ if (ptr) {
61
+ ssize_t size = ilios_malloc_size(ptr);
62
+ rb_gc_adjust_memory_usage(-size);
63
+ free(ptr);
64
+ }
65
+ }
66
+
67
+ void Init_ilios(void)
68
+ {
69
+ mIlios = rb_define_module("Ilios");
70
+ mCassandra = rb_define_module_under(mIlios, "Cassandra");
71
+ cSession = rb_define_class_under(mCassandra, "Session", rb_cObject);
72
+ cStatement = rb_define_class_under(mCassandra, "Statement", rb_cObject);
73
+ cResult = rb_define_class_under(mCassandra, "Result", rb_cObject);
74
+ cFuture = rb_define_class_under(mCassandra, "Future", rb_cObject);
75
+ eConnectError = rb_define_class_under(mCassandra, "ConnectError", rb_eStandardError);
76
+ eExecutionError = rb_define_class_under(mCassandra, "ExecutionError", rb_eStandardError);
77
+ eStatementError = rb_define_class_under(mCassandra, "StatementError", rb_eStandardError);
78
+
79
+ cQueue = rb_const_get(rb_cThread, rb_intern("Queue"));
80
+
81
+ id_cvar_config = rb_intern("@@config");
82
+ id_shuffle = rb_intern("shuffle");
83
+ id_to_time = rb_intern("to_time");
84
+ id_abort_on_exception_set = rb_intern("abort_on_exception=");
85
+ id_new = rb_intern("new");
86
+ id_push = rb_intern("push");
87
+ id_pop = rb_intern("pop");
88
+ sym_unsupported_column_type = ID2SYM(rb_intern("unsupported_column_type"));
89
+ sym_keyspace = ID2SYM(rb_intern("keyspace"));
90
+ sym_hosts = ID2SYM(rb_intern("hosts"));
91
+ sym_timeout_ms = ID2SYM(rb_intern("timeout_ms"));
92
+ sym_constant_delay_ms = ID2SYM(rb_intern("constant_delay_ms"));
93
+ sym_max_speculative_executions = ID2SYM(rb_intern("max_speculative_executions"));
94
+ sym_page_size = ID2SYM(rb_intern("page_size"));
95
+
96
+ Init_cassandra();
97
+ Init_session();
98
+ Init_statement();
99
+ Init_result();
100
+ Init_future();
101
+
102
+ cass_log_set_level(CASS_LOG_ERROR);
103
+
104
+ #if defined(HAVE_MALLOC_USABLE_SIZE) || defined(HAVE_MALLOC_SIZE)
105
+ cass_alloc_set_functions(ilios_malloc, ilios_realloc, ilios_free);
106
+ #endif
107
+ }
data/ext/ilios/ilios.h ADDED
@@ -0,0 +1,105 @@
1
+ #ifndef ILIOS_H
2
+ #define ILIOS_H
3
+
4
+ #include <stdint.h>
5
+ #include <float.h>
6
+ #include <cassandra.h>
7
+ #include <uv.h>
8
+ #include "ruby.h"
9
+ #include "ruby/thread.h"
10
+
11
+ #define GET_SESSION(obj, var) TypedData_Get_Struct(obj, CassandraSession, &cassandra_session_data_type, var)
12
+ #define GET_STATEMENT(obj, var) TypedData_Get_Struct(obj, CassandraStatement, &cassandra_statement_data_type, var)
13
+ #define GET_RESULT(obj, var) TypedData_Get_Struct(obj, CassandraResult, &cassandra_result_data_type, var)
14
+ #define GET_FUTURE(obj, var) TypedData_Get_Struct(obj, CassandraFuture, &cassandra_future_data_type, var)
15
+ #define CREATE_SESSION(var) TypedData_Make_Struct(cSession, CassandraSession, &cassandra_session_data_type, var)
16
+ #define CREATE_STATEMENT(var) TypedData_Make_Struct(cStatement, CassandraStatement, &cassandra_statement_data_type, var)
17
+ #define CREATE_RESULT(var) TypedData_Make_Struct(cResult, CassandraResult, &cassandra_result_data_type, var)
18
+ #define CREATE_FUTURE(var) TypedData_Make_Struct(cFuture, CassandraFuture, &cassandra_future_data_type, var)
19
+
20
+ typedef enum {
21
+ prepare_async,
22
+ execute_async
23
+ } future_kind;
24
+
25
+ typedef struct
26
+ {
27
+ CassCluster* cluster;
28
+ CassFuture* connect_future;
29
+ CassSession* session;
30
+
31
+ } CassandraSession;
32
+
33
+ typedef struct
34
+ {
35
+ CassStatement* statement;
36
+ const CassPrepared* prepared;
37
+ VALUE session_obj;
38
+ } CassandraStatement;
39
+
40
+ typedef struct
41
+ {
42
+ const CassResult *result;
43
+ CassFuture *future;
44
+ VALUE statement_obj;
45
+ } CassandraResult;
46
+
47
+ typedef struct
48
+ {
49
+ CassFuture *future;
50
+ future_kind kind;
51
+
52
+ VALUE session_obj;
53
+ VALUE statement_obj;
54
+ VALUE on_success_block;
55
+ VALUE on_failure_block;
56
+ VALUE proc_mutex;
57
+ } CassandraFuture;
58
+
59
+ extern const rb_data_type_t cassandra_session_data_type;
60
+ extern const rb_data_type_t cassandra_statement_data_type;
61
+ extern const rb_data_type_t cassandra_result_data_type;
62
+ extern const rb_data_type_t cassandra_future_data_type;
63
+
64
+ extern VALUE mIlios;
65
+ extern VALUE mCassandra;
66
+ extern VALUE cSession;
67
+ extern VALUE cStatement;
68
+ extern VALUE cResult;
69
+ extern VALUE cFuture;
70
+ extern VALUE eConnectError;
71
+ extern VALUE eExecutionError;
72
+ extern VALUE eStatementError;
73
+
74
+ extern VALUE cQueue;
75
+
76
+ extern VALUE id_cvar_config;
77
+ extern VALUE id_shuffle;
78
+ extern VALUE id_to_time;
79
+ extern VALUE id_abort_on_exception_set;
80
+ extern VALUE id_new;
81
+ extern VALUE id_push;
82
+ extern VALUE id_pop;
83
+ extern VALUE sym_unsupported_column_type;
84
+ extern VALUE sym_keyspace;
85
+ extern VALUE sym_hosts;
86
+ extern VALUE sym_timeout_ms;
87
+ extern VALUE sym_constant_delay_ms;
88
+ extern VALUE sym_max_speculative_executions;
89
+ extern VALUE sym_page_size;
90
+
91
+ extern void Init_cassandra(void);
92
+ extern void Init_session(void);
93
+ extern void Init_statement(void);
94
+ extern void Init_result(void);
95
+ extern void Init_future(void);
96
+
97
+ extern void nogvl_future_wait(CassFuture *future);
98
+ extern CassFuture *nogvl_session_prepare(CassSession* session, VALUE query);
99
+ extern CassFuture *nogvl_session_execute(CassSession* session, CassStatement* statement);
100
+
101
+ extern void statement_default_config(CassandraStatement *cassandra_statement);
102
+ extern void result_await(CassandraResult *cassandra_result);
103
+
104
+
105
+ #endif // ILIOS_H
data/ext/ilios/nogvl.c ADDED
@@ -0,0 +1,53 @@
1
+ #include "ilios.h"
2
+
3
+ typedef struct {
4
+ CassSession* session;
5
+ const char *query;
6
+ } nogvl_session_prepare_args;
7
+
8
+ typedef struct {
9
+ CassSession* session;
10
+ CassStatement* statement;
11
+ } nogvl_session_execute_args;
12
+
13
+ static void *nogvl_future_wait_cb(void *ptr)
14
+ {
15
+ CassFuture *future = (CassFuture *)ptr;
16
+ cass_future_wait(future);
17
+ return NULL;
18
+ }
19
+
20
+ void nogvl_future_wait(CassFuture *future)
21
+ {
22
+ rb_thread_call_without_gvl(nogvl_future_wait_cb, future, RUBY_UBF_PROCESS, 0);
23
+ }
24
+
25
+ static void *nogvl_session_prepare_cb(void *ptr)
26
+ {
27
+ nogvl_session_prepare_args *args = (nogvl_session_prepare_args *)ptr;
28
+ CassFuture *prepare_future;
29
+
30
+ prepare_future = cass_session_prepare(args->session, args->query);
31
+ return (void *)prepare_future;
32
+ }
33
+
34
+ CassFuture *nogvl_session_prepare(CassSession* session, VALUE query)
35
+ {
36
+ nogvl_session_prepare_args args = { session, StringValueCStr(query) };
37
+ return (CassFuture *)rb_thread_call_without_gvl(nogvl_session_prepare_cb, &args, RUBY_UBF_PROCESS, 0);
38
+ }
39
+
40
+ static void *nogvl_session_execute_cb(void *ptr)
41
+ {
42
+ nogvl_session_execute_args *args = (nogvl_session_execute_args *)ptr;
43
+ CassFuture *result_future;
44
+
45
+ result_future = cass_session_execute(args->session, args->statement);
46
+ return (void *)result_future;
47
+ }
48
+
49
+ CassFuture *nogvl_session_execute(CassSession* session, CassStatement* statement)
50
+ {
51
+ nogvl_session_execute_args args = { session, statement };
52
+ return (CassFuture *)rb_thread_call_without_gvl(nogvl_session_execute_cb, &args, RUBY_UBF_PROCESS, 0);
53
+ }
@@ -0,0 +1,239 @@
1
+ #include "ilios.h"
2
+
3
+ static void result_mark(void *ptr);
4
+ static void result_destroy(void *ptr);
5
+ static size_t result_memsize(const void *ptr);
6
+ static void result_compact(void *ptr);
7
+
8
+ const rb_data_type_t cassandra_result_data_type = {
9
+ "Ilios::Cassandra::Result",
10
+ {
11
+ result_mark,
12
+ result_destroy,
13
+ result_memsize,
14
+ result_compact,
15
+ },
16
+ 0, 0,
17
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
18
+ };
19
+
20
+ void result_await(CassandraResult *cassandra_result)
21
+ {
22
+ nogvl_future_wait(cassandra_result->future);
23
+
24
+ if (cass_future_error_code(cassandra_result->future) != CASS_OK) {
25
+ char error[4096] = { 0 };
26
+
27
+ strncpy(error, cass_error_desc(cass_future_error_code(cassandra_result->future)), sizeof(error) - 1);
28
+ rb_raise(eExecutionError, "Unable to wait executing: %s", error);
29
+ }
30
+
31
+ if (cassandra_result->result == NULL) {
32
+ cassandra_result->result = cass_future_get_result(cassandra_result->future);
33
+ }
34
+ }
35
+
36
+ static VALUE result_next_page(VALUE self)
37
+ {
38
+ CassandraResult *cassandra_result;
39
+ CassandraStatement *cassandra_statement;
40
+ CassandraSession *cassandra_session;
41
+ CassFuture *result_future;
42
+
43
+ GET_RESULT(self, cassandra_result);
44
+
45
+ if (cass_result_has_more_pages(cassandra_result->result) == cass_false) {
46
+ return Qnil;
47
+ }
48
+
49
+ GET_STATEMENT(cassandra_result->statement_obj, cassandra_statement);
50
+ GET_SESSION(cassandra_statement->session_obj, cassandra_session);
51
+
52
+ cass_statement_set_paging_state(cassandra_statement->statement, cassandra_result->result);
53
+
54
+ result_future = nogvl_session_execute(cassandra_session->session, cassandra_statement->statement);
55
+
56
+ cass_result_free(cassandra_result->result);
57
+ cass_future_free(cassandra_result->future);
58
+ cassandra_result->result = NULL;
59
+ cassandra_result->future = result_future;
60
+
61
+ result_await(cassandra_result);
62
+ return self;
63
+ }
64
+
65
+ static VALUE result_convert_row(const CassResult *result, const CassRow *row, size_t column_count)
66
+ {
67
+ VALUE key;
68
+ const char *name;
69
+ size_t name_length;
70
+ VALUE hash = rb_hash_new();
71
+
72
+ for (size_t i = 0; i < column_count; i++) {
73
+ const CassValue *value = cass_row_get_column(row, i);
74
+ const CassValueType type = cass_value_type(value);
75
+
76
+ cass_result_column_name(result, i, &name, &name_length);
77
+ key = rb_str_new(name, name_length);
78
+
79
+ if (cass_value_is_null(value)) {
80
+ rb_hash_aset(hash, key, Qnil);
81
+ continue;
82
+ }
83
+
84
+ switch (type) {
85
+ case CASS_VALUE_TYPE_TINY_INT:
86
+ {
87
+ cass_int8_t output;
88
+ cass_value_get_int8(value, &output);
89
+ rb_hash_aset(hash, key, INT2NUM(output));
90
+ }
91
+ break;
92
+
93
+ case CASS_VALUE_TYPE_SMALL_INT:
94
+ {
95
+ cass_int16_t output;
96
+ cass_value_get_int16(value, &output);
97
+ rb_hash_aset(hash, key, INT2NUM(output));
98
+ }
99
+ break;
100
+
101
+ case CASS_VALUE_TYPE_INT:
102
+ {
103
+ cass_int32_t output;
104
+ cass_value_get_int32(value, &output);
105
+ rb_hash_aset(hash, key, INT2NUM(output));
106
+ }
107
+ break;
108
+
109
+ case CASS_VALUE_TYPE_BIGINT:
110
+ {
111
+ cass_int64_t output;
112
+ cass_value_get_int64(value, &output);
113
+ rb_hash_aset(hash, key, LL2NUM(output));
114
+ }
115
+ break;
116
+
117
+ case CASS_VALUE_TYPE_FLOAT:
118
+ {
119
+ cass_float_t output;
120
+ cass_value_get_float(value, &output);
121
+ rb_hash_aset(hash, key, DBL2NUM(output));
122
+ }
123
+ break;
124
+
125
+ case CASS_VALUE_TYPE_DOUBLE:
126
+ {
127
+ cass_double_t output;
128
+ cass_value_get_double(value, &output);
129
+ rb_hash_aset(hash, key, DBL2NUM(output));
130
+ }
131
+ break;
132
+
133
+ case CASS_VALUE_TYPE_BOOLEAN:
134
+ {
135
+ cass_bool_t output;
136
+ cass_value_get_bool(value, &output);
137
+ rb_hash_aset(hash, key, output == cass_true ? Qtrue : Qfalse);
138
+ }
139
+ break;
140
+
141
+ case CASS_VALUE_TYPE_TEXT:
142
+ case CASS_VALUE_TYPE_ASCII:
143
+ case CASS_VALUE_TYPE_VARCHAR:
144
+ {
145
+ const char* s;
146
+ size_t s_length;
147
+ cass_value_get_string(value, &s, &s_length);
148
+ rb_hash_aset(hash, key, rb_str_new(s, s_length));
149
+ }
150
+ break;
151
+
152
+ case CASS_VALUE_TYPE_TIMESTAMP:
153
+ {
154
+ cass_int64_t output;
155
+ cass_value_get_int64(value, &output);
156
+ rb_hash_aset(hash, key, rb_time_new(output / 1000, output % 1000 * 1000));
157
+ }
158
+ break;
159
+
160
+ case CASS_VALUE_TYPE_UUID:
161
+ {
162
+ CassUuid output;
163
+ char uuid[40];
164
+ cass_value_get_uuid(value, &output);
165
+ cass_uuid_string(output, uuid);
166
+ rb_hash_aset(hash, key, rb_str_new2(uuid));
167
+ }
168
+ break;
169
+
170
+ default:
171
+ rb_warn("Unsupported type: %d", type);
172
+ rb_hash_aset(hash, key, sym_unsupported_column_type);
173
+ }
174
+ }
175
+
176
+ return hash;
177
+ }
178
+
179
+ static VALUE result_each(VALUE self)
180
+ {
181
+ CassandraResult *cassandra_result;
182
+ CassIterator *iterator;
183
+ size_t column_count;
184
+
185
+ RETURN_ENUMERATOR(self, 0, 0);
186
+
187
+ GET_RESULT(self, cassandra_result);
188
+
189
+ iterator = cass_iterator_from_result(cassandra_result->result);
190
+ column_count = cass_result_column_count(cassandra_result->result);
191
+ while (cass_iterator_next(iterator)) {
192
+ const CassRow *row = cass_iterator_get_row(iterator);
193
+ rb_yield(result_convert_row(cassandra_result->result, row, column_count));
194
+ }
195
+ cass_iterator_free(iterator);
196
+
197
+ return self;
198
+ }
199
+
200
+ static void result_mark(void *ptr)
201
+ {
202
+ CassandraResult *cassandra_result = (CassandraResult *)ptr;
203
+ rb_gc_mark_movable(cassandra_result->statement_obj);
204
+ }
205
+
206
+ static void result_destroy(void *ptr)
207
+ {
208
+ CassandraResult *cassandra_result = (CassandraResult *)ptr;
209
+
210
+ if (cassandra_result->result) {
211
+ cass_result_free(cassandra_result->result);
212
+ }
213
+ if (cassandra_result->future) {
214
+ cass_future_free(cassandra_result->future);
215
+ }
216
+ xfree(cassandra_result);
217
+ }
218
+
219
+ static size_t result_memsize(const void *ptr)
220
+ {
221
+ return sizeof(CassandraResult);
222
+ }
223
+
224
+ static void result_compact(void *ptr)
225
+ {
226
+ CassandraResult *cassandra_result = (CassandraResult *)ptr;
227
+
228
+ cassandra_result->statement_obj = rb_gc_location(cassandra_result->statement_obj);
229
+ }
230
+
231
+ void Init_result(void)
232
+ {
233
+ rb_undef_alloc_func(cResult);
234
+
235
+ rb_include_module(cResult, rb_mEnumerable);
236
+
237
+ rb_define_method(cResult, "next_page", result_next_page, 0);
238
+ rb_define_method(cResult, "each", result_each, 0);
239
+ }
@@ -0,0 +1,145 @@
1
+ #include "ilios.h"
2
+
3
+ static void session_destroy(void *ptr);
4
+ static size_t session_memsize(const void *ptr);
5
+
6
+ const rb_data_type_t cassandra_session_data_type = {
7
+ "Ilios::Cassandra::Session",
8
+ {
9
+ NULL,
10
+ session_destroy,
11
+ session_memsize,
12
+ NULL,
13
+ },
14
+ 0, 0,
15
+ RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE,
16
+ };
17
+
18
+ static VALUE session_prepare_async(VALUE self, VALUE query)
19
+ {
20
+ CassandraSession *cassandra_session;
21
+ CassandraFuture *cassandra_future;
22
+ CassFuture *prepare_future;
23
+ VALUE cassandra_future_obj;
24
+
25
+ GET_SESSION(self, cassandra_session);
26
+
27
+ prepare_future = nogvl_session_prepare(cassandra_session->session, query);
28
+
29
+ cassandra_future_obj = CREATE_FUTURE(cassandra_future);
30
+ cassandra_future->kind = prepare_async;
31
+ cassandra_future->future = prepare_future;
32
+ cassandra_future->session_obj = self;
33
+ cassandra_future->proc_mutex = rb_mutex_new();
34
+
35
+ return cassandra_future_obj;
36
+ }
37
+
38
+ static VALUE session_prepare(VALUE self, VALUE query)
39
+ {
40
+ CassandraSession *cassandra_session;
41
+ CassandraStatement *cassandra_statement;
42
+ CassFuture *prepare_future;
43
+ VALUE cassandra_statement_obj;
44
+
45
+ GET_SESSION(self, cassandra_session);
46
+
47
+ prepare_future = nogvl_session_prepare(cassandra_session->session, query);
48
+ nogvl_future_wait(prepare_future);
49
+
50
+ if (cass_future_error_code(prepare_future) != CASS_OK) {
51
+ char error[4096] = { 0 };
52
+
53
+ strncpy(error, cass_error_desc(cass_future_error_code(prepare_future)), sizeof(error) - 1);
54
+ cass_future_free(prepare_future);
55
+ rb_raise(eExecutionError, "Unable to prepare query: %s", error);
56
+ }
57
+
58
+ cassandra_statement_obj = CREATE_STATEMENT(cassandra_statement);
59
+
60
+ cassandra_statement->prepared = cass_future_get_prepared(prepare_future);
61
+ cassandra_statement->statement = cass_prepared_bind(cassandra_statement->prepared);
62
+ cassandra_statement->session_obj = self;
63
+ cass_future_free(prepare_future);
64
+
65
+ statement_default_config(cassandra_statement);
66
+ return cassandra_statement_obj;
67
+ }
68
+
69
+ static VALUE session_execute_async(VALUE self, VALUE statement)
70
+ {
71
+ CassandraSession *cassandra_session;
72
+ CassandraStatement *cassandra_statement;
73
+ CassandraFuture *cassandra_future;
74
+ CassFuture *result_future;
75
+ VALUE cassandra_future_obj;
76
+
77
+ GET_SESSION(self, cassandra_session);
78
+ GET_STATEMENT(statement, cassandra_statement);
79
+
80
+ result_future = nogvl_session_execute(cassandra_session->session, cassandra_statement->statement);
81
+
82
+ cassandra_future_obj = CREATE_FUTURE(cassandra_future);
83
+ cassandra_future->kind = execute_async;
84
+ cassandra_future->future = result_future;
85
+ cassandra_future->session_obj = self;
86
+ cassandra_future->statement_obj = statement;
87
+ cassandra_future->proc_mutex = rb_mutex_new();
88
+
89
+ return cassandra_future_obj;
90
+ }
91
+
92
+ static VALUE session_execute(VALUE self, VALUE statement)
93
+ {
94
+ CassandraSession *cassandra_session;
95
+ CassandraStatement *cassandra_statement;
96
+ CassandraResult *cassandra_result;
97
+ CassFuture *result_future;
98
+ VALUE cassandra_result_obj;
99
+
100
+ GET_SESSION(self, cassandra_session);
101
+ GET_STATEMENT(statement, cassandra_statement);
102
+
103
+ result_future = nogvl_session_execute(cassandra_session->session, cassandra_statement->statement);
104
+
105
+ cassandra_result_obj = CREATE_RESULT(cassandra_result);
106
+ cassandra_result->future = result_future;
107
+ cassandra_result->statement_obj = statement;
108
+
109
+ result_await(cassandra_result);
110
+ return cassandra_result_obj;
111
+ }
112
+
113
+ static void session_destroy(void *ptr)
114
+ {
115
+ CassandraSession *cassandra_session = (CassandraSession *)ptr;
116
+
117
+ if (cassandra_session->session) {
118
+ CassFuture *close_future = cass_session_close(cassandra_session->session);
119
+ nogvl_future_wait(close_future);
120
+ cass_future_free(close_future);
121
+ cass_session_free(cassandra_session->session);
122
+ }
123
+ if (cassandra_session->connect_future) {
124
+ cass_future_free(cassandra_session->connect_future);
125
+ }
126
+ if (cassandra_session->cluster) {
127
+ cass_cluster_free(cassandra_session->cluster);
128
+ }
129
+ xfree(cassandra_session);
130
+ }
131
+
132
+ static size_t session_memsize(const void *ptr)
133
+ {
134
+ return sizeof(CassandraSession);
135
+ }
136
+
137
+ void Init_session(void)
138
+ {
139
+ rb_undef_alloc_func(cSession);
140
+
141
+ rb_define_method(cSession, "prepare_async", session_prepare_async, 1);
142
+ rb_define_method(cSession, "prepare", session_prepare, 1);
143
+ rb_define_method(cSession, "execute_async", session_execute_async, 1);
144
+ rb_define_method(cSession, "execute", session_execute, 1);
145
+ }