async-actor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 9e9de464bc62b1ee6737b902f4dd92d669a8b001011ca92e80e2937b4323cbbc
4
+ data.tar.gz: b1acc7ef2be6d0f8e192cccdc640e5d26456bc1f2254fe79910b77490ff332c2
5
+ SHA512:
6
+ metadata.gz: a183a688047b5c1309b9c611146b3cb09d4ca2298f75ff01340fa4bf1dbf908ae22135056bafc3556ca2db702b8d13fd84977cffd210672f7cc4350db676956a
7
+ data.tar.gz: '09e2cd6172518386c72d1f24457c1c071912c41cb7008488c4b8ca666a1560849cc033778f9af9f0b3d8337c689d5fdae59e44a9a5b6623dd4252b660679441b'
checksums.yaml.gz.sig ADDED
Binary file
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ require 'async'
7
+
8
+ require_relative 'variable'
9
+
10
+ module Async
11
+ module Actor
12
+ class Proxy < BasicObject
13
+ class Finalizer
14
+ def initialize(queue, thread)
15
+ @queue = queue
16
+ @thread = thread
17
+ end
18
+
19
+ def call(id)
20
+ @queue.close
21
+ @thread.join
22
+ end
23
+ end
24
+
25
+ def initialize(target)
26
+ @target = target
27
+
28
+ @queue = ::Thread::Queue.new
29
+ @thread = __start__
30
+
31
+ # Define a finalizer to ensure the thread is closed:
32
+ ::ObjectSpace.define_finalizer(self, Finalizer.new(@queue, @thread))
33
+ end
34
+
35
+ # @parameter return_value [Symbol] One of :ignore, :promise or :wait.
36
+ def method_missing(*arguments, return_value: :wait, **options, &block)
37
+ unless return_value == :ignore
38
+ result = Variable.new
39
+ end
40
+
41
+ @queue.push([arguments, options, block, result])
42
+
43
+ if return_value == :promise
44
+ return result
45
+ else
46
+ return result&.get
47
+ end
48
+ end
49
+
50
+ protected
51
+
52
+ def __start__
53
+ ::Thread.new do
54
+ ::Kernel.Sync do |task|
55
+ while operation = @queue.pop
56
+ task.async do
57
+ arguments, options, block, result = operation
58
+ Variable.fulfill(result) do
59
+ @target.public_send(*arguments, **options, &block)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ module Async
7
+ module Actor
8
+ class Variable
9
+ def self.fulfill(variable)
10
+ variable.set(yield)
11
+ variable = nil
12
+ rescue => error
13
+ variable&.fail(error)
14
+ variable = nil
15
+ ensure
16
+ # throw, etc:
17
+ variable&.fail(RuntimeError.new("Invalid flow control!"))
18
+ end
19
+
20
+ def initialize
21
+ @set = nil
22
+ @value = nil
23
+
24
+ @guard = Thread::Mutex.new
25
+ @condition = Thread::ConditionVariable.new
26
+ end
27
+
28
+ def set(value)
29
+ @guard.synchronize do
30
+ raise "Variable already set!" unless @set.nil?
31
+
32
+ @set = true
33
+ @value = value
34
+ @condition.broadcast
35
+ end
36
+ end
37
+
38
+ def fail(error)
39
+ @guard.synchronize do
40
+ raise "Variable already set!" unless @set.nil?
41
+
42
+ @set = false
43
+ @error = error
44
+ @condition.broadcast
45
+ end
46
+ end
47
+
48
+ def get
49
+ @guard.synchronize do
50
+ while @set.nil?
51
+ @condition.wait(@guard)
52
+ end
53
+
54
+ if @set
55
+ return @value
56
+ else
57
+ raise @error
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ module Async
7
+ module Actor
8
+ VERSION = "0.1.0"
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Released under the MIT License.
4
+ # Copyright, 2023, by Samuel Williams.
5
+
6
+ require_relative 'actor/version'
7
+ require_relative 'actor/proxy'
8
+
9
+ module Async
10
+ module Actor
11
+ def self.new(instance)
12
+ Proxy.new(instance)
13
+ end
14
+ end
15
+ end
data/license.md ADDED
@@ -0,0 +1,21 @@
1
+ # MIT License
2
+
3
+ Copyright, 2023, by Samuel Williams.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/readme.md ADDED
@@ -0,0 +1,33 @@
1
+ # Async::Actor
2
+
3
+ Provides a simple actor model for asynchronous programming.
4
+
5
+ [![Development Status](https://github.com/socketry/async-actor/workflows/Test/badge.svg)](https://github.com/socketry/async-actor/actions?workflow=Test)
6
+
7
+ ## Motivation
8
+
9
+ Async provides a strongly opinionated model for asynchronous programming while trying to be transparent to the user. However, in cases where the scope (life time) of the asynchronous work does not align with the scope of the application code, it can be tricky to combine the two. For example, you may want to introduce a background message queue or job processing system, which takes advantage of async, without changing the execution model of the calling code. The jobs or message queue will almost certainly outlive the scope of the calling code, so it can be advantageous to separate the two.
10
+
11
+ This is where `Async::Actor` comes in. It provides a simple actor model, which uses an event driven message queue running inside an Async event loop. This separates the life cycle of the calling code and the actor and can be used to introduce asynchronous processing into existing code with minimal changes.
12
+
13
+ ## Usage
14
+
15
+ Please see the [project documentation](https://socketry.github.io/async-actor/) for more details.
16
+
17
+ ## Contributing
18
+
19
+ We welcome contributions to this project.
20
+
21
+ 1. Fork it.
22
+ 2. Create your feature branch (`git checkout -b my-new-feature`).
23
+ 3. Commit your changes (`git commit -am 'Add some feature'`).
24
+ 4. Push to the branch (`git push origin my-new-feature`).
25
+ 5. Create new Pull Request.
26
+
27
+ ### Developer Certificate of Origin
28
+
29
+ This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
30
+
31
+ ### Contributor Covenant
32
+
33
+ This project is governed by [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
data.tar.gz.sig ADDED
Binary file
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: async-actor
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ - |
12
+ -----BEGIN CERTIFICATE-----
13
+ MIIE2DCCA0CgAwIBAgIBATANBgkqhkiG9w0BAQsFADBhMRgwFgYDVQQDDA9zYW11
14
+ ZWwud2lsbGlhbXMxHTAbBgoJkiaJk/IsZAEZFg1vcmlvbnRyYW5zZmVyMRIwEAYK
15
+ CZImiZPyLGQBGRYCY28xEjAQBgoJkiaJk/IsZAEZFgJuejAeFw0yMjA4MDYwNDUz
16
+ MjRaFw0zMjA4MDMwNDUzMjRaMGExGDAWBgNVBAMMD3NhbXVlbC53aWxsaWFtczEd
17
+ MBsGCgmSJomT8ixkARkWDW9yaW9udHJhbnNmZXIxEjAQBgoJkiaJk/IsZAEZFgJj
18
+ bzESMBAGCgmSJomT8ixkARkWAm56MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB
19
+ igKCAYEAomvSopQXQ24+9DBB6I6jxRI2auu3VVb4nOjmmHq7XWM4u3HL+pni63X2
20
+ 9qZdoq9xt7H+RPbwL28LDpDNflYQXoOhoVhQ37Pjn9YDjl8/4/9xa9+NUpl9XDIW
21
+ sGkaOY0eqsQm1pEWkHJr3zn/fxoKPZPfaJOglovdxf7dgsHz67Xgd/ka+Wo1YqoE
22
+ e5AUKRwUuvaUaumAKgPH+4E4oiLXI4T1Ff5Q7xxv6yXvHuYtlMHhYfgNn8iiW8WN
23
+ XibYXPNP7NtieSQqwR/xM6IRSoyXKuS+ZNGDPUUGk8RoiV/xvVN4LrVm9upSc0ss
24
+ RZ6qwOQmXCo/lLcDUxJAgG95cPw//sI00tZan75VgsGzSWAOdjQpFM0l4dxvKwHn
25
+ tUeT3ZsAgt0JnGqNm2Bkz81kG4A2hSyFZTFA8vZGhp+hz+8Q573tAR89y9YJBdYM
26
+ zp0FM4zwMNEUwgfRzv1tEVVUEXmoFCyhzonUUw4nE4CFu/sE3ffhjKcXcY//qiSW
27
+ xm4erY3XAgMBAAGjgZowgZcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAwHQYDVR0O
28
+ BBYEFO9t7XWuFf2SKLmuijgqR4sGDlRsMC4GA1UdEQQnMCWBI3NhbXVlbC53aWxs
29
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MC4GA1UdEgQnMCWBI3NhbXVlbC53aWxs
30
+ aWFtc0BvcmlvbnRyYW5zZmVyLmNvLm56MA0GCSqGSIb3DQEBCwUAA4IBgQB5sxkE
31
+ cBsSYwK6fYpM+hA5B5yZY2+L0Z+27jF1pWGgbhPH8/FjjBLVn+VFok3CDpRqwXCl
32
+ xCO40JEkKdznNy2avOMra6PFiQyOE74kCtv7P+Fdc+FhgqI5lMon6tt9rNeXmnW/
33
+ c1NaMRdxy999hmRGzUSFjozcCwxpy/LwabxtdXwXgSay4mQ32EDjqR1TixS1+smp
34
+ 8C/NCWgpIfzpHGJsjvmH2wAfKtTTqB9CVKLCWEnCHyCaRVuKkrKjqhYCdmMBqCws
35
+ JkxfQWC+jBVeG9ZtPhQgZpfhvh+6hMhraUYRQ6XGyvBqEUe+yo6DKIT3MtGE2+CP
36
+ eX9i9ZWBydWb8/rvmwmX2kkcBbX0hZS1rcR593hGc61JR6lvkGYQ2MYskBveyaxt
37
+ Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
38
+ voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
39
+ -----END CERTIFICATE-----
40
+ date: 2023-12-07 00:00:00.000000000 Z
41
+ dependencies:
42
+ - !ruby/object:Gem::Dependency
43
+ name: async
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - "~>"
47
+ - !ruby/object:Gem::Version
48
+ version: '1'
49
+ type: :runtime
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - "~>"
54
+ - !ruby/object:Gem::Version
55
+ version: '1'
56
+ description:
57
+ email:
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - lib/async/actor.rb
63
+ - lib/async/actor/proxy.rb
64
+ - lib/async/actor/variable.rb
65
+ - lib/async/actor/version.rb
66
+ - license.md
67
+ - readme.md
68
+ homepage: https://github.com/socketry/async-actor/
69
+ licenses:
70
+ - MIT
71
+ metadata:
72
+ documentation_uri: https://socketry.github.io/async-actor/
73
+ funding_uri: https://github.com/sponsors/ioquatix
74
+ post_install_message:
75
+ rdoc_options: []
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '3.0'
83
+ required_rubygems_version: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - ">="
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubygems_version: 3.4.22
90
+ signing_key:
91
+ specification_version: 4
92
+ summary: A multi-threaded actor implementation where each actor has it's own event
93
+ loop.
94
+ test_files: []
metadata.gz.sig ADDED
Binary file