resource_warden 0.1.0 → 0.1.1
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/lib/ResourceWarden/Key.rb +5 -0
- data/lib/ResourceWarden/ResourceCell.rb +7 -1
- data/lib/ResourceWarden/Warden.rb +16 -3
- data/lib/ResourceWarden/types.rbs +1 -15
- data/lib/ResourceWarden/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a0524384f21128a12d22d6ef50d0a433c2bb5640e95057b909d0cddddd3e509e
|
|
4
|
+
data.tar.gz: 59e2f42a77d5f21f165623c5a4c31a2a99c373d8b8dd209f46eae8ca3945046c
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 0ec2387e3c5d99d2508d1e10941d0caa398f2665236ef59896a01ab9de61d75ae2505d1ed66c87ba41913a0ac72045020d29d66d5add93fa5ce6958c82450845
|
|
7
|
+
data.tar.gz: 92292cd7e7c31112d81d71f4acdc78cded5d0d86759c7ede33d85e263168ef2bb5f57f13ee792dbdba1959e7beb8546ad8d8898760425988bb3113509441ea09
|
data/lib/ResourceWarden/Key.rb
CHANGED
|
@@ -1,9 +1,14 @@
|
|
|
1
|
+
##
|
|
2
|
+
# A class encapsulating a single use Proc to change the owner of a resource to the thread that request a resource key
|
|
1
3
|
class Key
|
|
2
4
|
class ReuseException < Exception; end
|
|
3
5
|
def initialize(&block)
|
|
4
6
|
@proc = Proc.new(&block)
|
|
5
7
|
end
|
|
6
8
|
|
|
9
|
+
##
|
|
10
|
+
# Calls the Proc created by the resource cell which switches the owner of the resource to the thread that requested the key
|
|
11
|
+
# This is the only intended way to obtain ownership of a resource
|
|
7
12
|
def use
|
|
8
13
|
throw ReuseException.new("A key can only be used once") unless @proc.is_a?(Proc)
|
|
9
14
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
require_relative './Key'
|
|
2
|
+
##
|
|
2
3
|
# wraps a resource to ensure only a keyholder can execute code
|
|
3
4
|
module ResourceWarden
|
|
4
5
|
class ResourceCell
|
|
@@ -14,16 +15,18 @@ module ResourceWarden
|
|
|
14
15
|
@registry = []
|
|
15
16
|
end
|
|
16
17
|
|
|
18
|
+
##
|
|
17
19
|
# changes the heir to the caller and builds a connector proc to wait on the current thread
|
|
18
20
|
def get_key
|
|
19
21
|
heir = nil
|
|
22
|
+
thread = Thread.current
|
|
20
23
|
@registration.synchronize do
|
|
21
24
|
heir = @heir
|
|
22
25
|
@heir = Thread.current
|
|
23
26
|
end
|
|
24
27
|
Key.new do
|
|
25
28
|
heir&.join
|
|
26
|
-
chown(
|
|
29
|
+
chown(thread)
|
|
27
30
|
Unlock.new
|
|
28
31
|
end
|
|
29
32
|
end
|
|
@@ -43,6 +46,9 @@ module ResourceWarden
|
|
|
43
46
|
throw JailbreakException.new("A thread must first use a resource key before accessing a resource")
|
|
44
47
|
end
|
|
45
48
|
|
|
49
|
+
##
|
|
50
|
+
# Responds only to public methods of the resource cell until the calling thread owns the resource then responds
|
|
51
|
+
# resource methods as well
|
|
46
52
|
def respond_to_missing?(method_name, include_private = false)
|
|
47
53
|
super || Thread.current == @owner && @resource.respond_to?(method_name, include_private)
|
|
48
54
|
end
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
##
|
|
2
|
+
# Resource Exclusion module
|
|
2
3
|
# A block is passed which will then be encapsulated in a thread immediately joined by the current thread.
|
|
3
4
|
# This allows requests for multiple resources and guarantees a lock on all resources will be granted
|
|
4
5
|
# as soon as all prior virtual threads with a claim on a resource terminate.
|
|
@@ -13,24 +14,35 @@ module ResourceWarden
|
|
|
13
14
|
@mutex = Mutex.new
|
|
14
15
|
@registration = Mutex.new
|
|
15
16
|
|
|
17
|
+
##
|
|
18
|
+
# takes a list of resources which constitute a block of resources that must be obtained as a group
|
|
16
19
|
def initialize(*resources)
|
|
17
20
|
@cell_block = resources || []
|
|
18
21
|
@block_mutex = Mutex.new
|
|
19
22
|
end
|
|
20
23
|
|
|
24
|
+
##
|
|
25
|
+
# adds a resource to the exclusive resource block
|
|
26
|
+
# @param resource [ResourceWarden::ResourceCell]
|
|
21
27
|
def add(resource)
|
|
22
28
|
@block_mutex.synchronize { @cell_block << resource }
|
|
23
29
|
end
|
|
24
30
|
|
|
31
|
+
##
|
|
32
|
+
# @return [Array<ResourceWarden::ResourceCell>]
|
|
25
33
|
def resources
|
|
26
34
|
@cell_block
|
|
27
35
|
end
|
|
28
36
|
|
|
37
|
+
##
|
|
38
|
+
# Runs a block of code with exclusive access to all resources in the block
|
|
29
39
|
def synchronize(&block)
|
|
30
40
|
@block_mutex.synchronize { Warden.synchronize(*@cell_block, &block) }
|
|
31
41
|
end
|
|
32
42
|
|
|
33
|
-
|
|
43
|
+
##
|
|
44
|
+
# Runs a block of code with exclusive access to a list of resources
|
|
45
|
+
# @param resources [ResourceWarden::ResourceCell]
|
|
34
46
|
def self.synchronize(*resources, &block)
|
|
35
47
|
keys = []
|
|
36
48
|
# creating a virtual thread to guarantee the owning thread is joinable
|
|
@@ -42,7 +54,8 @@ module ResourceWarden
|
|
|
42
54
|
end
|
|
43
55
|
|
|
44
56
|
|
|
45
|
-
|
|
57
|
+
##
|
|
58
|
+
# Takes a object or block and creates a resource from the object or output of the block respectively
|
|
46
59
|
def self.create(object = nil)
|
|
47
60
|
@registration.synchronize do
|
|
48
61
|
item = block_given? ? yield : object
|
|
@@ -1,16 +1,10 @@
|
|
|
1
1
|
# Transparent wrapper class ignores requests from any caller other than the current owner
|
|
2
2
|
module ResourceWarden
|
|
3
3
|
class ResourceCell
|
|
4
|
-
# Creates the cell that will only allow a owning thread to call any method of the resource
|
|
5
4
|
def initialize: (untyped) -> void
|
|
6
|
-
# creates a blocking resource key that can only be used once to change the owner of the resource to the calling thread
|
|
7
5
|
def get_key: -> void
|
|
8
|
-
|
|
9
|
-
# returns the current resource owner
|
|
10
6
|
private def owner: -> Thread
|
|
11
7
|
private def chown: (Thread) -> void
|
|
12
|
-
|
|
13
|
-
# resource guard method
|
|
14
8
|
private def method_missing: (Symbol | String, *untyped) -> untyped
|
|
15
9
|
private def respond_to_missing?: (Symbol | String, *untyped) -> bool
|
|
16
10
|
|
|
@@ -20,24 +14,16 @@ module ResourceWarden
|
|
|
20
14
|
end
|
|
21
15
|
|
|
22
16
|
class Warden
|
|
23
|
-
# warden instance handles a specific resource group
|
|
24
17
|
def intialize: (*ResourceCell) -> void
|
|
25
|
-
# synchronize a block with all resource under the wardens management
|
|
26
18
|
def synchronize: () { () -> BasicObject } -> void
|
|
27
|
-
# puts a resource under this wardens management
|
|
28
19
|
def add: (ResourceCell) -> void
|
|
29
|
-
# returns the resources managed by this warden
|
|
30
20
|
def resources: () -> Array[ResourceCell]
|
|
31
|
-
|
|
32
|
-
def self.synchronize:(*Symbol) { () -> BasicObject } -> void
|
|
33
|
-
# creates a resourceCell either from an object or a cell
|
|
21
|
+
def self.synchronize:(*ResourceCell) { () -> BasicObject } -> void
|
|
34
22
|
def self.create:(untyped) -> ResourceCell | () { () -> Object } -> ResourceCell
|
|
35
23
|
end
|
|
36
24
|
|
|
37
25
|
class Key
|
|
38
|
-
# creates a key this should only be created by a resource cell
|
|
39
26
|
def initialize: () {() -> ResourceCell::Unlock } -> void
|
|
40
|
-
# changes the owner of the creating cell to the current thread after waiting for prior threads to complete
|
|
41
27
|
def use: () -> void
|
|
42
28
|
end
|
|
43
29
|
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: resource_warden
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Aaron Deibele
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-05-
|
|
11
|
+
date: 2022-05-04 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|