ilios 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
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
+ }