itsi-scheduler 0.2.10 → 0.2.11
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 +4 -4
- data/Cargo.lock +1 -1
- data/ext/itsi_scheduler/Cargo.toml +1 -1
- data/ext/itsi_server/Cargo.toml +1 -1
- data/ext/itsi_server/src/lib.rs +2 -0
- data/ext/itsi_server/src/ruby_types/itsi_http_response.rs +8 -0
- data/lib/itsi/scheduler/version.rb +1 -1
- data/lib/itsi/scheduler.rb +28 -0
- metadata +1 -2
- data/README.md +0 -76
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c057b5de1665276930d7c09f81ccc6e1b81419cf7cd9a4b3c04a08d3b6d0976d
|
4
|
+
data.tar.gz: 32fb526429c78f471eb248d3800dff138e7021aec6f95b13ee30ff4a4297a570
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c2304a02521484da65165d2f08632d9b52be536246ccefb5993b1715e7adcbe6cbc42fda820dffcd1e10bb1082b93ca9317e7aec6205cdfb735b3a6c933a63d5
|
7
|
+
data.tar.gz: d1c3f48ba6ba4c71694a5e0ee3f72ebb2b4229bbf4fe4cde8756ec5d6ed4d1c971c6e1e791c36b1f3ee7816e2db0a712aa70704b9c77ad9d2695021829c769c8
|
data/Cargo.lock
CHANGED
data/ext/itsi_server/Cargo.toml
CHANGED
data/ext/itsi_server/src/lib.rs
CHANGED
@@ -86,6 +86,8 @@ fn init(ruby: &Ruby) -> Result<()> {
|
|
86
86
|
response.define_method("<<", method!(ItsiHttpResponse::send_frame, 1))?;
|
87
87
|
response.define_method("write", method!(ItsiHttpResponse::send_frame, 1))?;
|
88
88
|
response.define_method("read", method!(ItsiHttpResponse::recv_frame, 0))?;
|
89
|
+
response.define_method("flush", method!(ItsiHttpResponse::flush, 0))?;
|
90
|
+
response.define_method("closed?", method!(ItsiHttpResponse::is_closed, 0))?;
|
89
91
|
response.define_method(
|
90
92
|
"send_and_close",
|
91
93
|
method!(ItsiHttpResponse::send_and_close, 1),
|
@@ -272,6 +272,14 @@ impl ItsiHttpResponse {
|
|
272
272
|
// not implemented
|
273
273
|
}
|
274
274
|
|
275
|
+
pub fn flush(&self) {
|
276
|
+
// no-op
|
277
|
+
}
|
278
|
+
|
279
|
+
pub fn is_closed(&self) -> bool {
|
280
|
+
self.data.response_writer.write().is_none()
|
281
|
+
}
|
282
|
+
|
275
283
|
pub fn send_and_close(&self, frame: Bytes) -> MagnusResult<()> {
|
276
284
|
let result = self.send_frame_into(ByteFrame::End(frame), &self.data.response_writer);
|
277
285
|
self.data.response_writer.write().take();
|
data/lib/itsi/scheduler.rb
CHANGED
@@ -4,7 +4,35 @@ require_relative "scheduler/version"
|
|
4
4
|
require_relative "scheduler/itsi_scheduler"
|
5
5
|
|
6
6
|
module Itsi
|
7
|
+
module ScheduleUtils
|
8
|
+
def schedule(&block)
|
9
|
+
return to_enum(:schedule) unless block_given?
|
10
|
+
|
11
|
+
Object.schedule do
|
12
|
+
each { |item| Object.schedule { block.call(item) } }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
7
17
|
class Scheduler
|
18
|
+
def self.enable_schedule_keyword!
|
19
|
+
Object.define_method(:schedule) do |&blk|
|
20
|
+
result = nil
|
21
|
+
return result unless blk
|
22
|
+
|
23
|
+
if Fiber.scheduler.nil?
|
24
|
+
Thread.new do
|
25
|
+
Fiber.set_scheduler Itsi::Scheduler.new
|
26
|
+
Fiber.schedule { result = blk[] }
|
27
|
+
end.join
|
28
|
+
else
|
29
|
+
Fiber.schedule { result = blk[] }
|
30
|
+
end
|
31
|
+
result
|
32
|
+
end
|
33
|
+
Enumerable.include(ScheduleUtils)
|
34
|
+
end
|
35
|
+
|
8
36
|
class Error < StandardError; end
|
9
37
|
|
10
38
|
def self.resume_token
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: itsi-scheduler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wouter Coppieters
|
@@ -35,7 +35,6 @@ files:
|
|
35
35
|
- ".rubocop.yml"
|
36
36
|
- Cargo.lock
|
37
37
|
- Cargo.toml
|
38
|
-
- README.md
|
39
38
|
- Rakefile
|
40
39
|
- ext/itsi_acme/Cargo.toml
|
41
40
|
- ext/itsi_acme/examples/high_level.rs
|
data/README.md
DELETED
@@ -1,76 +0,0 @@
|
|
1
|
-
---
|
2
|
-
title: Itsi Scheduler
|
3
|
-
type: docs
|
4
|
-
weight: 4
|
5
|
-
sidebar:
|
6
|
-
exclude: true
|
7
|
-
---
|
8
|
-
<img src="itsi-scheduler-100.png" width="80px" style="display: block; margin-left: auto; margin-right: auto;">
|
9
|
-
|
10
|
-
`Itsi Scheduler` is an implementation of a Ruby [Fiber Scheduler](https://docs.ruby-lang.org/en/3.2/Fiber/Scheduler.html).
|
11
|
-
|
12
|
-
When combined with Itsi Server, you can write endpoints that look just like regular synchronous Ruby code. Behind the scenes, the scheduler will transparently pause and resume fibers to prevent threads from blocking, greatly increasing throughput for I/O-heavy workloads
|
13
|
-
|
14
|
-
If you're purely after a lightweight, yet efficient Ruby scheduler,
|
15
|
-
you can use Itsi Scheduler as a standalone scheduler for any Ruby application.
|
16
|
-
|
17
|
-
Just use `Fiber.set_scheduler` to set an instance `Itsi::Scheduler` as a scheduler to opt in to this IO weaving behavior
|
18
|
-
*automatically* for all blocking IO.
|
19
|
-
|
20
|
-
### Primer on Fiber Schedulers
|
21
|
-
|
22
|
-
Fiber schedulers are a way to automatically manage the execution of non-blocking fibers in Ruby. A scheduler is responsible for the automatic pausing and resumption of Fibers based
|
23
|
-
on whether or not they are awaiting IO operations.
|
24
|
-
Ruby's Fiber scheduler implementation automatically invokes the current Fiber scheduler (if it exists) for each blocking operation, allowing it to seamlessly drive the execution of huge numbers of simultaneous non-blocking fibers
|
25
|
-
while ensuring the main thread is never blocked on IO.
|
26
|
-
|
27
|
-
This behind the scenes magic allows Ruby to provide async IO (just like we find in languages with `async/await` like `Rust`, `C#`, `JavaScript`) *but* with the added beauty
|
28
|
-
that synchronous and asynchronous code is identical! (I.e. Ruby's functions are [colorless](https://journal.stuffwithstuff.com/2015/02/01/what-color-is-your-function/))
|
29
|
-
|
30
|
-
## Getting Started
|
31
|
-
To install and use Itsi Scheduler follow the instructions below:
|
32
|
-
|
33
|
-
|
34
|
-
### 1 - Install Itsi Scheduler
|
35
|
-
|
36
|
-
**Prerequisites**
|
37
|
-
|
38
|
-
You'll need at least `build-essential` and `libclang-dev` installed to build Itsi on Linux.
|
39
|
-
E.g.
|
40
|
-
```bash
|
41
|
-
apt-get install build-essential libclang-dev
|
42
|
-
```
|
43
|
-
|
44
|
-
Then use `gem` to install the Itsi package. This will in turn install both the
|
45
|
-
`itsi-server` gem, and the `itsi-scheduler` gem.
|
46
|
-
|
47
|
-
|
48
|
-
```bash
|
49
|
-
gem install itsi-scheduler
|
50
|
-
```
|
51
|
-
|
52
|
-
|
53
|
-
### 2 - Use Itsi Scheduler
|
54
|
-
|
55
|
-
Great! You now have Itsi Scheduler installed.
|
56
|
-
Now you can run code like this:
|
57
|
-
|
58
|
-
```ruby
|
59
|
-
require 'itsi/scheduler'
|
60
|
-
require 'socket'
|
61
|
-
results = Thread.new do
|
62
|
-
Fiber.set_scheduler Itsi::Scheduler.new
|
63
|
-
results = []
|
64
|
-
Fiber.schedule do
|
65
|
-
results << Addrinfo.getaddrinfo("www.ruby-lang.org", 80, nil, :STREAM)
|
66
|
-
end
|
67
|
-
Fiber.schedule do
|
68
|
-
results << Addrinfo.getaddrinfo("www.google.com", 80, nil, :STREAM)
|
69
|
-
end
|
70
|
-
results
|
71
|
-
end.value
|
72
|
-
|
73
|
-
puts results.map(&:inspect)
|
74
|
-
```
|
75
|
-
|
76
|
-
to run many blocking operations simultaneously all while occupying only a single Ruby thread!
|