uringmachine 0.31.0 → 0.32.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/benchmark/openssl.rb CHANGED
@@ -81,7 +81,7 @@ end
81
81
  @um.ssl_set_bio(@ssl_conn)
82
82
  @ssl_conn.connect
83
83
 
84
- @conn = @um.connection(@ssl_conn, :ssl)
84
+ @io = @um.io(@ssl_conn)
85
85
 
86
86
  @msg = 'abc' * 1000
87
87
  @msg_newline = @msg + "\n"
@@ -91,15 +91,15 @@ def do_io(ssl)
91
91
  ssl.gets
92
92
  end
93
93
 
94
- def do_io_connection(ssl, um, conn)
94
+ def do_io_io(ssl, um, io)
95
95
  um.ssl_write(ssl, @msg_newline, 0)
96
- conn.read_line(0)
96
+ io.read_line(0)
97
97
  end
98
98
 
99
99
  Benchmark.ips do |x|
100
100
  x.report('stock') { do_io(@ssl_stock) }
101
101
  x.report('UM BIO') { do_io(@ssl_um) }
102
- x.report('UM Stream') { do_io_connection(@ssl_conn, @um, @conn) }
102
+ x.report('UM::IO') { do_io_io(@ssl_conn, @um, @io) }
103
103
 
104
104
  x.compare!(order: :baseline)
105
105
  end
@@ -4,7 +4,7 @@
4
4
  def fiber_switch
5
5
  while true
6
6
  next_fiber, value = @runqueue.shift
7
- return next_fiber.transfer value if next_fiber
7
+ return next_fiber.transfer(value) if next_fiber
8
8
 
9
9
  process_events
10
10
  end
@@ -0,0 +1,16 @@
1
+ require 'uringmachine'
2
+
3
+ machine = UM.new
4
+
5
+ reader = machine.spin {
6
+ input = +''
7
+ machine.read(UM::STDIN_FILENO, input, 256)
8
+ machine.write(UM::STDOUT_FILENO, "Got: #{input}")
9
+ }
10
+
11
+ sleeper = machine.spin {
12
+ machine.sleep(5)
13
+ machine.write(UM::STDOUT_FILENO, "5 seconds have elapsed!")
14
+ }
15
+
16
+ machine.join(reader, sleeper)
@@ -7,6 +7,7 @@ int ret;
7
7
  char buf[100];
8
8
 
9
9
  ret = io_uring_queue_init(8, &ring, 0);
10
+
10
11
  sqe = io_uring_get_sqe(&ring);
11
12
  io_uring_prep_read(sqe, STDIN_FILENO, buf, 100, 0);
12
13
  sqe->user_data = 42;
@@ -14,11 +15,19 @@ io_uring_submit(&ring);
14
15
 
15
16
  ...
16
17
 
17
- ret = io_uring_wait_cqe(&ring, &cqe);
18
- if (!ret) {
18
+ sqe = io_uring_get_sqe(&ring);
19
+ io_uring_prep_cancel(sqe, 42, IORING_ASYNC_CANCEL_USERDATA);
20
+ sqe->flags = IOSQE_CQE_SKIP_SUCCESS;
21
+ io_uring_submit(&ring);
22
+
23
+ if (!io_uring_wait_cqe(&ring, &cqe)) {
19
24
  if (cqe->user_data == 42) {
20
- int len = cqe->res;
21
- printf("Got: %d\n", len);
25
+ if (cqe->res == -ECANCELED)
26
+ printf("Cancelled!\n");
27
+ else {
28
+ int len = cqe->res;
29
+ printf("Got %d bytes\n", len);
30
+ }
22
31
  }
23
32
  io_uring_cqe_seen(&ring, cqe);
24
33
  }
data/examples/pg.rb CHANGED
@@ -66,9 +66,9 @@ $machine.listen(server_fd, UM::SOMAXCONN)
66
66
  puts 'Listening on port 1234'
67
67
 
68
68
  def handle_connection(fd)
69
- conn = UM::Connection.new($machine, fd)
69
+ io = UM::IO.new($machine, fd)
70
70
 
71
- while (l = conn.gets)
71
+ while (l = io.gets)
72
72
  $machine.write(fd, "You said: #{l}")
73
73
  end
74
74
  rescue Exception => e
@@ -0,0 +1,20 @@
1
+ f = machine.spin do
2
+ buf = +''
3
+ machine.read(fd, buf, 256)
4
+ machine.write(UM::STDOUT_FILENO, "Got: #{buf}")
5
+ rescue UM::Terminate
6
+ machine.write(UM::STDOUT_FILENO, "Cancelled")
7
+ end
8
+
9
+ machine.sleep(0.1)
10
+ machine.schedule(f, UM::Terminate.new)
11
+
12
+
13
+
14
+
15
+ # read with timeout
16
+ input = +''
17
+ machine.timeout(timeout, TimeoutError) {
18
+ machine.read(fd, input, 256)
19
+ }
20
+
@@ -0,0 +1,10 @@
1
+ machine = UM.new
2
+ scheduler = UM::FiberScheduler.new(machine)
3
+ Fiber.set_scheduler(scheduler)
4
+
5
+ Fiber.schedule {
6
+ # UringMachine-driven I/O!
7
+ puts "What's your favorite color?"
8
+ color = gets
9
+ puts "Wrong answer: #{color}!"
10
+ }
data/examples/um_io.rb ADDED
@@ -0,0 +1,19 @@
1
+ io = machine.io(fd)
2
+
3
+ # parse an incoming HTTP request
4
+ line = io.read_line(4096)
5
+ m = line.match(/^([a-z]+)\s+([^\s]+)\s+(http\/1\.1)/i)
6
+ headers = {
7
+ ':method' => m[1].downcase,
8
+ ':path' => m[2],
9
+ ':protocol' => m[3].downcase
10
+ }
11
+ while true
12
+ line = io.read_line(4096)
13
+ break if line.empty?
14
+
15
+ m = line.match(/^([a-z0-9\-]+)\:\s+(.+)/i)
16
+ headers[m[1].downcase] = m[2]
17
+ end
18
+
19
+ io.write("HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nfoo")
data/examples/um_mo.c ADDED
@@ -0,0 +1,32 @@
1
+ VALUE um_sleep(struct um *machine, double duration) {
2
+ struct um_op *op = um_op_acquire(machine);
3
+ op->fiber = rb_fiber_current();
4
+ op->ts = um_double_to_timespec(duration);
5
+ struct io_uring_sqe *sqe = um_get_sqe(machine, op);
6
+ io_uring_prep_timeout(sqe, &op->ts, 0, 0);
7
+
8
+ VALUE ret = um_switch(machine);
9
+ if (um_verify_op_completion(machine, op)) ret = DBL2NUM(duration);
10
+ um_op_release(machine, op);
11
+
12
+ RAISE_IF_EXCEPTION(ret);
13
+ return ret;
14
+ }
15
+
16
+ VALUE um_switch(struct um *machine) {
17
+ while (true) {
18
+ struct um_op *op = um_runqueue_shift(machine);
19
+ if (op) return rb_fiber_transfer(op->fiber, 1, &op->value);
20
+
21
+ um_wait_for_and_process_ready_cqes(machine);
22
+ }
23
+ }
24
+
25
+ void um_process_cqe(struct um *machine, struct io_uring_cqe *cqe) {
26
+ struct um_op *op = (struct um_op *)cqe->user_data;
27
+ if (op) {
28
+ op->result.res = cqe->res;
29
+ op->result.flags = cqe->flags;
30
+ um_runqueue_push(machine, op);
31
+ }
32
+ }
@@ -0,0 +1,15 @@
1
+ # singleshot accept
2
+ while (fd = machine.accept(server_fd))
3
+ handle_connection(fd)
4
+ end
5
+
6
+ # multishot accept
7
+ machine.accept_each(server_fd) { handle_connection(it) }
8
+
9
+ # multishot timeout
10
+ machine.periodically(5) { ... }
11
+
12
+ # multishot recv
13
+ machine.recv_each(fd, 0) { |data|
14
+ machine.write(UM::STDOUT_FILENO, "Got: #{data}\n")
15
+ }
@@ -0,0 +1,11 @@
1
+ ssl = OpenSSL::SSL::SSLSocket.new(IO.for_fd(server_fd), server_ctx)
2
+ machine.ssl_set_bio(ssl)
3
+ ssl.accept
4
+
5
+ ssl.write('Hello!')
6
+ # also:
7
+ machine.ssl_write(ssl, 'Hello!')
8
+
9
+ io = machine.io(ssl)
10
+ line = io.read_line(4096)
11
+ ...
data/ext/um/um.h CHANGED
@@ -80,12 +80,12 @@ enum um_op_kind {
80
80
  OP_TIMEOUT_MULTISHOT,
81
81
  };
82
82
 
83
- enum um_connection_mode {
84
- CONNECTION_FD,
85
- CONNECTION_SOCKET,
86
- CONNECTION_SSL,
87
- CONNECTION_STRING,
88
- CONNECTION_IO_BUFFER
83
+ enum um_io_mode {
84
+ IO_FD,
85
+ IO_SOCKET,
86
+ IO_SSL,
87
+ IO_STRING,
88
+ IO_IO_BUFFER
89
89
  };
90
90
 
91
91
  #define OP_F_CQE_SEEN (1U << 0) // CQE has been seen
@@ -272,11 +272,11 @@ struct um_async_op {
272
272
  struct um_op *op;
273
273
  };
274
274
 
275
- struct um_connection {
275
+ struct um_io {
276
276
  VALUE self;
277
277
  struct um *machine;
278
278
 
279
- enum um_connection_mode mode;
279
+ enum um_io_mode mode;
280
280
  union {
281
281
  int fd;
282
282
  VALUE target;
@@ -304,7 +304,7 @@ extern VALUE eUMError;
304
304
  extern VALUE cMutex;
305
305
  extern VALUE cQueue;
306
306
  extern VALUE cAsyncOp;
307
- extern VALUE eConnectionRESPError;
307
+ extern VALUE eIORESPError;
308
308
 
309
309
  struct um *um_get_machine(VALUE self);
310
310
  void um_setup(VALUE self, struct um *machine, uint size, uint sqpoll_timeout_msec, int sidecar_mode);
@@ -438,16 +438,16 @@ VALUE um_queue_pop(struct um *machine, struct um_queue *queue);
438
438
  VALUE um_queue_unshift(struct um *machine, struct um_queue *queue, VALUE value);
439
439
  VALUE um_queue_shift(struct um *machine, struct um_queue *queue);
440
440
 
441
- void connection_teardown(struct um_connection *conn);
442
- void connection_clear(struct um_connection *conn);
443
- VALUE connection_read_line(struct um_connection *conn, VALUE out_buffer, size_t maxlen);
444
- VALUE connection_read(struct um_connection *conn, VALUE out_buffer, ssize_t len, size_t inc, int safe_inc);
445
- VALUE connection_read_to_delim(struct um_connection *conn, VALUE out_buffer, VALUE delim, ssize_t maxlen);
446
- void connection_skip(struct um_connection *conn, size_t inc, int safe_inc);
447
- void connection_read_each(struct um_connection *conn);
448
- size_t connection_write_raw(struct um_connection *conn, const char *buffer, size_t len);
449
- VALUE connection_writev(struct um_connection *conn, int argc, VALUE *argv);
450
- VALUE resp_read(struct um_connection *conn, VALUE out_buffer);
441
+ void io_teardown(struct um_io *io);
442
+ void io_clear(struct um_io *io);
443
+ VALUE io_read_line(struct um_io *io, VALUE out_buffer, size_t maxlen);
444
+ VALUE io_read(struct um_io *io, VALUE out_buffer, ssize_t len, size_t inc, int safe_inc);
445
+ VALUE io_read_to_delim(struct um_io *io, VALUE out_buffer, VALUE delim, ssize_t maxlen);
446
+ void io_skip(struct um_io *io, size_t inc, int safe_inc);
447
+ void io_read_each(struct um_io *io);
448
+ size_t io_write_raw(struct um_io *io, const char *buffer, size_t len);
449
+ VALUE io_writev(struct um_io *io, int argc, VALUE *argv);
450
+ VALUE resp_read(struct um_io *io, VALUE out_buffer);
451
451
  void resp_encode(struct um_write_buffer *buf, VALUE obj);
452
452
  void resp_encode_cmd(struct um_write_buffer *buf, int argc, VALUE *argv);
453
453
 
data/ext/um/um_ext.c CHANGED
@@ -2,14 +2,12 @@ void Init_UM();
2
2
  void Init_Mutex();
3
3
  void Init_Queue();
4
4
  void Init_AsyncOp();
5
- void Init_SSL();
6
- void Init_Stream();
5
+ void Init_IO();
7
6
 
8
7
  void Init_um_ext(void) {
9
8
  Init_UM();
10
9
  Init_Mutex();
11
10
  Init_Queue();
12
11
  Init_AsyncOp();
13
- // Init_SSL();
14
- Init_Stream();
12
+ Init_IO();
15
13
  }