redstorm 0.6.6 → 0.7.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
}
|