interop 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3354d110f9c8fd23ec9681841e3403ec92b57d1d8247b2b856795f52344cc387
4
- data.tar.gz: a9ecc3aaa1428509a120c7cfba1582ff28a237abbe86898ab0a31b034e8dfd76
3
+ metadata.gz: c223f2bcb37a0232a64aada70c36947472db2cb1f3f93f4c240f8ef506521244
4
+ data.tar.gz: c138b462718e569d020a416451a89b81b8a04ed8a100cba3a528bf39b03c82f8
5
5
  SHA512:
6
- metadata.gz: 238204d49f14974ee72c8ece083866204a187788e55f3f3ad9047bf697f085480561d6f632cd183914c923605ca190cbdd6ac31b51d5cc0e9179bec149c556a3
7
- data.tar.gz: 1aa9d43425c0f37a5671947a88448289c9d9bf3775a261e7d8fbf0bca99e34909c0364bb1148fcbf47b3d6643abe75dc7558bde358be6f4906973f0b4a579cff
6
+ metadata.gz: 220ec6f89e51f1ffdc00657ff52f2a1d16a143dad472b5604c396adfb83748b3bb037203d79df524625c33b2c17232f80cf61045a05a2af6ba4a1792a41d1976
7
+ data.tar.gz: 7e24d2f42c7346248e14d04a981c0480f60746901272e9c01cbbbde442900fd2b151e02785bad850d112879d5a58abf545cf88baddc14f2f4abe39f0bc80f51c
@@ -53,7 +53,7 @@ module Hx
53
53
  end
54
54
 
55
55
  # @param [ContentType, ContentTypes] decoder
56
- def decode(decoder)
56
+ def decode(decoder = ContentType::STANDARD)
57
57
  decoder.decode self
58
58
  end
59
59
 
@@ -1,15 +1,17 @@
1
1
  require 'interop/connection'
2
2
  require 'interop/rpc/dispatcher'
3
3
  require 'interop/rpc/controller'
4
+ require 'interop/task_group'
4
5
 
5
6
  module Hx
6
7
  module Interop
7
8
  module RPC
8
9
  # Base class for RPC Client and Server
9
10
  class Base
10
- def initialize(reader, writer = reader)
11
+ def initialize(reader, writer = reader, task_group: TaskGroup.new)
11
12
  @connection = Connection.build(reader, writer)
12
13
  @dispatcher = Dispatcher.new
14
+ @tasks = task_group
13
15
  yield self if block_given?
14
16
  @io_thread = Thread.new do
15
17
  run
@@ -20,7 +22,8 @@ module Hx
20
22
 
21
23
  # TODO: custom exception handler?
22
24
 
23
- # Wait for the process to finish (i.e. for the connection to close).
25
+ # Wait for the process to finish (i.e. for the connection to close). Does not wait for running requests/event
26
+ # handlers to complete.
24
27
  def wait
25
28
  @io_thread.join
26
29
  raise @error if @error # TODO: wrap in something specific, to preserve backtrace
@@ -48,7 +51,7 @@ module Hx
48
51
 
49
52
  def run
50
53
  @connection.read_all do |request|
51
- Thread.new do
54
+ @tasks.run do
52
55
  yield request
53
56
  rescue StandardError => e
54
57
  @io_thread.raise e
@@ -0,0 +1,17 @@
1
+ module Hx
2
+ module Interop
3
+ # Base class for StreamReader and StreamWriter
4
+ class StreamAdapter
5
+ # @param [IO, StringIO] stream
6
+ def initialize(stream)
7
+ if stream.is_a? IO
8
+ stream.sync = true
9
+ stream.binmode
10
+ end
11
+
12
+ @stream = stream
13
+ @mutex = Mutex.new
14
+ end
15
+ end
16
+ end
17
+ end
@@ -2,22 +2,17 @@ require 'set'
2
2
 
3
3
  require 'interop/message'
4
4
  require 'interop/reader'
5
+ require 'interop/stream_adapter'
5
6
 
6
7
  module Hx
7
8
  module Interop
8
9
  # Reads messages from a stream (e.g. STDIN)
9
- class StreamReader
10
+ class StreamReader < StreamAdapter
10
11
  include Reader
11
12
 
12
13
  # Acceptable line terminators
13
14
  NEWLINES = Set.new(%W[\n \r\n]).freeze
14
15
 
15
- # @param [IO, StringIO] stream
16
- def initialize(stream)
17
- @stream = stream
18
- @mutex = Mutex.new
19
- end
20
-
21
16
  protected
22
17
 
23
18
  def _read
@@ -1,18 +1,13 @@
1
1
  require 'interop/message'
2
2
  require 'interop/writer'
3
+ require 'interop/stream_adapter'
3
4
 
4
5
  module Hx
5
6
  module Interop
6
7
  # Writes messages to a stream (e.g. STDOUT)
7
- class StreamWriter
8
+ class StreamWriter < StreamAdapter
8
9
  include Writer
9
10
 
10
- # @param [IO, StringIO] stream
11
- def initialize(stream)
12
- @stream = stream
13
- @mutex = Mutex.new
14
- end
15
-
16
11
  protected
17
12
 
18
13
  # @param [Message] message
@@ -0,0 +1,32 @@
1
+ module Hx
2
+ module Interop
3
+ # Allows blocking on running tasks
4
+ class TaskGroup
5
+ def initialize
6
+ @count = 0
7
+ @mutex = Mutex.new
8
+ @condition = ConditionVariable.new
9
+ end
10
+
11
+ # Run the given block in a new thread. Calls to #wait will block until it has finished running.
12
+ def run
13
+ @mutex.synchronize { @count += 1 }
14
+ Thread.new do
15
+ yield
16
+ ensure
17
+ @mutex.synchronize do
18
+ @count -= 1
19
+ @condition.broadcast if @count.zero?
20
+ end
21
+ end
22
+ end
23
+
24
+ # Block until all threads created by #run have finished.
25
+ def wait
26
+ @mutex.synchronize do
27
+ @condition.wait(@mutex) while @count.positive?
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,5 +1,5 @@
1
1
  module Hx
2
2
  module Interop
3
- VERSION = '0.3.0'.freeze
3
+ VERSION = '0.4.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: interop
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Neil E. Pearson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2021-08-19 00:00:00.000000000 Z
11
+ date: 2022-10-04 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Ruby implementation of hx/interop cross-language interop abstraction
14
14
  email:
@@ -40,8 +40,10 @@ files:
40
40
  - lib/interop/rpc/dispatcher.rb
41
41
  - lib/interop/rpc/magic.rb
42
42
  - lib/interop/rpc/server.rb
43
+ - lib/interop/stream_adapter.rb
43
44
  - lib/interop/stream_reader.rb
44
45
  - lib/interop/stream_writer.rb
46
+ - lib/interop/task_group.rb
45
47
  - lib/interop/version.rb
46
48
  - lib/interop/writer.rb
47
49
  homepage: https://github.com/hx/interop