async-service 0.13.0 → 0.14.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/agent.md +129 -0
- data/context/best-practices.md +320 -0
- data/context/getting-started.md +190 -0
- data/context/index.yaml +20 -0
- data/context/service-architecture.md +499 -0
- data/lib/async/service/configuration.rb +12 -0
- data/lib/async/service/container_environment.rb +42 -0
- data/lib/async/service/container_service.rb +77 -0
- data/lib/async/service/controller.rb +20 -0
- data/lib/async/service/environment.rb +59 -1
- data/lib/async/service/formatting.rb +84 -0
- data/lib/async/service/generic.rb +43 -4
- data/lib/async/service/loader.rb +2 -0
- data/lib/async/service/version.rb +2 -2
- data/lib/async/service.rb +7 -0
- data/readme.md +68 -1
- data/releases.md +85 -0
- data.tar.gz.sig +0 -0
- metadata +13 -4
- metadata.gz.sig +0 -0
@@ -5,8 +5,17 @@
|
|
5
5
|
|
6
6
|
module Async
|
7
7
|
module Service
|
8
|
+
# Represents a service configuration with lazy evaluation and module composition.
|
9
|
+
#
|
10
|
+
# Environments store configuration as methods that can be overridden and composed using Ruby modules. They support lazy evaluation through evaluators.
|
8
11
|
class Environment
|
12
|
+
# A builder for constructing environments using a DSL.
|
9
13
|
class Builder < BasicObject
|
14
|
+
# Create a new environment with facets and values.
|
15
|
+
# @parameter facets [Array(Module)] Modules to include in the environment.
|
16
|
+
# @parameter values [Hash] Key-value pairs to define as methods.
|
17
|
+
# @parameter block [Proc] A block for additional configuration.
|
18
|
+
# @returns [Module] The constructed environment module.
|
10
19
|
def self.for(*facets, **values, &block)
|
11
20
|
top = ::Module.new
|
12
21
|
|
@@ -46,10 +55,14 @@ module Async
|
|
46
55
|
return top
|
47
56
|
end
|
48
57
|
|
58
|
+
# Initialize a new builder.
|
59
|
+
# @parameter facet [Module] The module to build into, defaults to a new `Module`.
|
49
60
|
def initialize(facet = ::Module.new)
|
50
61
|
@facet = facet
|
51
62
|
end
|
52
63
|
|
64
|
+
# Include a module or other includable object into the environment.
|
65
|
+
# @parameter target [Module] The module to include.
|
53
66
|
def include(target)
|
54
67
|
if target.class == ::Module
|
55
68
|
@facet.include(target)
|
@@ -60,6 +73,10 @@ module Async
|
|
60
73
|
end
|
61
74
|
end
|
62
75
|
|
76
|
+
# Define methods dynamically on the environment.
|
77
|
+
# @parameter name [Symbol] The method name to define.
|
78
|
+
# @parameter argument [Object] The value to return from the method.
|
79
|
+
# @parameter block [Proc] A block to use as the method implementation.
|
63
80
|
def method_missing(name, argument = nil, &block)
|
64
81
|
if block
|
65
82
|
@facet.define_method(name, &block)
|
@@ -68,15 +85,25 @@ module Async
|
|
68
85
|
end
|
69
86
|
end
|
70
87
|
|
88
|
+
# Always respond to missing methods for dynamic method definition.
|
89
|
+
# @parameter name [Symbol] The method name.
|
90
|
+
# @parameter include_private [Boolean] Whether to include private methods.
|
91
|
+
# @returns [Boolean] Always true to enable dynamic method definition.
|
71
92
|
def respond_to_missing?(name, include_private = false)
|
72
93
|
true
|
73
94
|
end
|
74
95
|
end
|
75
96
|
|
97
|
+
# Build a new environment using the builder DSL.
|
98
|
+
# @parameter arguments [Array] Arguments passed to Builder.for
|
99
|
+
# @returns [Environment] A new environment instance.
|
76
100
|
def self.build(...)
|
77
101
|
Environment.new(Builder.for(...))
|
78
102
|
end
|
79
103
|
|
104
|
+
# Initialize a new environment.
|
105
|
+
# @parameter facet [Module] The facet module containing the configuration methods.
|
106
|
+
# @parameter parent [Environment | Nil] The parent environment for inheritance.
|
80
107
|
def initialize(facet = ::Module.new, parent = nil)
|
81
108
|
unless facet.class == ::Module
|
82
109
|
raise ArgumentError, "Facet must be a module!"
|
@@ -92,21 +119,32 @@ module Async
|
|
92
119
|
# @attribute [Environment | Nil] The parent environment, if any.
|
93
120
|
attr :parent
|
94
121
|
|
122
|
+
# Include this environment's facet into a target module.
|
123
|
+
# @parameter target [Module] The target module to include into.
|
95
124
|
def included(target)
|
96
125
|
@parent&.included(target)
|
97
126
|
target.include(@facet)
|
98
127
|
end
|
99
128
|
|
129
|
+
# Create a new environment with additional configuration.
|
130
|
+
# @parameter arguments [Array] Arguments passed to Environment.build.
|
131
|
+
# @returns [Environment] A new environment with this as parent.
|
100
132
|
def with(...)
|
101
133
|
return self.class.new(Builder.for(...), self)
|
102
134
|
end
|
103
135
|
|
136
|
+
# Check if this environment implements a given interface.
|
137
|
+
# @parameter interface [Module] The interface to check.
|
138
|
+
# @returns [Boolean] True if this environment implements the interface.
|
104
139
|
def implements?(interface)
|
105
140
|
@facet <= interface
|
106
141
|
end
|
107
142
|
|
108
143
|
# An evaluator is lazy read-only view of an environment. It memoizes all method calls.
|
109
144
|
class Evaluator
|
145
|
+
# Create an evaluator wrapper for an environment.
|
146
|
+
# @parameter environment [Environment] The environment to wrap.
|
147
|
+
# @returns [Evaluator] A new evaluator instance.
|
110
148
|
def self.wrap(environment)
|
111
149
|
evaluator = ::Class.new(self)
|
112
150
|
|
@@ -137,14 +175,19 @@ module Async
|
|
137
175
|
return evaluator.new
|
138
176
|
end
|
139
177
|
|
178
|
+
# Initialize a new evaluator.
|
140
179
|
def initialize
|
141
180
|
@cache = {}
|
142
181
|
end
|
143
182
|
|
183
|
+
# Inspect representation of the evaluator.
|
184
|
+
# @returns [String] A string representation of the evaluator with its keys.
|
144
185
|
def inspect
|
145
186
|
"#<#{Evaluator} #{self.keys}>"
|
146
187
|
end
|
147
188
|
|
189
|
+
# Convert the evaluator to a hash.
|
190
|
+
# @returns [Hash] A hash with all evaluated keys and values.
|
148
191
|
def to_h
|
149
192
|
# Ensure all keys are evaluated:
|
150
193
|
self.keys.each do |name|
|
@@ -154,23 +197,38 @@ module Async
|
|
154
197
|
return @cache
|
155
198
|
end
|
156
199
|
|
200
|
+
# Convert the evaluator to JSON.
|
201
|
+
# @parameter arguments [Array] Arguments passed to to_json.
|
202
|
+
# @returns [String] A JSON representation of the evaluator.
|
157
203
|
def to_json(...)
|
158
204
|
self.to_h.to_json(...)
|
159
205
|
end
|
160
206
|
|
207
|
+
# Get value for a given key.
|
208
|
+
# @parameter key [Symbol] The key to look up.
|
209
|
+
# @returns [Object, nil] The value for the key, or nil if not found.
|
161
210
|
def [](key)
|
162
|
-
self.
|
211
|
+
if self.key?(key)
|
212
|
+
self.__send__(key)
|
213
|
+
end
|
163
214
|
end
|
164
215
|
|
216
|
+
# Check if a key is available.
|
217
|
+
# @parameter key [Symbol] The key to check.
|
218
|
+
# @returns [Boolean] True if the key exists.
|
165
219
|
def key?(key)
|
166
220
|
self.keys.include?(key)
|
167
221
|
end
|
168
222
|
end
|
169
223
|
|
224
|
+
# Create an evaluator for this environment.
|
225
|
+
# @returns [Evaluator] A lazy evaluator for this environment.
|
170
226
|
def evaluator
|
171
227
|
return Evaluator.wrap(self)
|
172
228
|
end
|
173
229
|
|
230
|
+
# Convert the environment to a hash.
|
231
|
+
# @returns [Hash] A hash representation of the environment.
|
174
232
|
def to_h
|
175
233
|
evaluator.to_h
|
176
234
|
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Released under the MIT License.
|
4
|
+
# Copyright, 2025, by Samuel Williams.
|
5
|
+
|
6
|
+
module Async
|
7
|
+
module Service
|
8
|
+
# Formatting utilities for service titles.
|
9
|
+
#
|
10
|
+
# Services need meaningful process/thread names for monitoring and debugging. This module provides consistent formatting for common service metrics like connection counts, request ratios, and load values in process titles.
|
11
|
+
#
|
12
|
+
# It is expected you will include these into your service class and use them to update the `instance.name` in the health check.
|
13
|
+
module Formatting
|
14
|
+
UNITS = [nil, "K", "M", "B", "T", "P", "E", "Z", "Y"]
|
15
|
+
|
16
|
+
# Format a count into a human-readable string.
|
17
|
+
# @parameter value [Numeric] The count to format.
|
18
|
+
# @parameter units [Array] The units to use for formatting (default: UNITS).
|
19
|
+
# @returns [String] A formatted string representing the count.
|
20
|
+
def format_count(value, units = UNITS)
|
21
|
+
value = value.to_f
|
22
|
+
index = 0
|
23
|
+
limit = units.size - 1
|
24
|
+
|
25
|
+
# Handle negative numbers by working with absolute value:
|
26
|
+
negative = value < 0
|
27
|
+
value = value.abs
|
28
|
+
|
29
|
+
while value >= 1000 and index < limit
|
30
|
+
value = value / 1000
|
31
|
+
index += 1
|
32
|
+
end
|
33
|
+
|
34
|
+
result = String.new
|
35
|
+
result << "-" if negative
|
36
|
+
result << value.round(2).to_s
|
37
|
+
result << units[index].to_s if units[index]
|
38
|
+
|
39
|
+
return result
|
40
|
+
end
|
41
|
+
|
42
|
+
module_function :format_count
|
43
|
+
|
44
|
+
# Format a ratio as "current/total" with human-readable counts.
|
45
|
+
# @parameter current [Numeric] The current value.
|
46
|
+
# @parameter total [Numeric] The total value.
|
47
|
+
# @returns [String] A formatted ratio string.
|
48
|
+
def format_ratio(current, total)
|
49
|
+
"#{format_count(current)}/#{format_count(total)}"
|
50
|
+
end
|
51
|
+
|
52
|
+
module_function :format_ratio
|
53
|
+
|
54
|
+
# Format a load value as a decimal with specified precision.
|
55
|
+
# @parameter load [Numeric] The load value (typically 0.0 to 1.0+).
|
56
|
+
# @returns [String] A formatted load string.
|
57
|
+
def format_load(load)
|
58
|
+
load.round(2).to_s
|
59
|
+
end
|
60
|
+
|
61
|
+
module_function :format_load
|
62
|
+
|
63
|
+
# Format multiple statistics into a compact string.
|
64
|
+
# @parameter stats [Hash] Hash of statistic names to values or [current, total] arrays.
|
65
|
+
# @returns [String] A formatted statistics string.
|
66
|
+
def format_statistics(**pairs)
|
67
|
+
pairs.map do |key, value|
|
68
|
+
case value
|
69
|
+
when Array
|
70
|
+
if value.length == 2
|
71
|
+
"#{key.to_s.upcase}=#{format_ratio(value[0], value[1])}"
|
72
|
+
else
|
73
|
+
"#{key.to_s.upcase}=#{value.join('/')}"
|
74
|
+
end
|
75
|
+
else
|
76
|
+
"#{key.to_s.upcase}=#{format_count(value)}"
|
77
|
+
end
|
78
|
+
end.join(" ")
|
79
|
+
end
|
80
|
+
|
81
|
+
module_function :format_statistics
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -11,7 +11,7 @@ module Async
|
|
11
11
|
# Designed to be invoked within an {Async::Controller::Container}.
|
12
12
|
class Generic
|
13
13
|
# Convert the given environment into a service if possible.
|
14
|
-
# @parameter environment [
|
14
|
+
# @parameter environment [Environment] The environment to use to construct the service.
|
15
15
|
# @returns [Generic | Nil] The constructed service if the environment specifies a service class.
|
16
16
|
def self.wrap(environment)
|
17
17
|
evaluator = environment.evaluator
|
@@ -24,12 +24,17 @@ module Async
|
|
24
24
|
end
|
25
25
|
|
26
26
|
# Initialize the service from the given environment.
|
27
|
-
# @parameter environment [
|
27
|
+
# @parameter environment [Environment]
|
28
28
|
def initialize(environment, evaluator = environment.evaluator)
|
29
29
|
@environment = environment
|
30
30
|
@evaluator = evaluator
|
31
31
|
end
|
32
32
|
|
33
|
+
# @attribute [Environment] The environment which is used to configure the service.
|
34
|
+
attr :environment
|
35
|
+
|
36
|
+
# Convert the service evaluator to a hash.
|
37
|
+
# @returns [Hash] A hash representation of the evaluator.
|
33
38
|
def to_h
|
34
39
|
@evaluator.to_h
|
35
40
|
end
|
@@ -40,7 +45,7 @@ module Async
|
|
40
45
|
@evaluator.name
|
41
46
|
end
|
42
47
|
|
43
|
-
# Start the service.
|
48
|
+
# Start the service. Called before the container setup.
|
44
49
|
def start
|
45
50
|
Console.debug(self) {"Starting service #{self.name}..."}
|
46
51
|
end
|
@@ -51,10 +56,44 @@ module Async
|
|
51
56
|
Console.debug(self) {"Setting up service #{self.name}..."}
|
52
57
|
end
|
53
58
|
|
54
|
-
# Stop the service.
|
59
|
+
# Stop the service. Called after the container is stopped.
|
55
60
|
def stop(graceful = true)
|
56
61
|
Console.debug(self) {"Stopping service #{self.name}..."}
|
57
62
|
end
|
63
|
+
|
64
|
+
protected
|
65
|
+
|
66
|
+
# Start the health checker.
|
67
|
+
#
|
68
|
+
# If a timeout is specified, a transient child task will be scheduled, which will yield the instance if a block is given, then mark the instance as ready, and finally sleep for half the health check duration (so that we guarantee that the health check runs in time).
|
69
|
+
#
|
70
|
+
# If a timeout is not specified, the health checker will yield the instance immediately and then mark the instance as ready.
|
71
|
+
#
|
72
|
+
# @parameter instance [Object] The service instance to check.
|
73
|
+
# @parameter timeout [Numeric] The timeout duration for the health check.
|
74
|
+
# @parameter parent [Async::Task] The parent task to run the health checker in.
|
75
|
+
# @yields {|instance| ...} If a block is given, it will be called with the service instance at least once.
|
76
|
+
def health_checker(instance, timeout = @evaluator.health_check_timeout, parent: Async::Task.current, &block)
|
77
|
+
if timeout
|
78
|
+
parent.async(transient: true) do
|
79
|
+
while true
|
80
|
+
if block_given?
|
81
|
+
yield(instance)
|
82
|
+
end
|
83
|
+
|
84
|
+
instance.ready!
|
85
|
+
|
86
|
+
sleep(timeout / 2)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
else
|
90
|
+
if block_given?
|
91
|
+
yield(instance)
|
92
|
+
end
|
93
|
+
|
94
|
+
instance.ready!
|
95
|
+
end
|
96
|
+
end
|
58
97
|
end
|
59
98
|
end
|
60
99
|
end
|
data/lib/async/service/loader.rb
CHANGED
@@ -38,6 +38,8 @@ module Async
|
|
38
38
|
loader.instance_eval(File.read(path), path)
|
39
39
|
end
|
40
40
|
|
41
|
+
# Load a file relative to the loader's root directory.
|
42
|
+
# @parameter path [String] The path to the file to load.
|
41
43
|
def load_file(path)
|
42
44
|
Loader.load_file(@configuration, File.expand_path(path, @root))
|
43
45
|
end
|
data/lib/async/service.rb
CHANGED
data/readme.md
CHANGED
@@ -1,9 +1,76 @@
|
|
1
1
|
# Async::Service
|
2
2
|
|
3
|
-
Provides a simple service interface for configuring and running services.
|
3
|
+
Provides a simple service interface for configuring and running asynchronous services in Ruby.
|
4
4
|
|
5
5
|
[](https://github.com/socketry/async-service/actions?workflow=Test)
|
6
6
|
|
7
|
+
## Features
|
8
|
+
|
9
|
+
- **Service Management**: Define, configure, and run long-running services.
|
10
|
+
- **Container Integration**: Built on `async-container` for robust process management.
|
11
|
+
- **Multiple Services**: Run and coordinate multiple services together.
|
12
|
+
- **Automatic Restart**: Services automatically restart on failure.
|
13
|
+
- **Graceful Shutdown**: Clean shutdown handling with proper resource cleanup.
|
14
|
+
- **Environment Configuration**: Configure services with environment variables and settings.
|
15
|
+
|
16
|
+
## Usage
|
17
|
+
|
18
|
+
Please see the [project documentation](https://socketry.github.io/async-service/) for more details.
|
19
|
+
|
20
|
+
- [Getting Started](https://socketry.github.io/async-service/guides/getting-started/index) - This guide explains how to get started with `async-service` to create and run services in Ruby.
|
21
|
+
|
22
|
+
- [Service Architecture](https://socketry.github.io/async-service/guides/service-architecture/index) - This guide explains the key architectural components of `async-service` and how they work together to provide a clean separation of concerns.
|
23
|
+
|
24
|
+
- [Best Practices](https://socketry.github.io/async-service/guides/best-practices/index) - This guide outlines recommended patterns and practices for building robust, maintainable services with `async-service`.
|
25
|
+
|
26
|
+
## Releases
|
27
|
+
|
28
|
+
Please see the [project releases](https://socketry.github.io/async-service/releases/index) for all releases.
|
29
|
+
|
30
|
+
### v0.14.0
|
31
|
+
|
32
|
+
- Introduce `ContainerEnvironment` and `ContainerService` for implementing best-practice services.
|
33
|
+
|
34
|
+
### v0.13.0
|
35
|
+
|
36
|
+
- Fix null services handling.
|
37
|
+
- Modernize code and improve documentation.
|
38
|
+
- Make service name optional and improve code comments.
|
39
|
+
- Add `respond_to_missing?` for completeness.
|
40
|
+
|
41
|
+
### v0.12.0
|
42
|
+
|
43
|
+
- Add convenient `Configuration.build{...}` method for constructing inline configurations.
|
44
|
+
|
45
|
+
### v0.11.0
|
46
|
+
|
47
|
+
- Allow builder with argument for more flexible configuration construction.
|
48
|
+
|
49
|
+
### v0.10.0
|
50
|
+
|
51
|
+
- Add `Environment::Evaluator#as_json` for JSON serialization support.
|
52
|
+
- Allow constructing a configuration with existing environments.
|
53
|
+
|
54
|
+
### v0.9.0
|
55
|
+
|
56
|
+
- Allow providing a list of modules to include in environments.
|
57
|
+
|
58
|
+
### v0.8.0
|
59
|
+
|
60
|
+
- Introduce `Environment#implements?` and related methods for interface checking.
|
61
|
+
|
62
|
+
### v0.7.0
|
63
|
+
|
64
|
+
- Allow instance methods that take arguments in environments.
|
65
|
+
|
66
|
+
### v0.6.1
|
67
|
+
|
68
|
+
- Fix requirement that facet must be a module.
|
69
|
+
|
70
|
+
### v0.6.0
|
71
|
+
|
72
|
+
- Unify construction of environments for better consistency.
|
73
|
+
|
7
74
|
## Contributing
|
8
75
|
|
9
76
|
We welcome contributions to this project.
|
data/releases.md
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
# Releases
|
2
|
+
|
3
|
+
## v0.14.0
|
4
|
+
|
5
|
+
- Introduce `ContainerEnvironment` and `ContainerService` for implementing best-practice services.
|
6
|
+
|
7
|
+
## v0.13.0
|
8
|
+
|
9
|
+
- Fix null services handling.
|
10
|
+
- Modernize code and improve documentation.
|
11
|
+
- Make service name optional and improve code comments.
|
12
|
+
- Add `respond_to_missing?` for completeness.
|
13
|
+
|
14
|
+
## v0.12.0
|
15
|
+
|
16
|
+
- Add convenient `Configuration.build{...}` method for constructing inline configurations.
|
17
|
+
|
18
|
+
## v0.11.0
|
19
|
+
|
20
|
+
- Allow builder with argument for more flexible configuration construction.
|
21
|
+
|
22
|
+
## v0.10.0
|
23
|
+
|
24
|
+
- Add `Environment::Evaluator#as_json` for JSON serialization support.
|
25
|
+
- Allow constructing a configuration with existing environments.
|
26
|
+
|
27
|
+
## v0.9.0
|
28
|
+
|
29
|
+
- Allow providing a list of modules to include in environments.
|
30
|
+
|
31
|
+
## v0.8.0
|
32
|
+
|
33
|
+
- Introduce `Environment#implements?` and related methods for interface checking.
|
34
|
+
|
35
|
+
## v0.7.0
|
36
|
+
|
37
|
+
- Allow instance methods that take arguments in environments.
|
38
|
+
|
39
|
+
## v0.6.1
|
40
|
+
|
41
|
+
- Fix requirement that facet must be a module.
|
42
|
+
|
43
|
+
## v0.6.0
|
44
|
+
|
45
|
+
- Unify construction of environments for better consistency.
|
46
|
+
|
47
|
+
## v0.5.1
|
48
|
+
|
49
|
+
- Relax dependency on async-container for better compatibility.
|
50
|
+
|
51
|
+
## v0.5.0
|
52
|
+
|
53
|
+
- Add support for passing through options to controllers.
|
54
|
+
|
55
|
+
## v0.4.0
|
56
|
+
|
57
|
+
- Reuse evaluator for service instances for better performance.
|
58
|
+
- Expose `Configuration.load` and `Controller.start` for better composition.
|
59
|
+
- Add simple service example.
|
60
|
+
|
61
|
+
## v0.3.1
|
62
|
+
|
63
|
+
- Fix usage of `raise` in `BasicObject` context.
|
64
|
+
|
65
|
+
## v0.3.0
|
66
|
+
|
67
|
+
- Use modules for environments instead of basic objects.
|
68
|
+
- Allow non-modules to be included in environments.
|
69
|
+
|
70
|
+
## v0.2.1
|
71
|
+
|
72
|
+
- Add missing call to `super` in service implementations.
|
73
|
+
|
74
|
+
## v0.2.0
|
75
|
+
|
76
|
+
- Add support for loading other configuration files.
|
77
|
+
- Minor bug fixes and improvements.
|
78
|
+
|
79
|
+
## v0.1.0
|
80
|
+
|
81
|
+
- Initial release with core service framework.
|
82
|
+
- Environment abstraction for service configuration.
|
83
|
+
- Improved evaluator implementation with comprehensive tests.
|
84
|
+
- Controller for handling service execution.
|
85
|
+
- Support for explicit `service_class` configuration.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: async-service
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -36,7 +36,7 @@ cert_chain:
|
|
36
36
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
37
37
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
38
38
|
-----END CERTIFICATE-----
|
39
|
-
date:
|
39
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
40
40
|
dependencies:
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: async
|
@@ -71,16 +71,25 @@ executables:
|
|
71
71
|
extensions: []
|
72
72
|
extra_rdoc_files: []
|
73
73
|
files:
|
74
|
+
- agent.md
|
74
75
|
- bin/async-service
|
76
|
+
- context/best-practices.md
|
77
|
+
- context/getting-started.md
|
78
|
+
- context/index.yaml
|
79
|
+
- context/service-architecture.md
|
75
80
|
- lib/async/service.rb
|
76
81
|
- lib/async/service/configuration.rb
|
82
|
+
- lib/async/service/container_environment.rb
|
83
|
+
- lib/async/service/container_service.rb
|
77
84
|
- lib/async/service/controller.rb
|
78
85
|
- lib/async/service/environment.rb
|
86
|
+
- lib/async/service/formatting.rb
|
79
87
|
- lib/async/service/generic.rb
|
80
88
|
- lib/async/service/loader.rb
|
81
89
|
- lib/async/service/version.rb
|
82
90
|
- license.md
|
83
91
|
- readme.md
|
92
|
+
- releases.md
|
84
93
|
homepage: https://github.com/socketry/async-service
|
85
94
|
licenses:
|
86
95
|
- MIT
|
@@ -94,14 +103,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
94
103
|
requirements:
|
95
104
|
- - ">="
|
96
105
|
- !ruby/object:Gem::Version
|
97
|
-
version: '3.
|
106
|
+
version: '3.2'
|
98
107
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
108
|
requirements:
|
100
109
|
- - ">="
|
101
110
|
- !ruby/object:Gem::Version
|
102
111
|
version: '0'
|
103
112
|
requirements: []
|
104
|
-
rubygems_version: 3.6.
|
113
|
+
rubygems_version: 3.6.9
|
105
114
|
specification_version: 4
|
106
115
|
summary: A service layer for Async.
|
107
116
|
test_files: []
|
metadata.gz.sig
CHANGED
Binary file
|