fluent-plugin-kinesis 1.3.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -23
- data/CHANGELOG.md +13 -0
- data/Gemfile +9 -9
- data/LICENSE.txt +201 -40
- data/Makefile +24 -31
- data/README.md +179 -308
- data/Rakefile +9 -13
- data/benchmark/task.rake +96 -58
- data/fluent-plugin-kinesis.gemspec +15 -19
- data/gemfiles/Gemfile.fluentd-0.12 +10 -10
- data/lib/fluent/plugin/kinesis.rb +166 -0
- data/lib/fluent/plugin/kinesis_helper/aggregator.rb +99 -0
- data/lib/fluent/plugin/kinesis_helper/api.rb +152 -121
- data/lib/fluent/plugin/kinesis_helper/client.rb +125 -12
- data/lib/fluent/plugin/out_kinesis_firehose.rb +40 -27
- data/lib/fluent/plugin/out_kinesis_streams.rb +51 -30
- data/lib/fluent/plugin/out_kinesis_streams_aggregated.rb +76 -0
- data/lib/fluent_plugin_kinesis/version.rb +10 -10
- metadata +18 -70
- data/README-v0.4.md +0 -348
- data/benchmark/dummy.conf +0 -0
- data/gemfiles/Gemfile.aws-sdk-2.4 +0 -20
- data/gemfiles/Gemfile.fluentd-0.10.58 +0 -20
- data/gemfiles/Gemfile.fluentd-0.14.11 +0 -20
- data/gemfiles/Gemfile.ruby-2.0 +0 -21
- data/gemfiles/Gemfile.ruby-2.1 +0 -21
- data/lib/fluent/plugin/kinesis_helper.rb +0 -36
- data/lib/fluent/plugin/kinesis_helper/class_methods.rb +0 -123
- data/lib/fluent/plugin/kinesis_helper/credentials.rb +0 -51
- data/lib/fluent/plugin/kinesis_helper/error.rb +0 -43
- data/lib/fluent/plugin/kinesis_helper/format.rb +0 -85
- data/lib/fluent/plugin/kinesis_helper/initialize.rb +0 -59
- data/lib/fluent/plugin/kinesis_helper/kpl.rb +0 -82
- data/lib/fluent/plugin/out_kinesis.rb +0 -323
- data/lib/fluent/plugin/out_kinesis_producer.rb +0 -48
- data/lib/fluent/plugin/patched_detach_process_impl.rb +0 -103
- data/lib/kinesis_producer.rb +0 -24
- data/lib/kinesis_producer/binary.rb +0 -10
- data/lib/kinesis_producer/daemon.rb +0 -270
- data/lib/kinesis_producer/library.rb +0 -122
- data/lib/kinesis_producer/protobuf/config.pb.rb +0 -66
- data/lib/kinesis_producer/protobuf/messages.pb.rb +0 -151
- data/lib/kinesis_producer/tasks/binary.rake +0 -73
@@ -1,36 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Amazon Software License (the "License").
|
5
|
-
# You may not use this file except in compliance with the License.
|
6
|
-
# A copy of the License is located at
|
7
|
-
#
|
8
|
-
# http://aws.amazon.com/asl/
|
9
|
-
#
|
10
|
-
# or in the "license" file accompanying this file. This file is distributed
|
11
|
-
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
-
# express or implied. See the License for the specific language governing
|
13
|
-
# permissions and limitations under the License.
|
14
|
-
|
15
|
-
require 'fluent/plugin/kinesis_helper/class_methods'
|
16
|
-
require 'fluent/plugin/kinesis_helper/initialize'
|
17
|
-
require 'fluent/plugin/kinesis_helper/error'
|
18
|
-
|
19
|
-
module Fluent
|
20
|
-
module KinesisHelper
|
21
|
-
include Fluent::SetTimeKeyMixin
|
22
|
-
include Fluent::SetTagKeyMixin
|
23
|
-
# detach_multi_process has been deleted at 0.14.12
|
24
|
-
# https://github.com/fluent/fluentd/commit/fcd8cc18e1f3a95710a80f982b91a1414fadc432
|
25
|
-
require 'fluent/version'
|
26
|
-
if Gem::Version.new(Fluent::VERSION) < Gem::Version.new('0.14.12')
|
27
|
-
require 'fluent/process'
|
28
|
-
include Fluent::DetachMultiProcessMixin
|
29
|
-
end
|
30
|
-
|
31
|
-
def self.included(klass)
|
32
|
-
klass.extend ClassMethods
|
33
|
-
end
|
34
|
-
include Initialize
|
35
|
-
end
|
36
|
-
end
|
@@ -1,123 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Amazon Software License (the "License").
|
5
|
-
# You may not use this file except in compliance with the License.
|
6
|
-
# A copy of the License is located at
|
7
|
-
#
|
8
|
-
# http://aws.amazon.com/asl/
|
9
|
-
#
|
10
|
-
# or in the "license" file accompanying this file. This file is distributed
|
11
|
-
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
-
# express or implied. See the License for the specific language governing
|
13
|
-
# permissions and limitations under the License.
|
14
|
-
|
15
|
-
module Fluent
|
16
|
-
module KinesisHelper
|
17
|
-
module ClassMethods
|
18
|
-
def config_param_for_streams
|
19
|
-
const_set(:RequestType, :streams)
|
20
|
-
const_set(:BatchRequestLimitCount, 500)
|
21
|
-
const_set(:BatchRequestLimitSize, 5 * 1024 * 1024)
|
22
|
-
config_param :stream_name, :string
|
23
|
-
config_param :region, :string, default: nil
|
24
|
-
config_param :partition_key, :string, default: nil
|
25
|
-
config_param_for_sdk
|
26
|
-
config_param_for_credentials
|
27
|
-
config_param_for_format
|
28
|
-
config_param_for_batch_request
|
29
|
-
config_param_for_debug
|
30
|
-
end
|
31
|
-
|
32
|
-
def config_param_for_firehose
|
33
|
-
const_set(:RequestType, :firehose)
|
34
|
-
const_set(:BatchRequestLimitCount, 500)
|
35
|
-
const_set(:BatchRequestLimitSize, 4 * 1024 * 1024)
|
36
|
-
config_param :delivery_stream_name, :string
|
37
|
-
config_param :region, :string, default: nil
|
38
|
-
config_param :append_new_line, :bool, default: true
|
39
|
-
config_param_for_sdk
|
40
|
-
config_param_for_credentials
|
41
|
-
config_param_for_format
|
42
|
-
config_param_for_batch_request
|
43
|
-
config_param_for_debug
|
44
|
-
end
|
45
|
-
|
46
|
-
def config_param_for_producer
|
47
|
-
const_set(:RequestType, :producer)
|
48
|
-
config_param :stream_name, :string, default: nil
|
49
|
-
config_param :stream_name_prefix, :string, default: nil
|
50
|
-
config_param :region, :string, default: nil
|
51
|
-
config_param :partition_key, :string, default: nil
|
52
|
-
config_param :enable_kpl_logging, :bool, default: false
|
53
|
-
config_param_for_credentials
|
54
|
-
config_param_for_format
|
55
|
-
config_param_for_debug
|
56
|
-
|
57
|
-
config_section :kinesis_producer, multi: false do
|
58
|
-
require 'kinesis_producer'
|
59
|
-
type_map = {
|
60
|
-
Protobuf::Field::BoolField => :bool,
|
61
|
-
Protobuf::Field::Uint64Field => :integer,
|
62
|
-
Protobuf::Field::StringField => :string,
|
63
|
-
}
|
64
|
-
KinesisProducer::ConfigurationFields.each do |field|
|
65
|
-
next if field.name == 'region'
|
66
|
-
type = type_map[field.type_class]
|
67
|
-
config_param field.name, type, default: field.default_value
|
68
|
-
end
|
69
|
-
config_param :credentials_refresh_delay, :integer, default: 5000
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def config_param_for_sdk
|
74
|
-
config_param :http_proxy, :string, default: nil, secret: true
|
75
|
-
config_param :endpoint, :string, default: nil
|
76
|
-
config_param :ssl_verify_peer, :bool, default: true
|
77
|
-
end
|
78
|
-
|
79
|
-
def config_param_for_credentials
|
80
|
-
config_param :aws_key_id, :string, default: nil, secret: true
|
81
|
-
config_param :aws_sec_key, :string, default: nil, secret: true
|
82
|
-
config_section :shared_credentials, multi: false do
|
83
|
-
config_param :profile_name, :string, default: nil
|
84
|
-
config_param :path, :string, default: nil
|
85
|
-
end
|
86
|
-
config_section :assume_role_credentials, multi: false do
|
87
|
-
config_param :role_arn, :string, secret: true
|
88
|
-
config_param :external_id, :string, default: nil, secret: true
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
def config_param_for_format
|
93
|
-
config_param :formatter, :string, default: 'json'
|
94
|
-
config_param :data_key, :string, default: nil
|
95
|
-
config_param :log_truncate_max_size, :integer, default: 0
|
96
|
-
config_param :reduce_max_size_error_message, :bool, default: false
|
97
|
-
end
|
98
|
-
|
99
|
-
def config_param_for_batch_request
|
100
|
-
config_param :retries_on_batch_request, :integer, default: 3
|
101
|
-
config_param :reset_backoff_if_success, :bool, default: true
|
102
|
-
config_param :batch_request_max_count, :integer, default: const_get(:BatchRequestLimitCount)
|
103
|
-
config_param :batch_request_max_size, :integer, default: const_get(:BatchRequestLimitSize)
|
104
|
-
end
|
105
|
-
|
106
|
-
def config_param_for_debug
|
107
|
-
config_param :debug, :bool, default: false
|
108
|
-
end
|
109
|
-
|
110
|
-
def request_type
|
111
|
-
const_get(:RequestType)
|
112
|
-
end
|
113
|
-
|
114
|
-
def api?
|
115
|
-
[:streams, :firehose].include?(request_type)
|
116
|
-
end
|
117
|
-
|
118
|
-
def kpl?
|
119
|
-
[:producer].include?(request_type)
|
120
|
-
end
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
@@ -1,51 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Amazon Software License (the "License").
|
5
|
-
# You may not use this file except in compliance with the License.
|
6
|
-
# A copy of the License is located at
|
7
|
-
#
|
8
|
-
# http://aws.amazon.com/asl/
|
9
|
-
#
|
10
|
-
# or in the "license" file accompanying this file. This file is distributed
|
11
|
-
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
-
# express or implied. See the License for the specific language governing
|
13
|
-
# permissions and limitations under the License.
|
14
|
-
|
15
|
-
module Fluent
|
16
|
-
module KinesisHelper
|
17
|
-
module Credentials
|
18
|
-
def credentials
|
19
|
-
@provider ||= case
|
20
|
-
when @assume_role_credentials
|
21
|
-
Aws::AssumeRoleCredentials.new(
|
22
|
-
client: Aws::STS::Client.new(region: @region),
|
23
|
-
role_arn: @assume_role_credentials.role_arn,
|
24
|
-
external_id: @assume_role_credentials.external_id,
|
25
|
-
role_session_name: 'aws-fluent-plugin-kinesis',
|
26
|
-
duration_seconds: 60 * 60,
|
27
|
-
)
|
28
|
-
when @shared_credentials
|
29
|
-
Aws::SharedCredentials.new(
|
30
|
-
profile_name: @shared_credentials.profile_name,
|
31
|
-
path: @shared_credentials.path,
|
32
|
-
)
|
33
|
-
else
|
34
|
-
default_credentials_provider
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
private
|
39
|
-
|
40
|
-
def default_credentials_provider
|
41
|
-
config_class = Struct.new(:access_key_id, :secret_access_key, :region, :session_token, :profile, :instance_profile_credentials_retries, :instance_profile_credentials_timeout)
|
42
|
-
config = config_class.new(@aws_key_id, @aws_sec_key, @region)
|
43
|
-
provider = Aws::CredentialProviderChain.new(config).resolve
|
44
|
-
if provider.nil?
|
45
|
-
raise Fluent::ConfigError, "You must specify credentials on ~/.aws/credentials, environment variables or instance profile for default credentials"
|
46
|
-
end
|
47
|
-
provider
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
@@ -1,43 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Amazon Software License (the "License").
|
5
|
-
# You may not use this file except in compliance with the License.
|
6
|
-
# A copy of the License is located at
|
7
|
-
#
|
8
|
-
# http://aws.amazon.com/asl/
|
9
|
-
#
|
10
|
-
# or in the "license" file accompanying this file. This file is distributed
|
11
|
-
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
-
# express or implied. See the License for the specific language governing
|
13
|
-
# permissions and limitations under the License.
|
14
|
-
|
15
|
-
module Fluent
|
16
|
-
module KinesisHelper
|
17
|
-
class BaseError < ::StandardError; end
|
18
|
-
class SkipRecordError < BaseError; end
|
19
|
-
|
20
|
-
class KeyNotFoundError < SkipRecordError
|
21
|
-
def initialize(key, record)
|
22
|
-
super "Key '#{key}' doesn't exist on #{record}"
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
class ExceedMaxRecordSizeError < SkipRecordError
|
27
|
-
def initialize(record, reduce_message)
|
28
|
-
if reduce_message == true
|
29
|
-
sampled_record = "#{record.slice(0,1024)}...#{record.slice(-1024,1024)}"
|
30
|
-
super "Record size limit exceeded for #{record.length}-bytes record: #{sampled_record}"
|
31
|
-
else
|
32
|
-
super "Record size limit exceeded for #{record}"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
class InvalidRecordError < SkipRecordError
|
38
|
-
def initialize(record)
|
39
|
-
super "Invalid type of record: #{record}"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|
@@ -1,85 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Amazon Software License (the "License").
|
5
|
-
# You may not use this file except in compliance with the License.
|
6
|
-
# A copy of the License is located at
|
7
|
-
#
|
8
|
-
# http://aws.amazon.com/asl/
|
9
|
-
#
|
10
|
-
# or in the "license" file accompanying this file. This file is distributed
|
11
|
-
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
-
# express or implied. See the License for the specific language governing
|
13
|
-
# permissions and limitations under the License.
|
14
|
-
|
15
|
-
require 'fluent/plugin/kinesis_helper/error'
|
16
|
-
|
17
|
-
module Fluent
|
18
|
-
module KinesisHelper
|
19
|
-
module Format
|
20
|
-
MaxRecordSize = 1024 * 1024 # 1 MB
|
21
|
-
|
22
|
-
def configure(conf)
|
23
|
-
super
|
24
|
-
@formatter = Fluent::Plugin.new_formatter(@formatter)
|
25
|
-
@formatter.configure(conf)
|
26
|
-
end
|
27
|
-
|
28
|
-
def format(tag, time, record)
|
29
|
-
[tag, time, record].to_msgpack
|
30
|
-
end
|
31
|
-
|
32
|
-
private
|
33
|
-
|
34
|
-
def data_format(tag, time, record)
|
35
|
-
if @data_key and record[@data_key].nil?
|
36
|
-
raise KeyNotFoundError.new(@data_key, record)
|
37
|
-
elsif @data_key
|
38
|
-
record[@data_key].to_s
|
39
|
-
else
|
40
|
-
@formatter.format(tag, time, record).chomp
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def key(record)
|
45
|
-
if @partition_key.nil?
|
46
|
-
SecureRandom.hex(16)
|
47
|
-
elsif !record.key?(@partition_key)
|
48
|
-
raise KeyNotFoundError.new(@partition_key, record)
|
49
|
-
else
|
50
|
-
record[@partition_key]
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def convert_to_records(chunk)
|
55
|
-
chunk.to_enum(:msgpack_each).map{|tag, time, record|
|
56
|
-
convert_record(tag, time, record)
|
57
|
-
}.compact
|
58
|
-
end
|
59
|
-
|
60
|
-
def convert_record(tag, time, record)
|
61
|
-
unless record.is_a? Hash
|
62
|
-
raise InvalidRecordError, record
|
63
|
-
end
|
64
|
-
converted = convert_format(tag, time, record)
|
65
|
-
converted[:data] += "\n" if @append_new_line
|
66
|
-
if converted[:data].size > MaxRecordSize
|
67
|
-
raise ExceedMaxRecordSizeError.new(converted[:data], @reduce_max_size_error_message)
|
68
|
-
else
|
69
|
-
converted
|
70
|
-
end
|
71
|
-
rescue SkipRecordError => e
|
72
|
-
log.error(truncate e)
|
73
|
-
nil
|
74
|
-
end
|
75
|
-
|
76
|
-
def truncate(msg)
|
77
|
-
if @log_truncate_max_size == 0 or (msg.to_s.size <= @log_truncate_max_size)
|
78
|
-
msg.to_s
|
79
|
-
else
|
80
|
-
msg.to_s[0...@log_truncate_max_size]
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
@@ -1,59 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Amazon Software License (the "License").
|
5
|
-
# You may not use this file except in compliance with the License.
|
6
|
-
# A copy of the License is located at
|
7
|
-
#
|
8
|
-
# http://aws.amazon.com/asl/
|
9
|
-
#
|
10
|
-
# or in the "license" file accompanying this file. This file is distributed
|
11
|
-
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
-
# express or implied. See the License for the specific language governing
|
13
|
-
# permissions and limitations under the License.
|
14
|
-
|
15
|
-
module Fluent
|
16
|
-
module KinesisHelper
|
17
|
-
module Initialize
|
18
|
-
def initialize
|
19
|
-
super
|
20
|
-
class << self
|
21
|
-
define_method('log') { $log } unless method_defined?(:log)
|
22
|
-
|
23
|
-
require 'aws-sdk'
|
24
|
-
require 'fluent/plugin/kinesis_helper/format'
|
25
|
-
require 'fluent/plugin/kinesis_helper/client'
|
26
|
-
require 'fluent/plugin/kinesis_helper/credentials'
|
27
|
-
include Format, Client, Credentials
|
28
|
-
|
29
|
-
case
|
30
|
-
when api?
|
31
|
-
require 'fluent/plugin/kinesis_helper/api'
|
32
|
-
include API
|
33
|
-
when kpl?
|
34
|
-
require 'fluent/plugin/kinesis_helper/kpl'
|
35
|
-
require 'fluent/version'
|
36
|
-
if Gem::Version.new(Fluent::VERSION) < Gem::Version.new('0.12.20')
|
37
|
-
# Backport from https://github.com/fluent/fluentd/pull/757
|
38
|
-
require 'fluent/plugin/patched_detach_process_impl'
|
39
|
-
include PatchedDetachProcessImpl
|
40
|
-
end
|
41
|
-
include KPL
|
42
|
-
end
|
43
|
-
|
44
|
-
def request_type
|
45
|
-
self.class.request_type
|
46
|
-
end
|
47
|
-
|
48
|
-
def api?
|
49
|
-
self.class.api?
|
50
|
-
end
|
51
|
-
|
52
|
-
def kpl?
|
53
|
-
self.class.kpl?
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
@@ -1,82 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Copyright 2014-2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
3
|
-
#
|
4
|
-
# Licensed under the Amazon Software License (the "License").
|
5
|
-
# You may not use this file except in compliance with the License.
|
6
|
-
# A copy of the License is located at
|
7
|
-
#
|
8
|
-
# http://aws.amazon.com/asl/
|
9
|
-
#
|
10
|
-
# or in the "license" file accompanying this file. This file is distributed
|
11
|
-
# on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
|
12
|
-
# express or implied. See the License for the specific language governing
|
13
|
-
# permissions and limitations under the License.
|
14
|
-
|
15
|
-
module Fluent
|
16
|
-
module KinesisHelper
|
17
|
-
module KPL
|
18
|
-
def configure(conf)
|
19
|
-
# To workaround when the kinesis_producer section is not specified
|
20
|
-
if conf.elements.none?{|e|e.name == "kinesis_producer"}
|
21
|
-
conf.add_element("kinesis_producer")
|
22
|
-
end
|
23
|
-
super(conf)
|
24
|
-
if @region.nil?
|
25
|
-
keys = %w(AWS_REGION AMAZON_REGION AWS_DEFAULT_REGION)
|
26
|
-
@region = ENV.values_at(*keys).compact.first
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
def start
|
31
|
-
detach_multi_process do
|
32
|
-
super
|
33
|
-
client
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def shutdown
|
38
|
-
super
|
39
|
-
client.destroy
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def client_options
|
45
|
-
{
|
46
|
-
credentials: credentials,
|
47
|
-
configuration: build_kpl_configuration,
|
48
|
-
credentials_refresh_delay: @kinesis_producer.credentials_refresh_delay,
|
49
|
-
debug: @debug,
|
50
|
-
logger: log,
|
51
|
-
enable_kpl_logging: @enable_kpl_logging,
|
52
|
-
}
|
53
|
-
end
|
54
|
-
|
55
|
-
def build_kpl_configuration
|
56
|
-
configuration = @kinesis_producer.to_h
|
57
|
-
configuration.update(region: @region) unless @region.nil?
|
58
|
-
end
|
59
|
-
|
60
|
-
def write_chunk_to_kpl(records)
|
61
|
-
records.map do |record|
|
62
|
-
client.put_record(record)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def wait_futures(futures)
|
67
|
-
futures.each do |f|
|
68
|
-
f.wait
|
69
|
-
result = f.value!
|
70
|
-
end
|
71
|
-
end
|
72
|
-
|
73
|
-
def on_detach_process(i)
|
74
|
-
Process.setsid
|
75
|
-
end
|
76
|
-
|
77
|
-
def on_exit_process(i)
|
78
|
-
shutdown
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|