volucer-worker 0.1.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.
data/lib/volucer.rb ADDED
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ # A Ruby worker SDK for volucer's worker protocol.
4
+ #
5
+ # The specification is `docs/worker-protocol.md` in `sailantis/volucer`; this package is the
6
+ # other end of it, beside the PHP one in `sailantis/volucer-php-sdk` and the Python one in
7
+ # `sailantis/volucer-python-sdk`.
8
+ #
9
+ # The ordinary use is three lines:
10
+ #
11
+ # require 'volucer'
12
+ # require 'my_app' # a Rack application
13
+ #
14
+ # Volucer::Worker.connect.run(&Volucer::Rack.handler(MyApp.new))
15
+ #
16
+ # Requiring this file **reassigns `$stdout` to `$stderr`**, and that is deliberate rather
17
+ # than surprising once the reason is known: the worker protocol uses the child process's
18
+ # stdout as its channel, so anything an application `puts` would land inside a frame and
19
+ # desynchronise the stream permanently. The PHP SDK solves the same problem with an output
20
+ # buffer and the Python SDK by rebinding `sys.stdout`; this is Ruby's version of the same
21
+ # decision. The real channel is kept in `Volucer::CHANNEL_OUT` and `Volucer::CHANNEL_IN`.
22
+
23
+ require_relative 'volucer/version'
24
+ require_relative 'volucer/protocol'
25
+ require_relative 'volucer/message'
26
+ require_relative 'volucer/grpc'
27
+ require_relative 'volucer/rpc'
28
+ require_relative 'volucer/services'
29
+ require_relative 'volucer/worker'
30
+ require_relative 'volucer/rack'
31
+ require_relative 'volucer/supervisor'
32
+
33
+ module Volucer
34
+ # The protocol channel, captured before `$stdout` is reassigned.
35
+ CHANNEL_OUT = $stdout
36
+
37
+ # The protocol channel, captured before `$stdin` could be wrapped by anything.
38
+ CHANNEL_IN = $stdin
39
+
40
+ # A `$stdout` that cannot corrupt the worker channel.
41
+ #
42
+ # Writes go to `$stderr`, which is not part of the protocol and is drained by the
43
+ # supervisor. An application's `puts` therefore still reaches a human, just not the wire.
44
+ class GuardedStdout
45
+ def initialize(err = $stderr)
46
+ @err = err
47
+ end
48
+
49
+ def write(*objects)
50
+ written = 0
51
+ objects.each { |object| written += @err.write(object.to_s) }
52
+ written
53
+ end
54
+
55
+ def <<(object)
56
+ @err.write(object.to_s)
57
+ self
58
+ end
59
+
60
+ def print(*objects)
61
+ objects.each { |object| @err.write(object.to_s) }
62
+ nil
63
+ end
64
+
65
+ def printf(format, *args)
66
+ @err.write(format(format, *args))
67
+ nil
68
+ end
69
+
70
+ def puts(*objects)
71
+ @err.puts(*objects)
72
+ nil
73
+ end
74
+
75
+ def flush
76
+ @err.flush
77
+ self
78
+ end
79
+
80
+ def sync
81
+ true
82
+ end
83
+
84
+ def sync=(value); end
85
+
86
+ def tty?
87
+ false
88
+ end
89
+
90
+ def isatty
91
+ false
92
+ end
93
+
94
+ def fileno
95
+ # Deliberately the *real* stderr descriptor rather than stdout's, so a library that
96
+ # does fd-level writes lands in the same place as everything else.
97
+ @err.fileno
98
+ end
99
+
100
+ def close; end
101
+
102
+ def closed?
103
+ false
104
+ end
105
+ end
106
+ end
107
+
108
+ # Reassign `$stdout`, keeping the real channel in `Volucer::CHANNEL_OUT`. Done at load rather
109
+ # than at worker construction, because construction reads the constant and the two must not
110
+ # be able to be confused.
111
+ $stdout = Volucer::GuardedStdout.new($stderr) unless $stdout.is_a?(Volucer::GuardedStdout)
metadata ADDED
@@ -0,0 +1,58 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: volucer-worker
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sailantis
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: |
13
+ The Ruby end of volucer's worker protocol. The specification is
14
+ `docs/worker-protocol.md` in sailantis/volucer; this gem implements it beside the PHP
15
+ and Python SDKs. Includes a Rack adapter, CALL/RETURN and JOB support, an `[rpc]` client
16
+ for applications that are not workers, and no runtime dependencies beyond the standard
17
+ library.
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - LICENSE
23
+ - README.md
24
+ - lib/volucer.rb
25
+ - lib/volucer/grpc.rb
26
+ - lib/volucer/message.rb
27
+ - lib/volucer/protocol.rb
28
+ - lib/volucer/rack.rb
29
+ - lib/volucer/rpc.rb
30
+ - lib/volucer/services.rb
31
+ - lib/volucer/supervisor.rb
32
+ - lib/volucer/version.rb
33
+ - lib/volucer/worker.rb
34
+ homepage: https://github.com/sailantis/volucer-ruby-sdk
35
+ licenses:
36
+ - MIT
37
+ metadata:
38
+ homepage_uri: https://github.com/sailantis/volucer-ruby-sdk
39
+ source_code_uri: https://github.com/sailantis/volucer-ruby-sdk
40
+ documentation_uri: https://github.com/sailantis/volucer/blob/main/docs/worker-protocol.md
41
+ rdoc_options: []
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '3.1'
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ requirements: []
55
+ rubygems_version: 4.0.20
56
+ specification_version: 4
57
+ summary: A Ruby worker SDK for the volucer worker protocol
58
+ test_files: []