async-safe 0.1.0 → 0.2.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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/context/getting-started.md +4 -4
- data/lib/async/safe/builtins.rb +27 -0
- data/lib/async/safe/monitor.rb +9 -7
- data/lib/async/safe/version.rb +1 -1
- data/lib/async/safe.rb +8 -2
- data/readme.md +5 -0
- data/releases.md +5 -0
- data.tar.gz.sig +0 -0
- metadata +1 -1
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 52f743f5c66ba254659d3f6afb52e8f6bf1189f395ca931e708890eea1fe4e00
|
4
|
+
data.tar.gz: 4a89412e5fd61a9c4c5bdac4d90a6897e70fbeccac5301b58e56a3cf622542a8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b7b6981fe90ffdbef57060678ba4988202333120848cc40d4528873b9a6ccd5b39a53549d35886d75a08343db12697855eb56c74af9d06c9434e2a153d6caef5
|
7
|
+
data.tar.gz: 8a0ec23a746938beeadd581af8e7aaa19dc0219826343a40ef9d93071e34b2956e67fcab1c33c3529940716195b7958e2f99a127c2e6c47ca72e333f0c783f61
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/context/getting-started.md
CHANGED
@@ -25,7 +25,7 @@ Async::Safe.enable!
|
|
25
25
|
|
26
26
|
When a violation is detected, an `Async::Safe::ViolationError` will be raised immediately with details about the object, method, and execution contexts involved.
|
27
27
|
|
28
|
-
|
28
|
+
### Single-Owner Model
|
29
29
|
|
30
30
|
By default, all objects are assumed to follow a **single-owner model** - they should only be accessed from one fiber/thread at a time:
|
31
31
|
|
@@ -51,7 +51,7 @@ Fiber.schedule do
|
|
51
51
|
end
|
52
52
|
~~~
|
53
53
|
|
54
|
-
|
54
|
+
### Marking Async-Safe Classes
|
55
55
|
|
56
56
|
Mark entire classes as safe for concurrent access:
|
57
57
|
|
@@ -90,7 +90,7 @@ class MyQueue
|
|
90
90
|
end
|
91
91
|
~~~
|
92
92
|
|
93
|
-
|
93
|
+
### Marking Async-Safe Methods
|
94
94
|
|
95
95
|
Mark specific methods as async-safe:
|
96
96
|
|
@@ -122,7 +122,7 @@ Fiber.schedule do
|
|
122
122
|
end
|
123
123
|
~~~
|
124
124
|
|
125
|
-
|
125
|
+
### Transferring Ownership
|
126
126
|
|
127
127
|
Explicitly transfer ownership between fibers:
|
128
128
|
|
data/lib/async/safe/builtins.rb
CHANGED
@@ -20,3 +20,30 @@ Fiber::ASYNC_SAFE = true
|
|
20
20
|
|
21
21
|
# ObjectSpace::WeakMap is async-safe:
|
22
22
|
ObjectSpace::WeakMap::ASYNC_SAFE = true
|
23
|
+
|
24
|
+
module Async
|
25
|
+
module Safe
|
26
|
+
module TransferableThreadQueue
|
27
|
+
def pop(...)
|
28
|
+
object = super(...)
|
29
|
+
Async::Safe.transfer(object)
|
30
|
+
object
|
31
|
+
end
|
32
|
+
|
33
|
+
def deq(...)
|
34
|
+
object = super(...)
|
35
|
+
Async::Safe.transfer(object)
|
36
|
+
object
|
37
|
+
end
|
38
|
+
|
39
|
+
def shift(...)
|
40
|
+
object = super(...)
|
41
|
+
Async::Safe.transfer(object)
|
42
|
+
object
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
Thread::Queue.prepend(Async::Safe::TransferableThreadQueue)
|
49
|
+
Thread::SizedQueue.prepend(Async::Safe::TransferableThreadQueue)
|
data/lib/async/safe/monitor.rb
CHANGED
@@ -64,10 +64,13 @@ module Async
|
|
64
64
|
ASYNC_SAFE = true
|
65
65
|
|
66
66
|
# Initialize a new monitor instance.
|
67
|
-
|
67
|
+
#
|
68
|
+
# @parameter logger [Object | Nil] Optional logger to use for violations instead of raising exceptions.
|
69
|
+
def initialize(logger: nil)
|
68
70
|
@owners = ObjectSpace::WeakMap.new
|
69
71
|
@mutex = Thread::Mutex.new
|
70
72
|
@trace_point = nil
|
73
|
+
@logger = logger
|
71
74
|
end
|
72
75
|
|
73
76
|
attr :owners
|
@@ -128,12 +131,11 @@ module Async
|
|
128
131
|
if owner = @owners[object]
|
129
132
|
# Violation if accessed from different fiber:
|
130
133
|
if owner != current
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
owner: owner,
|
135
|
-
|
136
|
-
)
|
134
|
+
if @logger
|
135
|
+
@logger.warn(self, "Async::Safe violation detected!", klass: klass, method: method, owner: owner, current: current, backtrace: caller_locations(3..))
|
136
|
+
else
|
137
|
+
raise ViolationError.new(target: object, method: method, owner: owner, current: current)
|
138
|
+
end
|
137
139
|
end
|
138
140
|
else
|
139
141
|
# First access - record owner:
|
data/lib/async/safe/version.rb
CHANGED
data/lib/async/safe.rb
CHANGED
@@ -61,8 +61,14 @@ module Async
|
|
61
61
|
#
|
62
62
|
# This activates a TracePoint that tracks object access across fibers and threads.
|
63
63
|
# There is no performance overhead when monitoring is disabled.
|
64
|
-
|
65
|
-
|
64
|
+
#
|
65
|
+
# @parameter logger [Object | Nil] Optional logger to use for violations instead of raising exceptions.
|
66
|
+
def enable!(logger: nil)
|
67
|
+
if @monitor
|
68
|
+
raise "Async::Safe is already enabled!"
|
69
|
+
end
|
70
|
+
|
71
|
+
@monitor = Monitor.new(logger: logger)
|
66
72
|
@monitor.enable!
|
67
73
|
end
|
68
74
|
|
data/readme.md
CHANGED
@@ -22,6 +22,11 @@ Please see the [project documentation](https://socketry.github.io/async-safe/) f
|
|
22
22
|
|
23
23
|
Please see the [project releases](https://socketry.github.io/async-safe/releases/index) for all releases.
|
24
24
|
|
25
|
+
### v0.2.0
|
26
|
+
|
27
|
+
- `Thread::Queue` transfers ownership of objects popped from it.
|
28
|
+
- Add support for `logger:` option in `Async::Safe.enable!` which logs violations instead of raising errors.
|
29
|
+
|
25
30
|
### v0.1.0
|
26
31
|
|
27
32
|
- Implement TracePoint-based ownership tracking.
|
data/releases.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# Releases
|
2
2
|
|
3
|
+
## v0.2.0
|
4
|
+
|
5
|
+
- `Thread::Queue` transfers ownership of objects popped from it.
|
6
|
+
- Add support for `logger:` option in `Async::Safe.enable!` which logs violations instead of raising errors.
|
7
|
+
|
3
8
|
## v0.1.0
|
4
9
|
|
5
10
|
- Implement TracePoint-based ownership tracking.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
metadata.gz.sig
CHANGED
Binary file
|