redstorm 0.6.6 → 0.7.0.beta1
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 +7 -0
- data/CHANGELOG.md +6 -1
- data/README.md +8 -7
- data/examples/dsl/exclamation_topology.rb +2 -4
- data/examples/dsl/exclamation_topology2.rb +4 -5
- data/examples/dsl/hello_world_topology.rb +7 -0
- data/examples/dsl/kafka_topology.rb +5 -1
- data/examples/dsl/redis_word_count_topology.rb +5 -9
- data/examples/dsl/ruby_version_topology.rb +2 -0
- data/examples/dsl/word_count_topology.rb +4 -5
- data/examples/trident/word_count_query.rb +33 -0
- data/examples/trident/word_count_topology.rb +153 -0
- data/ivy/storm_dependencies.xml +1 -1
- data/ivy/topology_dependencies.xml +3 -2
- data/lib/red_storm.rb +5 -2
- data/lib/red_storm/configurator.rb +12 -0
- data/lib/red_storm/dsl/batch_bolt.rb +34 -0
- data/lib/red_storm/dsl/batch_committer_bolt.rb +9 -0
- data/lib/red_storm/dsl/batch_spout.rb +53 -0
- data/lib/red_storm/dsl/bolt.rb +7 -2
- data/lib/red_storm/dsl/output_collector.rb +8 -0
- data/lib/red_storm/dsl/spout.rb +3 -1
- data/lib/red_storm/dsl/topology.rb +2 -2
- data/lib/red_storm/dsl/tuple.rb +2 -0
- data/lib/red_storm/topology_launcher.rb +14 -10
- data/lib/red_storm/version.rb +1 -1
- data/redstorm.gemspec +1 -0
- data/src/main/redstorm/storm/jruby/JRubyBatchBolt.java +53 -35
- data/src/main/redstorm/storm/jruby/JRubyBatchSpout.java +77 -42
- data/src/main/redstorm/storm/jruby/JRubyBolt.java +54 -34
- data/src/main/redstorm/storm/jruby/JRubySpout.java +62 -40
- data/src/main/redstorm/storm/jruby/JRubyTransactionalBolt.java +57 -35
- data/src/main/redstorm/storm/jruby/JRubyTransactionalCommitterBolt.java +6 -17
- data/src/main/redstorm/storm/jruby/JRubyTransactionalCommitterSpout.java +14 -26
- data/src/main/redstorm/storm/jruby/JRubyTransactionalSpout.java +60 -37
- data/src/main/redstorm/storm/jruby/JRubyTridentFunction.java +66 -0
- metadata +16 -23
- data/lib/red_storm/proxy/batch_bolt.rb +0 -63
- data/lib/red_storm/proxy/batch_committer_bolt.rb +0 -52
- data/lib/red_storm/proxy/batch_spout.rb +0 -59
- data/lib/red_storm/proxy/bolt.rb +0 -63
- data/lib/red_storm/proxy/proxy_function.rb +0 -40
- data/lib/red_storm/proxy/spout.rb +0 -87
- data/lib/red_storm/proxy/transactional_committer_spout.rb +0 -47
- data/lib/red_storm/proxy/transactional_spout.rb +0 -46
- data/src/main/redstorm/storm/jruby/JRubyProxyFunction.java +0 -51
@@ -0,0 +1,53 @@
|
|
1
|
+
module RedStorm
|
2
|
+
module DSL
|
3
|
+
|
4
|
+
class BatchSpout < Spout
|
5
|
+
|
6
|
+
def self.java_proxy; "Java::RedstormStormJruby::JRubyBatchSpout"; end
|
7
|
+
|
8
|
+
def get_output_fields
|
9
|
+
Fields.new(self.class.fields)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.on_emit_batch(*args, &on_emit_batch_block)
|
13
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
14
|
+
method_name = args.first
|
15
|
+
|
16
|
+
self.on_emit_batch_options.merge!(options)
|
17
|
+
|
18
|
+
# indirecting through a lambda defers the method lookup at invocation time
|
19
|
+
# and the performance penalty is negligible
|
20
|
+
body = block_given? ? on_emit_batch_block : lambda{|batch_id, collector| self.send((method_name || :on_emit_batch).to_sym)}
|
21
|
+
define_method(:on_emit_batch, body)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Spout proxy interface
|
25
|
+
|
26
|
+
#
|
27
|
+
# note that in batch spout, ack is for the batch id and not the message id as in the base spout.
|
28
|
+
# TODO maybe rename msg_id to just id in the base spout
|
29
|
+
#
|
30
|
+
|
31
|
+
def emit_batch(batch_id, collector)
|
32
|
+
# TODO this is a TridentCollector, emit should just work by setting @collector
|
33
|
+
# report_error need to be hooked?
|
34
|
+
@collector = collector
|
35
|
+
on_emit_batch(batch_id, collector)
|
36
|
+
end
|
37
|
+
|
38
|
+
def open(config, context)
|
39
|
+
@context = context
|
40
|
+
@config = config
|
41
|
+
|
42
|
+
on_init
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def self.on_emit_batch_options
|
48
|
+
@on_emit_batch_options ||= {}
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/red_storm/dsl/bolt.rb
CHANGED
@@ -3,6 +3,9 @@ require 'red_storm/configurator'
|
|
3
3
|
require 'red_storm/environment'
|
4
4
|
require 'pathname'
|
5
5
|
|
6
|
+
java_import 'backtype.storm.tuple.Fields'
|
7
|
+
java_import 'backtype.storm.tuple.Values'
|
8
|
+
|
6
9
|
module RedStorm
|
7
10
|
module DSL
|
8
11
|
|
@@ -11,6 +14,8 @@ module RedStorm
|
|
11
14
|
class Bolt
|
12
15
|
attr_reader :collector, :context, :config
|
13
16
|
|
17
|
+
def self.java_proxy; "Java::RedstormStormJruby::JRubyBolt"; end
|
18
|
+
|
14
19
|
# DSL class methods
|
15
20
|
|
16
21
|
def self.log
|
@@ -54,11 +59,11 @@ module RedStorm
|
|
54
59
|
end
|
55
60
|
|
56
61
|
def unanchored_emit(*values)
|
57
|
-
@collector.
|
62
|
+
@collector.emit_tuple(Values.new(*values))
|
58
63
|
end
|
59
64
|
|
60
65
|
def anchored_emit(tuple, *values)
|
61
|
-
@collector.
|
66
|
+
@collector.emit_anchor_tuple(tuple, Values.new(*values))
|
62
67
|
end
|
63
68
|
|
64
69
|
def ack(tuple)
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'java'
|
2
|
+
java_import 'backtype.storm.task.OutputCollector'
|
3
|
+
|
4
|
+
# make alias methods to specific signatures to avoid selection overhead for heavily overloaded method
|
5
|
+
class OutputCollector
|
6
|
+
java_alias :emit_tuple, :emit, [java.lang.Class.for_name("java.util.List")]
|
7
|
+
java_alias :emit_anchor_tuple, :emit, [java.lang.Class.for_name("backtype.storm.tuple.Tuple"), java.lang.Class.for_name("java.util.List")]
|
8
|
+
end
|
data/lib/red_storm/dsl/spout.rb
CHANGED
@@ -11,6 +11,8 @@ module RedStorm
|
|
11
11
|
class Spout
|
12
12
|
attr_reader :config, :context, :collector
|
13
13
|
|
14
|
+
def self.java_proxy; "Java::RedstormStormJruby::JRubySpout"; end
|
15
|
+
|
14
16
|
# DSL class methods
|
15
17
|
|
16
18
|
def self.configure(&configure_block)
|
@@ -99,7 +101,7 @@ module RedStorm
|
|
99
101
|
unreliable_emit(*values)
|
100
102
|
end
|
101
103
|
else
|
102
|
-
sleep(0.1)
|
104
|
+
sleep(0.1) # see https://twitter.com/colinsurprenant/status/406445541904494592
|
103
105
|
end
|
104
106
|
end
|
105
107
|
end
|
@@ -46,7 +46,7 @@ module RedStorm
|
|
46
46
|
elsif is_java?
|
47
47
|
@clazz.new(*constructor_args)
|
48
48
|
else
|
49
|
-
|
49
|
+
Object.module_eval(@clazz.java_proxy).new(@clazz.base_class_path, @clazz.name, @output_fields)
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -95,7 +95,7 @@ module RedStorm
|
|
95
95
|
elsif is_java?
|
96
96
|
@clazz.new(*constructor_args)
|
97
97
|
else
|
98
|
-
|
98
|
+
Object.module_eval(@clazz.java_proxy).new(@clazz.base_class_path, @clazz.name, @output_fields)
|
99
99
|
end
|
100
100
|
end
|
101
101
|
end
|
data/lib/red_storm/dsl/tuple.rb
CHANGED
@@ -2,8 +2,11 @@ require 'java'
|
|
2
2
|
|
3
3
|
# This hack get rif of the "Use RbConfig instead of obsolete and deprecated Config"
|
4
4
|
# deprecation warning that is triggered by "java_import 'backtype.storm.Config'".
|
5
|
-
|
6
|
-
|
5
|
+
begin
|
6
|
+
Object.send :remove_const, :Config
|
7
|
+
Config = RbConfig
|
8
|
+
rescue NameError
|
9
|
+
end
|
7
10
|
|
8
11
|
# see https://github.com/colinsurprenant/redstorm/issues/7
|
9
12
|
module Backtype
|
@@ -20,14 +23,15 @@ java_import 'backtype.storm.tuple.Fields'
|
|
20
23
|
java_import 'backtype.storm.tuple.Tuple'
|
21
24
|
java_import 'backtype.storm.tuple.Values'
|
22
25
|
|
23
|
-
java_import 'redstorm.storm.jruby.JRubyBolt'
|
24
|
-
java_import 'redstorm.storm.jruby.JRubySpout'
|
25
|
-
java_import 'redstorm.storm.jruby.JRubyBatchBolt'
|
26
|
-
java_import 'redstorm.storm.jruby.JRubyBatchCommitterBolt'
|
27
|
-
java_import 'redstorm.storm.jruby.JRubyBatchSpout'
|
28
|
-
java_import 'redstorm.storm.jruby.JRubyTransactionalSpout'
|
29
|
-
java_import 'redstorm.storm.jruby.JRubyTransactionalBolt'
|
30
|
-
java_import 'redstorm.storm.jruby.JRubyTransactionalCommitterBolt'
|
26
|
+
# java_import 'redstorm.storm.jruby.JRubyBolt'
|
27
|
+
# java_import 'redstorm.storm.jruby.JRubySpout'
|
28
|
+
# java_import 'redstorm.storm.jruby.JRubyBatchBolt'
|
29
|
+
# java_import 'redstorm.storm.jruby.JRubyBatchCommitterBolt'
|
30
|
+
# java_import 'redstorm.storm.jruby.JRubyBatchSpout'
|
31
|
+
# java_import 'redstorm.storm.jruby.JRubyTransactionalSpout'
|
32
|
+
# java_import 'redstorm.storm.jruby.JRubyTransactionalBolt'
|
33
|
+
# java_import 'redstorm.storm.jruby.JRubyTransactionalCommitterBolt'
|
34
|
+
# java_import 'redstorm.storm.jruby.JRubyProxyFunction'
|
31
35
|
|
32
36
|
java_package 'redstorm'
|
33
37
|
|
data/lib/red_storm/version.rb
CHANGED
data/redstorm.gemspec
CHANGED
@@ -11,6 +11,7 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = 'https://github.com/colinsurprenant/redstorm'
|
12
12
|
s.summary = 'JRuby on Storm'
|
13
13
|
s.description = 'JRuby integration & DSL for the Storm distributed realtime computation system'
|
14
|
+
s.license = "Apache 2.0"
|
14
15
|
|
15
16
|
s.rubyforge_project = 'redstorm'
|
16
17
|
|
@@ -10,81 +10,99 @@ import backtype.storm.tuple.Tuple;
|
|
10
10
|
import backtype.storm.tuple.Fields;
|
11
11
|
import java.util.Map;
|
12
12
|
|
13
|
+
import org.jruby.Ruby;
|
14
|
+
import org.jruby.RubyObject;
|
15
|
+
import org.jruby.runtime.Helpers;
|
16
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
17
|
+
import org.jruby.javasupport.JavaUtil;
|
18
|
+
import org.jruby.RubyModule;
|
19
|
+
import org.jruby.exceptions.RaiseException;
|
20
|
+
|
13
21
|
/**
|
14
|
-
* the JRubyBolt class is a
|
15
|
-
* this proxy is required to bypass the serialization/deserialization
|
16
|
-
*
|
17
|
-
* (Java serialization call on a JRuby class).
|
22
|
+
* the JRubyBolt class is a proxy class to the actual bolt implementation in JRuby.
|
23
|
+
* this proxy is required to bypass the serialization/deserialization issues of JRuby objects.
|
24
|
+
* JRuby classes do not support Java serialization.
|
18
25
|
*
|
19
|
-
* Note that the JRuby bolt
|
20
|
-
* deserialization at the worker and in the declareOutputFields
|
21
|
-
* serialization at topology creation.
|
26
|
+
* Note that the JRuby bolt class is instanciated in the prepare method which is called after
|
27
|
+
* deserialization at the worker and in the declareOutputFields & getComponentConfiguration
|
28
|
+
* methods which are called once before serialization at topology creation.
|
22
29
|
*/
|
23
30
|
public class JRubyBatchBolt extends BaseBatchBolt {
|
24
|
-
|
25
|
-
String
|
26
|
-
String
|
27
|
-
|
31
|
+
private final String _realBoltClassName;
|
32
|
+
private final String[] _fields;
|
33
|
+
private final String _bootstrap;
|
34
|
+
|
35
|
+
// transient to avoid serialization
|
36
|
+
private transient IRubyObject _ruby_bolt;
|
37
|
+
private transient Ruby __ruby__;
|
28
38
|
|
29
39
|
/**
|
30
40
|
* create a new JRubyBolt
|
31
|
-
*
|
32
|
-
* @param baseClassPath the topology/project base JRuby class file path
|
41
|
+
*
|
42
|
+
* @param baseClassPath the topology/project base JRuby class file path
|
33
43
|
* @param realBoltClassName the fully qualified JRuby bolt implementation class name
|
44
|
+
* @param fields the output fields names
|
34
45
|
*/
|
35
46
|
public JRubyBatchBolt(String baseClassPath, String realBoltClassName, String[] fields) {
|
36
|
-
_baseClassPath = baseClassPath;
|
37
47
|
_realBoltClassName = realBoltClassName;
|
38
48
|
_fields = fields;
|
49
|
+
_bootstrap = "require '" + baseClassPath + "'";
|
39
50
|
}
|
40
51
|
|
41
52
|
@Override
|
42
|
-
public void prepare(final Map
|
43
|
-
|
44
|
-
|
45
|
-
|
53
|
+
public void prepare(final Map conf, final TopologyContext context, final BatchOutputCollector collector, final Object id) {
|
54
|
+
_ruby_bolt = initialize_ruby_bolt();
|
55
|
+
IRubyObject ruby_conf = JavaUtil.convertJavaToRuby(__ruby__, conf);
|
56
|
+
IRubyObject ruby_context = JavaUtil.convertJavaToRuby(__ruby__, context);
|
57
|
+
IRubyObject ruby_collector = JavaUtil.convertJavaToRuby(__ruby__, collector);
|
58
|
+
IRubyObject ruby_id = JavaUtil.convertJavaToRuby(__ruby__, id);
|
59
|
+
Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "prepare", ruby_conf, ruby_context, ruby_collector, ruby_id);
|
46
60
|
}
|
47
61
|
|
48
62
|
@Override
|
49
63
|
public void execute(Tuple input) {
|
50
|
-
|
64
|
+
IRubyObject ruby_input = JavaUtil.convertJavaToRuby(__ruby__, input);
|
65
|
+
Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "execute", ruby_input);
|
51
66
|
}
|
52
67
|
|
53
68
|
@Override
|
54
69
|
public void finishBatch() {
|
55
|
-
|
70
|
+
Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "finish_batch");
|
56
71
|
}
|
57
72
|
|
58
73
|
@Override
|
59
74
|
public void declareOutputFields(OutputFieldsDeclarer declarer) {
|
60
|
-
// declareOutputFields is executed in the topology creation time, before serialisation.
|
61
|
-
// do not set the _proxyBolt instance variable here to avoid JRuby serialization
|
62
|
-
// issues. Just create tmp bolt instance to call declareOutputFields.
|
63
75
|
if (_fields.length > 0) {
|
64
76
|
declarer.declare(new Fields(_fields));
|
65
77
|
} else {
|
66
|
-
|
67
|
-
|
78
|
+
IRubyObject ruby_bolt = initialize_ruby_bolt();
|
79
|
+
IRubyObject ruby_declarer = JavaUtil.convertJavaToRuby(__ruby__, declarer);
|
80
|
+
Helpers.invoke(__ruby__.getCurrentContext(), ruby_bolt, "declare_output_fields", ruby_declarer);
|
68
81
|
}
|
69
82
|
}
|
70
83
|
|
71
84
|
@Override
|
72
85
|
public Map<String, Object> getComponentConfiguration() {
|
73
86
|
// getComponentConfiguration is executed in the topology creation time, before serialisation.
|
74
|
-
//
|
75
|
-
|
76
|
-
|
77
|
-
|
87
|
+
// just create tmp bolt instance to call getComponentConfiguration.
|
88
|
+
|
89
|
+
IRubyObject ruby_bolt = initialize_ruby_bolt();
|
90
|
+
IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), ruby_bolt, "get_component_configuration");
|
91
|
+
return (Map)ruby_result.toJava(Map.class);
|
78
92
|
}
|
79
|
-
|
80
93
|
|
81
|
-
private
|
94
|
+
private IRubyObject initialize_ruby_bolt() {
|
95
|
+
__ruby__ = Ruby.getGlobalRuntime();
|
96
|
+
|
97
|
+
RubyModule ruby_class;
|
82
98
|
try {
|
83
|
-
|
84
|
-
return proxy;
|
99
|
+
ruby_class = __ruby__.getClassFromPath(_realBoltClassName);
|
85
100
|
}
|
86
|
-
catch (
|
87
|
-
|
101
|
+
catch (RaiseException e) {
|
102
|
+
// after deserialization we need to recreate ruby environment
|
103
|
+
__ruby__.evalScriptlet(_bootstrap);
|
104
|
+
ruby_class = __ruby__.getClassFromPath(_realBoltClassName);
|
88
105
|
}
|
106
|
+
return Helpers.invoke(__ruby__.getCurrentContext(), ruby_class, "new");
|
89
107
|
}
|
90
108
|
}
|
@@ -6,83 +6,118 @@ import storm.trident.operation.TridentCollector;
|
|
6
6
|
import storm.trident.spout.IBatchSpout;
|
7
7
|
import java.util.Map;
|
8
8
|
|
9
|
+
import org.jruby.Ruby;
|
10
|
+
import org.jruby.RubyObject;
|
11
|
+
import org.jruby.runtime.Helpers;
|
12
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
13
|
+
import org.jruby.javasupport.JavaUtil;
|
14
|
+
import org.jruby.RubyModule;
|
15
|
+
import org.jruby.exceptions.RaiseException;
|
16
|
+
|
9
17
|
/**
|
10
|
-
* the JRubySpout class is a
|
11
|
-
* this proxy is required to bypass the serialization/deserialization
|
12
|
-
*
|
13
|
-
* (Java serialization call on a JRuby class).
|
18
|
+
* the JRubySpout class is a proxy class to the actual spout implementation in JRuby.
|
19
|
+
* this proxy is required to bypass the serialization/deserialization issues of JRuby objects.
|
20
|
+
* JRuby classes do not support Java serialization.
|
14
21
|
*
|
15
|
-
* Note that the JRuby spout
|
16
|
-
* deserialization at the worker and in
|
17
|
-
* are called once before serialization at topology creation.
|
22
|
+
* Note that the JRuby spout class is instanciated in the open method which is called after
|
23
|
+
* deserialization at the worker and in the declareOutputFields & getComponentConfiguration
|
24
|
+
* methods which are called once before serialization at topology creation.
|
18
25
|
*/
|
19
26
|
public class JRubyBatchSpout implements IBatchSpout {
|
20
|
-
|
21
|
-
String
|
22
|
-
String
|
23
|
-
|
27
|
+
private final String _realSpoutClassName;
|
28
|
+
private final String[] _fields;
|
29
|
+
private final String _bootstrap;
|
30
|
+
|
31
|
+
// transient to avoid serialization
|
32
|
+
private transient IRubyObject _ruby_spout;
|
33
|
+
private transient Ruby __ruby__;
|
34
|
+
|
24
35
|
/**
|
25
|
-
* create a new
|
26
|
-
*
|
27
|
-
* @param baseClassPath the topology/project base JRuby class file path
|
36
|
+
* create a new JRubyBatchSpout
|
37
|
+
*
|
38
|
+
* @param baseClassPath the topology/project base JRuby class file path
|
28
39
|
* @param realSpoutClassName the fully qualified JRuby spout implementation class name
|
40
|
+
* @param fields the output fields names
|
29
41
|
*/
|
30
42
|
public JRubyBatchSpout(String baseClassPath, String realSpoutClassName) {
|
31
|
-
_baseClassPath = baseClassPath;
|
32
43
|
_realSpoutClassName = realSpoutClassName;
|
44
|
+
_fields = null;
|
45
|
+
_bootstrap = "require '" + baseClassPath + "'";
|
46
|
+
}
|
47
|
+
|
48
|
+
/* constructor for compatibility with JRubySpout signature */
|
49
|
+
public JRubyBatchSpout(String baseClassPath, String realSpoutClassName, String[] fields) {
|
50
|
+
_realSpoutClassName = realSpoutClassName;
|
51
|
+
_fields = fields;
|
52
|
+
_bootstrap = "require '" + baseClassPath + "'";
|
33
53
|
}
|
34
54
|
|
35
55
|
@Override
|
36
56
|
public void open(final Map conf, final TopologyContext context) {
|
37
|
-
// create instance of the jruby proxy class here, after deserialization in the workers.
|
38
|
-
_proxySpout = newProxySpout(_baseClassPath, _realSpoutClassName);
|
39
|
-
_proxySpout.open(conf, context);
|
57
|
+
// // create instance of the jruby proxy class here, after deserialization in the workers.
|
58
|
+
// _proxySpout = newProxySpout(_baseClassPath, _realSpoutClassName);
|
59
|
+
// _proxySpout.open(conf, context);
|
60
|
+
|
61
|
+
|
62
|
+
_ruby_spout = initialize_ruby_spout();
|
63
|
+
IRubyObject ruby_conf = JavaUtil.convertJavaToRuby(__ruby__, conf);
|
64
|
+
IRubyObject ruby_context = JavaUtil.convertJavaToRuby(__ruby__, context);
|
65
|
+
Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "open", ruby_conf, ruby_context);
|
40
66
|
}
|
41
67
|
|
42
68
|
@Override
|
43
69
|
public void emitBatch(long batchId, TridentCollector collector) {
|
44
|
-
_proxySpout.emitBatch(batchId, collector);
|
45
|
-
|
70
|
+
// _proxySpout.emitBatch(batchId, collector);
|
71
|
+
|
72
|
+
IRubyObject ruby_batch_id = JavaUtil.convertJavaToRuby(__ruby__, batchId);
|
73
|
+
IRubyObject ruby_collector = JavaUtil.convertJavaToRuby(__ruby__, collector);
|
74
|
+
Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "emit_batch", ruby_batch_id, ruby_collector);
|
75
|
+
}
|
46
76
|
|
47
77
|
@Override
|
48
78
|
public void close() {
|
49
|
-
_proxySpout.close();
|
79
|
+
// _proxySpout.close();
|
80
|
+
|
81
|
+
Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "close");
|
50
82
|
}
|
51
83
|
|
52
84
|
@Override
|
53
85
|
public void ack(long batchId) {
|
54
|
-
_proxySpout.ack(batchId);
|
86
|
+
// _proxySpout.ack(batchId);
|
87
|
+
|
88
|
+
IRubyObject ruby_batch_id = JavaUtil.convertJavaToRuby(__ruby__, batchId);
|
89
|
+
Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "ack", ruby_batch_id);
|
55
90
|
}
|
56
91
|
|
57
92
|
@Override
|
58
93
|
public Fields getOutputFields() {
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
// issues. Just create tmp spout instance to call getOutputFields.
|
63
|
-
IBatchSpout spout = newProxySpout(_baseClassPath, _realSpoutClassName);
|
64
|
-
return spout.getOutputFields();
|
65
|
-
} else {
|
66
|
-
return _proxySpout.getOutputFields();
|
67
|
-
}
|
94
|
+
IRubyObject ruby_spout = initialize_ruby_spout();
|
95
|
+
IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), ruby_spout, "get_output_fields");
|
96
|
+
return (Fields)ruby_result.toJava(Fields.class);
|
68
97
|
}
|
69
98
|
|
70
99
|
@Override
|
71
100
|
public Map<String, Object> getComponentConfiguration() {
|
72
|
-
// getComponentConfiguration is executed in the topology creation time before serialisation.
|
73
|
-
//
|
74
|
-
|
75
|
-
|
76
|
-
|
101
|
+
// getComponentConfiguration is executed in the topology creation time, before serialisation.
|
102
|
+
// just create tmp spout instance to call getComponentConfiguration.
|
103
|
+
|
104
|
+
IRubyObject ruby_spout = initialize_ruby_spout();
|
105
|
+
IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), ruby_spout, "get_component_configuration");
|
106
|
+
return (Map)ruby_result.toJava(Map.class);
|
77
107
|
}
|
78
|
-
|
79
|
-
private
|
108
|
+
|
109
|
+
private IRubyObject initialize_ruby_spout() {
|
110
|
+
__ruby__ = Ruby.getGlobalRuntime();
|
111
|
+
|
112
|
+
RubyModule ruby_class;
|
80
113
|
try {
|
81
|
-
|
82
|
-
return proxy;
|
114
|
+
ruby_class = __ruby__.getClassFromPath(_realSpoutClassName);
|
83
115
|
}
|
84
|
-
catch (
|
85
|
-
|
116
|
+
catch (RaiseException e) {
|
117
|
+
// after deserialization we need to recreate ruby environment
|
118
|
+
__ruby__.evalScriptlet(_bootstrap);
|
119
|
+
ruby_class = __ruby__.getClassFromPath(_realSpoutClassName);
|
86
120
|
}
|
121
|
+
return Helpers.invoke(__ruby__.getCurrentContext(), ruby_class, "new");
|
87
122
|
}
|
88
123
|
}
|