polyphony 0.29 → 0.30

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +14 -0
  4. data/Gemfile.lock +1 -1
  5. data/TODO.md +15 -10
  6. data/docs/getting-started/tutorial.md +3 -3
  7. data/docs/index.md +2 -3
  8. data/docs/{technical-overview → main-concepts}/concurrency.md +62 -15
  9. data/docs/{technical-overview → main-concepts}/design-principles.md +21 -8
  10. data/docs/{technical-overview → main-concepts}/exception-handling.md +80 -38
  11. data/docs/{technical-overview → main-concepts}/extending.md +4 -3
  12. data/docs/{technical-overview → main-concepts}/fiber-scheduling.md +3 -3
  13. data/docs/{technical-overview.md → main-concepts.md} +2 -2
  14. data/examples/core/xx-at_exit.rb +29 -0
  15. data/examples/core/xx-fork-terminate.rb +27 -0
  16. data/examples/core/xx-pingpong.rb +18 -0
  17. data/examples/core/xx-stop.rb +20 -0
  18. data/ext/gyro/async.c +1 -1
  19. data/ext/gyro/extconf.rb +0 -3
  20. data/ext/gyro/gyro.c +7 -8
  21. data/ext/gyro/gyro.h +2 -0
  22. data/ext/gyro/queue.c +6 -6
  23. data/ext/gyro/selector.c +32 -1
  24. data/ext/gyro/thread.c +55 -9
  25. data/ext/gyro/timer.c +1 -0
  26. data/lib/polyphony/core/exceptions.rb +4 -1
  27. data/lib/polyphony/core/global_api.rb +1 -6
  28. data/lib/polyphony/core/thread_pool.rb +3 -3
  29. data/lib/polyphony/extensions/core.rb +7 -1
  30. data/lib/polyphony/extensions/fiber.rb +159 -72
  31. data/lib/polyphony/extensions/io.rb +2 -4
  32. data/lib/polyphony/extensions/openssl.rb +0 -17
  33. data/lib/polyphony/extensions/thread.rb +46 -22
  34. data/lib/polyphony/version.rb +1 -1
  35. data/lib/polyphony.rb +20 -18
  36. data/test/coverage.rb +1 -1
  37. data/test/helper.rb +7 -3
  38. data/test/test_fiber.rb +285 -72
  39. data/test/test_global_api.rb +7 -52
  40. data/test/test_io.rb +8 -0
  41. data/test/test_signal.rb +1 -0
  42. data/test/test_thread.rb +76 -56
  43. data/test/test_thread_pool.rb +27 -5
  44. data/test/test_throttler.rb +1 -0
  45. metadata +12 -12
  46. data/lib/polyphony/core/supervisor.rb +0 -114
  47. data/lib/polyphony/line_reader.rb +0 -82
  48. data/test/test_gyro.rb +0 -25
  49. data/test/test_supervisor.rb +0 -180
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb34882b5a9cb5bbf2b1b27909795f96e5291fe953aeea53f6ebd4e95d8bd19f
4
- data.tar.gz: c38af8c17d62b70fed44988182e70caba305eb9abbb3c4d1a8fdeda349031bae
3
+ metadata.gz: cf1cef97b80aa22506d7b5d1547062cfb62909ef12411fe0877ff3972f00198f
4
+ data.tar.gz: 5418b1912ea214600fbbc435e91f56e6db325dd21710530932fef944b27fc7ab
5
5
  SHA512:
6
- metadata.gz: ab9f3c212357aa7eedaee5f43c1b85ff28337e8bb1cc3d693fcc72ff02c49ddf55b211daccfd0eb516cfca1544e02312f10f5e59eb0903c55279cc5983a69ca3
7
- data.tar.gz: 9d871f6e1c8013a13fc03f191d6e0ac7fb7766e723c73be3afcf2d870cea9595bc750c4d45c7efb1a61104ef0611e00a430baae6b3a0c5afcd4b2a859c8677f5
6
+ metadata.gz: f878c45416276bb13e40c8641ab614d75c47f82b82859ab21fa37ae7012e487d040919b50a8f588d097fa2ab95295f20b79a91ab5ae4ec8177f0846c6cbd3892
7
+ data.tar.gz: 9d97c148ea0f54e15d1c55209a53131d09278fa7c8dd426c1f3d945ba26f86c0ffebb056dde9f4e324719a3dc424afcde2bbf99cddbadfe781bc9e1fab965ef9
data/.gitignore CHANGED
@@ -53,6 +53,7 @@ test.rb
53
53
  .vscode
54
54
 
55
55
  lib/gyro_ext.bundle
56
+ lib/gyro_ext.so
56
57
 
57
58
  _site
58
59
  .sass-cache
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ 0.30 2020-14-02
2
+ ---------------
3
+
4
+ * Add support for awaiting a fiber from multiple monitor fibers at once
5
+ * Implemented child fibers
6
+ * Fix TERM and INT signal handling (close #11)
7
+ * Fix compiling on Linux
8
+ * Do not reset runnable value in Gyro_suspend (prevents interrupting timers)
9
+ * Don't snooze when stopping a fiber
10
+ * Fix IO#read for files larger than 8KB (#10)
11
+ * Fix fiber messaging in main fiber
12
+ * Prevent signalling of inactive async watcher
13
+ * Better fiber messaging
14
+
1
15
  0.29 2020-02-02
2
16
  ---------------
3
17
 
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- polyphony (0.29)
4
+ polyphony (0.30)
5
5
  modulation (~> 1.0)
6
6
 
7
7
  GEM
data/TODO.md CHANGED
@@ -1,15 +1,20 @@
1
- ## 0.29 Multithreaded fiber scheduling - some rough corners
1
+ ## 0.31 Working Sinatra application
2
+
3
+ - Accept rate/interval in `spin_loop` and `spin_worker_loop`:
4
+
5
+ ```ruby
6
+ spin_loop(10) { ... } # 10 times per second
7
+ spin_loop(rate: 10) { ... } # 10 times per second
8
+ spin_loop(interval: 10) { ... } # once every ten seconds
9
+ ```
2
10
 
3
11
  - Docs: explain difference between `sleep` and `suspend`
4
12
  - Check why first call to `#sleep` returns too early in tests. Check the
5
13
  sleep behaviour in a spawned thread.
6
-
7
- ## 0.30 Working Sinatra application
8
-
9
14
  - app with database access (postgresql)
10
15
  - benchmarks!
11
16
 
12
- ## 0.31 Sidekick
17
+ ## 0.32 Sidekick
13
18
 
14
19
  Plan of action:
15
20
 
@@ -17,13 +22,13 @@ Plan of action:
17
22
  - test performance
18
23
  - proceed from there
19
24
 
20
- ## 0.32 Testing && Docs
25
+ ## 0.33 Testing && Docs
21
26
 
22
27
  - Pull out redis/postgres code, put into new `polyphony-xxx` gems
23
28
 
24
- ## 0.33 Integration
29
+ ## 0.34 Integration
25
30
 
26
- ## 0.34 Real IO#gets and IO#read
31
+ ## 0.35 Real IO#gets and IO#read
27
32
 
28
33
  - More tests
29
34
  - Implement some basic stuff missing:
@@ -33,11 +38,11 @@ Plan of action:
33
38
  - `IO.foreach`
34
39
  - `Process.waitpid`
35
40
 
36
- ## 0.35 Rails
41
+ ## 0.36 Rails
37
42
 
38
43
  - Rails?
39
44
 
40
- ## 0.36 DNS
45
+ ## 0.37 DNS
41
46
 
42
47
  ### DNS client
43
48
 
@@ -5,7 +5,7 @@ nav_order: 2
5
5
  parent: Getting Started
6
6
  permalink: /getting-started/tutorial/
7
7
  prev_title: Installing Polyphony
8
- next_title: Design Principles
8
+ next_title: Concurrency the Easy Way
9
9
  ---
10
10
  # A Gentle Introduction to Polyphony
11
11
 
@@ -332,7 +332,7 @@ fiber.raise 'foo'
332
332
  ```
333
333
 
334
334
  For more information on how exceptions are handled in Polyphony, see [exception
335
- handling](../../technical-overview/exception-handling/).
335
+ handling](../../main-concepts/exception-handling/).
336
336
 
337
337
  ## Supervising - controlling multiple fibers at once
338
338
 
@@ -441,6 +441,6 @@ possibilities for Ruby. Polyphony has the performance characteristics and
441
441
  provides the necessary tools for transforming how concurrent Ruby apps are
442
442
  written. Polyphony is still new, and the present documentation is far from being
443
443
  complete. To learn more about Polyphony, read the [technical
444
- overview](../../technical-overview/design-principles/). For more examples please
444
+ overview](../../main-concepts/design-principles/). For more examples please
445
445
  consult the [Github
446
446
  repository](https://github.com/digital-fabric/polyphony/tree/master/examples).
data/docs/index.md CHANGED
@@ -78,10 +78,9 @@ Polyphony draws inspiration from the following, in no particular order:
78
78
 
79
79
  ## Going further
80
80
 
81
- To learn more about using Polyphony to build concurrent applications, read the
82
- technical overview below, or look at the [included
81
+ To learn more about using Polyphony to build concurrent applications, continue reading, or look at the [bundled
83
82
  examples](https://github.com/digital-fabric/polyphony/tree/9e0f3b09213156bdf376ef33684ef267517f06e8/examples/README.md).
84
- A thorough reference is forthcoming.
83
+ A thorough API reference is forthcoming.
85
84
 
86
85
  ## Contributing to Polyphony
87
86
 
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  layout: page
3
3
  title: Concurrency the Easy Way
4
- nav_order: 2
5
- parent: Technical Overview
6
- permalink: /technical-overview/concurrency/
7
- prev_title: Design Principles
4
+ nav_order: 1
5
+ parent: Main Concepts
6
+ permalink: /main-concepts/concurrency/
7
+ prev_title: A Gentle Introduction to Polyphony
8
8
  next_title: How Fibers are Scheduled
9
9
  ---
10
10
  # Concurrency the Easy Way
@@ -65,10 +65,64 @@ understand, compared to callback-style programming.
65
65
 
66
66
  Polyphony extends the core `Fiber` class with additional functionality that
67
67
  allows scheduling, synchronizing, interrupting and otherwise controlling running
68
- fibers. Polyphony makes sure any exception raised while a fiber is running is
69
- [handled correctly](exception-handling.md). Moreover, fibers can communicate
70
- with each other using message passing, turning them into autonomous actors in a
71
- highly concurrent environment.
68
+ fibers. Starting a concurrent operation inside a fiber is as simple as a `spin`
69
+ method call:
70
+
71
+ ```ruby
72
+ while (connection = server.accept)
73
+ spin { handle_connection(connection) }
74
+ end
75
+ ```
76
+
77
+ In order to facilitate developing applications that employ complex concurrent
78
+ patterns and can scale easily, Polyphony employs a [structured
79
+ approach](https://en.wikipedia.org/wiki/Structured_concurrency) to controlling
80
+ fiber lifetime. A spun fiber is considered the *child* of the fiber from which
81
+ it was spun, and is always limited to the life time of its parent:
82
+
83
+ ```ruby
84
+ parent = spin do
85
+ do_something
86
+ child = spin do
87
+ do_some_other_stuff
88
+ end
89
+ # the child fiber is guaranteed to stop executing before the parent fiber
90
+ # terminates
91
+ end
92
+ ```
93
+
94
+ Any uncaught exception raised in a fiber will be
95
+ [propagated]((exception-handling.md)) to its parent, and potentially further up
96
+ the fiber hierarchy, all the way to the main fiber:
97
+
98
+ ```ruby
99
+ parent = spin do
100
+ child = spin do
101
+ raise 'foo'
102
+ end
103
+ sleep
104
+ end
105
+
106
+ sleep
107
+ # the exception will be propagated from the child fiber to the parent fiber,
108
+ # and from the parent fiber to the main fiber, which will cause the program to
109
+ # abort.
110
+ ```
111
+
112
+ In addition, fibers can communicate with each other using message passing,
113
+ turning them into autonomous actors in a highly concurrent environment. Message
114
+ passing is in many ways a superior way to pass data between concurrent entities,
115
+ obviating the need to synchronize access to shared resources:
116
+
117
+ ```ruby
118
+ writer = spin do
119
+ while (write_request = receive)
120
+ do_write(write_request)
121
+ end
122
+ end
123
+ ...
124
+ writer << { stamp: Time.now, value: rand }
125
+ ```
72
126
 
73
127
  ## Higher-Order Concurrency Constructs
74
128
 
@@ -80,19 +134,13 @@ Cancel scopes \(borrowed from the brilliant Python library
80
134
  [Trio](https://trio.readthedocs.io/en/stable/)\) allows cancelling ongoing
81
135
  operations for any reason with more control over cancelling behaviour.
82
136
 
83
- Supervisors allow controlling multiple fibers. They offer enhanced exception
84
- handling and can be nested to create complex supervision trees ala
85
- [Erlang](https://adoptingerlang.org/docs/development/supervision_trees/).
86
-
87
137
  Some other constructs offered by Polyphony:
88
138
 
89
139
  * `Mutex` - a mutex used to synchronize access to a single shared resource.
90
140
  * `ResourcePool` - used for synchronizing access to a limited amount of shared
91
-
92
141
  resources, for example a pool of database connections.
93
142
 
94
143
  * `Throttler` - used for throttling repeating operations, for example throttling
95
-
96
144
  access to a shared resource, or throttling incoming requests.
97
145
 
98
146
  ## A Compelling Concurrency Solution for Ruby
@@ -106,4 +154,3 @@ way to write concurrent applications in Ruby. Polyphony aims to show that Ruby
106
154
  can be used for developing sufficiently high-performance applications, while
107
155
  offering all the advantages of Ruby, with source code that is easy to read and
108
156
  understand.
109
-
@@ -1,16 +1,26 @@
1
1
  ---
2
2
  layout: page
3
3
  title: Design Principles
4
- nav_order: 1
5
- parent: Technical Overview
6
- permalink: /technical-overview/design-principles/
7
- prev_title: A Gentle Introduction to Polyphony
8
- next_title: Concurrency the Easy Way
4
+ nav_order: 5
5
+ parent: Main Concepts
6
+ permalink: /main-concepts/design-principles/
7
+ prev_title: Extending Polyphony
9
8
  ---
10
9
  # Design Principles
11
10
 
12
- Polyphony was created in order to enable creating high-performance concurrent
13
- applications in Ruby, by utilizing Ruby fibers together with the
11
+ Polyphony was created in order to enable developing high-performance concurrent
12
+ applications in Ruby using a fluent, compact syntax and API. Polyphony enables
13
+ fine-grained concurrency - the splitting up of operations into a large number of
14
+ concurrent tasks, each concerned with small part of the whole and advancing at
15
+ its own pace.
16
+
17
+
18
+
19
+
20
+ a single Ruby process may spin up millions of
21
+ concurrent fibers.
22
+
23
+ , by utilizing Ruby fibers together with the
14
24
  [libev](http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod) event reactor
15
25
  library. Polyphony's design is based on the following principles:
16
26
 
@@ -57,8 +67,11 @@ library. Polyphony's design is based on the following principles:
57
67
  }
58
68
  ```
59
69
 
70
+ - Breaking up operations into
71
+
60
72
  - Polyphony should embrace Ruby's standard `raise/rescue/ensure` exception
61
- handling mechanism:
73
+ handling mechanism. Exception handling in a highly concurrent environment
74
+ should be robust and foolproof:
62
75
 
63
76
  ```ruby
64
77
  cancel_after(0.5) do
@@ -1,21 +1,21 @@
1
1
  ---
2
2
  layout: page
3
3
  title: Exception Handling
4
- nav_order: 4
5
- parent: Technical Overview
6
- permalink: /technical-overview/exception-handling/
4
+ nav_order: 3
5
+ parent: Main Concepts
6
+ permalink: /main-concepts/exception-handling/
7
7
  prev_title: How Fibers are Scheduled
8
8
  next_title: Extending Polyphony
9
9
  ---
10
10
  # Exception Handling
11
11
 
12
12
  Ruby employs a pretty robust exception handling mechanism. An raised exception
13
- will bubble up the call stack until a suitable exception handler is found, based
14
- on the exception's class. In addition, the exception will include a stack trace
15
- showing the execution path from the exception's locus back to the program's
16
- entry point. Unfortunately, when exceptions are raised while switching between
17
- fibers, stack traces will only include partial information. Here's a simple
18
- demonstration:
13
+ will propagate up the fiber tree until a suitable exception handler is found,
14
+ based on the exception's class. In addition, the exception will include a stack
15
+ trace showing the execution path from the exception's locus back to the
16
+ program's entry point. Unfortunately, when exceptions are raised while switching
17
+ between fibers, stack traces will only include partial information. Here's a
18
+ simple demonstration:
19
19
 
20
20
  _fiber\_exception.rb_
21
21
 
@@ -124,7 +124,7 @@ fired or not. We call `timer.stop` inside an ensure block, thus ensuring that
124
124
  the timer will have stopped once the awaiting fiber has resumed, even if it has
125
125
  not fired.
126
126
 
127
- ## Bubbling Up - A Robust Solution for Uncaught Exceptions
127
+ ## Exception Propagation
128
128
 
129
129
  One of the "annoying" things about exceptions is that for them to be useful, you
130
130
  have to intercept them \(using `rescue`\). If you forget to do that, you'll end
@@ -132,9 +132,9 @@ up with uncaught exceptions that can wreak havoc. For example, by default a Ruby
132
132
  `Thread` in which an exception was raised without being caught, will simply
133
133
  terminate with the exception silently swallowed.
134
134
 
135
- To prevent the same from happening with fibers, Polyphony provides a mechanism
136
- that lets uncaught exceptions bubble up through the chain of calling fibers.
137
- Let's discuss the following example:
135
+ To prevent the same from happening with fibers, Polyphony provides a robust
136
+ mechanism that propagates uncaught exceptions up through the chain of parent
137
+ fibers. Let's discuss the following example:
138
138
 
139
139
  ```ruby
140
140
  require 'polyphony'
@@ -144,17 +144,23 @@ spin do
144
144
  spin do
145
145
  spin do
146
146
  raise 'foo'
147
- end.await
148
- end.await
149
- end.await
150
- end.await
147
+ end
148
+ sleep
149
+ end
150
+ sleep
151
+ end
152
+ sleep
153
+ end
154
+
155
+ sleep
151
156
  ```
152
157
 
153
- In this example, there are four fibers, nested one within the other. An
154
- exception is raised in the inner most fiber, and having no exception handler,
155
- will bubble up through the different enclosing fibers, until reaching the
158
+ In the above example, four nested fibers are created, and each of them, except
159
+ for the innermost fiber, goes to sleep for an unlimited duration. An exception
160
+ is raised in the innermost fiber, and having no corresponding exception handler,
161
+ will propagate up through the enclosing fibers, until reaching the
156
162
  top-most level, that of the root fiber, at which point the exception will cause
157
- the program to halt and print an error message.
163
+ the program to abort and print an error message.
158
164
 
159
165
  ## MoveOn and Cancel - Interrupting Fiber Execution
160
166
 
@@ -163,8 +169,8 @@ provides two exception classes that used exclusively to interrupt fiber
163
169
  execution: `MoveOn` and `Cancel`. Both of these classes are used in various
164
170
  fiber-control APIs, and `MoveOn` exceptions in particular are handled in a
165
171
  particular manner by Polyphony. The difference between `MoveOn` and `Cancel` is
166
- that `MoveOn` stops fiber execution without the exception bubbling up. It can
167
- optionally provide an arbitrary return value for the fiber. `Cancel` will bubble
172
+ that `MoveOn` stops fiber execution without the exception propagating. It can
173
+ optionally provide an arbitrary return value for the fiber. `Cancel` will propagate
168
174
  up like all exceptions.
169
175
 
170
176
  The `MoveOn` and `Cancel` classes are normally used indirectly, through the
@@ -183,22 +189,58 @@ f3 = spin { sleep 100 }
183
189
  f3.cancel #=> will raise a Cancel exception
184
190
  ```
185
191
 
186
- ## Signal Handling and Termination
192
+ In addition to `MoveOn` and `Cancel`, Polyphony employs internally another
193
+ exception class, `Terminate` for terminating a fiber once its parent has
194
+ finished executing.
195
+
196
+ ## The Special Problem of Signal Handling
197
+
198
+ Ruby by default handles process signals by generating exceptions, allowing the
199
+ handling of signals in a structured manner. However, process signals may arrive
200
+ at any moment, and may be trapped while any arbitrary fiber is running, and even
201
+ while an event loop is running.
187
202
 
188
- Polyphony does not normally intercept process signals, though it is possible to
189
- intercept them using `Gyro::Signal` watchers. It is, however, recommended for
190
- the time being to not interfere with Ruby's normal signal processing.
203
+ Two signals in particular require special care as they involve the stopping of
204
+ the entire process: `TERM` and `INT`. The `TERM` signal should be handled
205
+ gracefully, i.e. with proper cleanup, which also means terminating all fibers.
206
+ The `INT` signal requires halting the process and printing a correct stack
207
+ trace.
208
+
209
+ To ensure correct behaviour for these two signals, polyphony installs signal
210
+ handlers that ensure that the main thread's event loop stops if it's currently
211
+ running, and that the corresponding exceptions (namely `SystemExit` and
212
+ `Interrupt`) are handled correctly by propagating them using Polyphony's normal
213
+ exception handling mechanisms.
214
+
215
+ Care should be taken when handling other signals. There are two options for
216
+ correctly handling the signals: using Ruby's stock `trap` method, and using
217
+ Polyphony's signal watchers. The stock method involves trapping signals as
218
+ usual, but making sure we're not inside the event loop:
219
+
220
+ ```ruby
221
+ trap('SIGHUP') do
222
+ Thread.current.break_out_of_ev_loop(nil)
223
+ handle_hup_signal
224
+ end
225
+ ```
226
+
227
+ The alternative is to use `Polyphony.wait_for_signal`:
228
+
229
+ ```ruby
230
+ hup_handler = spin_loop do
231
+ Polyphony.wait_for_signal
232
+ handle_hup_signal
233
+ end
234
+ ```
191
235
 
192
- In Ruby there are three core exception classes are related to signal handling
193
- and process termination: `Interrupt` - raised upon receiving an `INT` signal;
194
- `SystemExit` - raised upon calling `Kernel#exit`; and `SignalException` - raised
195
- upon receiving other signals.
236
+ ## The Special Problem of Thread Termination
196
237
 
197
- These exceptions are raised on the main thread and in a multi-fiber environment
198
- can occur in any fiber, as long as it is the currently running fiber. In
199
- Polyphony, when these exceptions are raised in a fiber other than the main
200
- fiber, they will be effectively tranferred to the main fiber for processing.
238
+ Thread termination using `Thread#kill` or `Thread#raise` also presents the same
239
+ problems as signal handling in a multi-fiber environment. The termination can
240
+ occur while any fiber is running, and even while running the thread's event
241
+ loop.
201
242
 
202
- This means that any handlers for these three exception classes should be put
203
- only in the main fiber. This mechanism also helps with showing a correct
204
- backtrace for these exceptions.
243
+ To ensure proper thread termination, including the termination of all the
244
+ thread's fibers, Polyphony patches the `Thread#kill` and `Thread#raise` methods
245
+ to schedule the thread's main fiber with the corresponding exceptions, thus
246
+ ensuring an orderly termination or exception handling.
@@ -1,10 +1,11 @@
1
1
  ---
2
2
  layout: page
3
3
  title: Extending Polyphony
4
- nav_order: 5
5
- parent: Technical Overview
6
- permalink: /technical-overview/extending/
4
+ nav_order: 4
5
+ parent: Main Concepts
6
+ permalink: /main-concepts/extending/
7
7
  prev_title: Exception Handling
8
+ next_title: Design Principles
8
9
  ---
9
10
  # Extending Polyphony
10
11
 
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  layout: page
3
3
  title: How Fibers are Scheduled
4
- nav_order: 3
5
- parent: Technical Overview
6
- permalink: /technical-overview/fiber-scheduling/
4
+ nav_order: 2
5
+ parent: Main Concepts
6
+ permalink: /main-concepts/fiber-scheduling/
7
7
  prev_title: Concurrency the Easy Way
8
8
  next_title: Exception Handling
9
9
  ---
@@ -1,10 +1,10 @@
1
1
  ---
2
2
  layout: page
3
- title: Technical Overview
3
+ title: Main Concepts
4
4
  description: Lorem ipsum
5
5
  has_children: true
6
6
  section: true
7
7
  has_toc: false
8
8
  nav_order: 3
9
- section_link: /technical-overview/design-principles
9
+ section_link: /main-concepts/concurrency
10
10
  ---
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ Exception.__disable_sanitized_backtrace__ = true
7
+
8
+ child_pid = Polyphony.fork do
9
+ at_exit do
10
+ puts "at_exit"
11
+ f = spin { sleep 10 }
12
+ trap('SIGINT') { f.stop }
13
+ f.await
14
+ end
15
+
16
+ f1 = spin { sleep 100 }
17
+
18
+ puts "pid: #{Process.pid}"
19
+
20
+ pid = Process.pid
21
+
22
+ f1.join
23
+ end
24
+
25
+ sleep 0.1
26
+ Process.kill('INT', child_pid)
27
+ sleep 0.1
28
+ Process.kill('INT', child_pid)
29
+ Process.wait(child_pid)
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ Exception.__disable_sanitized_backtrace__ = true
7
+
8
+ pid = Polyphony.fork do
9
+ f = spin do
10
+ p 1
11
+ sleep 1
12
+ p 2
13
+ ensure
14
+ p 2.5
15
+ end
16
+ p 3
17
+ snooze
18
+ p 4
19
+ # f.stop
20
+ # f.join
21
+ # Fiber.current.terminate_all_children
22
+ # Fiber.current.await_all_children
23
+ p 5
24
+ end
25
+
26
+ puts "Child pid: #{pid}"
27
+ Process.wait(pid)
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ pong = spin_loop do
7
+ msg, ping = receive
8
+ puts msg
9
+ ping << 'pong'
10
+ end
11
+
12
+ ping = spin_loop do
13
+ pong << ['ping', Fiber.current]
14
+ msg = receive
15
+ puts msg
16
+ end
17
+
18
+ suspend
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+ require 'polyphony'
5
+
6
+ f1 = spin do
7
+ f2 = spin { sleep 60 }
8
+ f3 = spin { sleep 60 }
9
+ sleep 60
10
+ ensure
11
+ p 1
12
+ f2.stop
13
+ p 2
14
+ f3.stop
15
+ p "should reach here!"
16
+ end
17
+
18
+ sleep 0.1
19
+ f1.stop
20
+ snooze
data/ext/gyro/async.c CHANGED
@@ -78,7 +78,7 @@ static VALUE Gyro_Async_signal(int argc, VALUE *argv, VALUE self) {
78
78
  struct Gyro_Async *async;
79
79
  GetGyro_Async(self, async);
80
80
 
81
- if (!async->ev_loop) {
81
+ if (!async->active) {
82
82
  // printf("signal! called before await\n");
83
83
  return Qnil;
84
84
  }
data/ext/gyro/extconf.rb CHANGED
@@ -16,8 +16,5 @@ $defs << "-DHAVE_SYS_RESOURCE_H" if have_header("sys/resource.h")
16
16
 
17
17
  CONFIG["optflags"] << " -fno-strict-aliasing" unless RUBY_PLATFORM =~ /mswin/
18
18
 
19
- CONFIG["optflags"] << " -Wcomment"
20
- CONFIG["optflags"] << " -Wbitwise-op-parentheses"
21
-
22
19
  dir_config "gyro_ext"
23
20
  create_makefile "gyro_ext"