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.
Files changed (46) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +6 -1
  3. data/README.md +8 -7
  4. data/examples/dsl/exclamation_topology.rb +2 -4
  5. data/examples/dsl/exclamation_topology2.rb +4 -5
  6. data/examples/dsl/hello_world_topology.rb +7 -0
  7. data/examples/dsl/kafka_topology.rb +5 -1
  8. data/examples/dsl/redis_word_count_topology.rb +5 -9
  9. data/examples/dsl/ruby_version_topology.rb +2 -0
  10. data/examples/dsl/word_count_topology.rb +4 -5
  11. data/examples/trident/word_count_query.rb +33 -0
  12. data/examples/trident/word_count_topology.rb +153 -0
  13. data/ivy/storm_dependencies.xml +1 -1
  14. data/ivy/topology_dependencies.xml +3 -2
  15. data/lib/red_storm.rb +5 -2
  16. data/lib/red_storm/configurator.rb +12 -0
  17. data/lib/red_storm/dsl/batch_bolt.rb +34 -0
  18. data/lib/red_storm/dsl/batch_committer_bolt.rb +9 -0
  19. data/lib/red_storm/dsl/batch_spout.rb +53 -0
  20. data/lib/red_storm/dsl/bolt.rb +7 -2
  21. data/lib/red_storm/dsl/output_collector.rb +8 -0
  22. data/lib/red_storm/dsl/spout.rb +3 -1
  23. data/lib/red_storm/dsl/topology.rb +2 -2
  24. data/lib/red_storm/dsl/tuple.rb +2 -0
  25. data/lib/red_storm/topology_launcher.rb +14 -10
  26. data/lib/red_storm/version.rb +1 -1
  27. data/redstorm.gemspec +1 -0
  28. data/src/main/redstorm/storm/jruby/JRubyBatchBolt.java +53 -35
  29. data/src/main/redstorm/storm/jruby/JRubyBatchSpout.java +77 -42
  30. data/src/main/redstorm/storm/jruby/JRubyBolt.java +54 -34
  31. data/src/main/redstorm/storm/jruby/JRubySpout.java +62 -40
  32. data/src/main/redstorm/storm/jruby/JRubyTransactionalBolt.java +57 -35
  33. data/src/main/redstorm/storm/jruby/JRubyTransactionalCommitterBolt.java +6 -17
  34. data/src/main/redstorm/storm/jruby/JRubyTransactionalCommitterSpout.java +14 -26
  35. data/src/main/redstorm/storm/jruby/JRubyTransactionalSpout.java +60 -37
  36. data/src/main/redstorm/storm/jruby/JRubyTridentFunction.java +66 -0
  37. metadata +16 -23
  38. data/lib/red_storm/proxy/batch_bolt.rb +0 -63
  39. data/lib/red_storm/proxy/batch_committer_bolt.rb +0 -52
  40. data/lib/red_storm/proxy/batch_spout.rb +0 -59
  41. data/lib/red_storm/proxy/bolt.rb +0 -63
  42. data/lib/red_storm/proxy/proxy_function.rb +0 -40
  43. data/lib/red_storm/proxy/spout.rb +0 -87
  44. data/lib/red_storm/proxy/transactional_committer_spout.rb +0 -47
  45. data/lib/red_storm/proxy/transactional_spout.rb +0 -46
  46. data/src/main/redstorm/storm/jruby/JRubyProxyFunction.java +0 -51
@@ -8,81 +8,101 @@ import backtype.storm.tuple.Tuple;
8
8
  import backtype.storm.tuple.Fields;
9
9
  import java.util.Map;
10
10
 
11
+ import org.jruby.Ruby;
12
+ import org.jruby.RubyObject;
13
+ import org.jruby.runtime.Helpers;
14
+ import org.jruby.runtime.builtin.IRubyObject;
15
+ import org.jruby.javasupport.JavaUtil;
16
+ import org.jruby.RubyModule;
17
+ import org.jruby.exceptions.RaiseException;
18
+
11
19
  /**
12
- * the JRubyBolt class is a simple proxy class to the actual bolt implementation in JRuby.
13
- * this proxy is required to bypass the serialization/deserialization process when dispatching
14
- * the bolts to the workers. JRuby does not yet support serialization from Java
15
- * (Java serialization call on a JRuby class).
20
+ * the JRubyBolt class is a proxy class to the actual bolt implementation in JRuby.
21
+ * this proxy is required to bypass the serialization/deserialization issues of JRuby objects.
22
+ * JRuby classes do not support Java serialization.
16
23
  *
17
- * Note that the JRuby bolt proxy class is instanciated in the prepare method which is called after
18
- * deserialization at the worker and in the declareOutputFields method which is called once before
19
- * serialization at topology creation.
24
+ * Note that the JRuby bolt class is instanciated in the prepare method which is called after
25
+ * deserialization at the worker and in the declareOutputFields & getComponentConfiguration
26
+ * methods which are called once before serialization at topology creation.
20
27
  */
21
28
  public class JRubyBolt implements IRichBolt {
22
- IRichBolt _proxyBolt;
23
- String _realBoltClassName;
24
- String _baseClassPath;
25
- String[] _fields;
29
+ private final String _realBoltClassName;
30
+ private final String[] _fields;
31
+ private final String _bootstrap;
32
+
33
+ // transient to avoid serialization
34
+ private transient IRubyObject _ruby_bolt;
35
+ private transient Ruby __ruby__;
26
36
 
27
37
  /**
28
38
  * create a new JRubyBolt
29
- *
30
- * @param baseClassPath the topology/project base JRuby class file path
39
+ *
40
+ * @param baseClassPath the topology/project base JRuby class file path
31
41
  * @param realBoltClassName the fully qualified JRuby bolt implementation class name
42
+ * @param fields the output fields names
32
43
  */
33
44
  public JRubyBolt(String baseClassPath, String realBoltClassName, String[] fields) {
34
- _baseClassPath = baseClassPath;
35
45
  _realBoltClassName = realBoltClassName;
36
46
  _fields = fields;
47
+ _bootstrap = "require '" + baseClassPath + "'";
37
48
  }
38
49
 
39
50
  @Override
40
- public void prepare(final Map stormConf, final TopologyContext context, final OutputCollector collector) {
41
- // create instance of the jruby class here, after deserialization in the workers.
42
- _proxyBolt = newProxyBolt(_baseClassPath, _realBoltClassName);
43
- _proxyBolt.prepare(stormConf, context, collector);
51
+ public void prepare(final Map conf, final TopologyContext context, final OutputCollector collector) {
52
+ _ruby_bolt = initialize_ruby_bolt();
53
+ IRubyObject ruby_conf = JavaUtil.convertJavaToRuby(__ruby__, conf);
54
+ IRubyObject ruby_context = JavaUtil.convertJavaToRuby(__ruby__, context);
55
+ IRubyObject ruby_collector = JavaUtil.convertJavaToRuby(__ruby__, collector);
56
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "prepare", ruby_conf, ruby_context, ruby_collector);
44
57
  }
45
58
 
46
59
  @Override
47
60
  public void execute(Tuple input) {
48
- _proxyBolt.execute(input);
61
+ IRubyObject ruby_input = JavaUtil.convertJavaToRuby(__ruby__, input);
62
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "execute", ruby_input);
49
63
  }
50
64
 
51
65
  @Override
52
66
  public void cleanup() {
53
- _proxyBolt.cleanup();
67
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "cleanup");
54
68
  }
55
69
 
56
70
  @Override
57
71
  public void declareOutputFields(OutputFieldsDeclarer declarer) {
58
72
  // declareOutputFields is executed in the topology creation time, before serialisation.
59
- // do not set the _proxyBolt instance variable here to avoid JRuby serialization
60
- // issues. Just create tmp bolt instance to call declareOutputFields.
73
+ // just create tmp bolt instance to call declareOutputFields.
74
+
61
75
  if (_fields.length > 0) {
62
76
  declarer.declare(new Fields(_fields));
63
77
  } else {
64
- IRichBolt bolt = newProxyBolt(_baseClassPath, _realBoltClassName);
65
- bolt.declareOutputFields(declarer);
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);
66
81
  }
67
82
  }
68
83
 
69
84
  @Override
70
85
  public Map<String, Object> getComponentConfiguration() {
71
86
  // getComponentConfiguration is executed in the topology creation time, before serialisation.
72
- // do not set the _proxyBolt instance variable here to avoid JRuby serialization
73
- // issues. Just create tmp bolt instance to call declareOutputFields.
74
- IRichBolt bolt = newProxyBolt(_baseClassPath, _realBoltClassName);
75
- return bolt.getComponentConfiguration();
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);
76
92
  }
77
-
78
93
 
79
- private static IRichBolt newProxyBolt(String baseClassPath, String realBoltClassName) {
94
+ private IRubyObject initialize_ruby_bolt() {
95
+ __ruby__ = Ruby.getGlobalRuntime();
96
+
97
+ RubyModule ruby_class;
80
98
  try {
81
- redstorm.proxy.Bolt proxy = new redstorm.proxy.Bolt(baseClassPath, realBoltClassName);
82
- return proxy;
99
+ ruby_class = __ruby__.getClassFromPath(_realBoltClassName);
83
100
  }
84
- catch (Exception e) {
85
- throw new RuntimeException(e);
101
+ catch (RaiseException e) {
102
+ // after deserialization we need to recreate ruby environment
103
+ __ruby__.evalScriptlet(_bootstrap);
104
+ ruby_class = __ruby__.getClassFromPath(_realBoltClassName);
86
105
  }
106
+ return Helpers.invoke(__ruby__.getCurrentContext(), ruby_class, "new");
87
107
  }
88
108
  }
@@ -8,100 +8,122 @@ import backtype.storm.tuple.Tuple;
8
8
  import backtype.storm.tuple.Fields;
9
9
  import java.util.Map;
10
10
 
11
+ import org.jruby.Ruby;
12
+ import org.jruby.RubyObject;
13
+ import org.jruby.runtime.Helpers;
14
+ import org.jruby.runtime.builtin.IRubyObject;
15
+ import org.jruby.javasupport.JavaUtil;
16
+ import org.jruby.RubyModule;
17
+ import org.jruby.exceptions.RaiseException;
18
+
11
19
  /**
12
- * the JRubySpout class is a simple proxy class to the actual spout implementation in JRuby.
13
- * this proxy is required to bypass the serialization/deserialization process when dispatching
14
- * the spout to the workers. JRuby does not yet support serialization from Java
15
- * (Java serialization call on a JRuby class).
20
+ * the JRubySpout class is a proxy class to the actual spout implementation in JRuby.
21
+ * this proxy is required to bypass the serialization/deserialization issues of JRuby objects.
22
+ * JRuby classes do not support Java serialization.
16
23
  *
17
- * Note that the JRuby spout proxy class is instanciated in the open method which is called after
18
- * deserialization at the worker and in both the declareOutputFields and isDistributed methods which
19
- * are called once before serialization at topology creation.
24
+ * Note that the JRuby spout class is instanciated in the open method which is called after
25
+ * deserialization at the worker and in the declareOutputFields & getComponentConfiguration
26
+ * methods which are called once before serialization at topology creation.
20
27
  */
21
28
  public class JRubySpout implements IRichSpout {
22
- IRichSpout _proxySpout;
23
- String _realSpoutClassName;
24
- String _baseClassPath;
25
- String[] _fields;
29
+ private final String _realSpoutClassName;
30
+ private final String[] _fields;
31
+ private final String _bootstrap;
32
+
33
+ // transient to avoid serialization
34
+ private transient IRubyObject _ruby_spout;
35
+ private transient Ruby __ruby__;
26
36
 
27
37
  /**
28
38
  * create a new JRubySpout
29
- *
30
- * @param baseClassPath the topology/project base JRuby class file path
39
+ *
40
+ * @param baseClassPath the topology/project base JRuby class file path
31
41
  * @param realSpoutClassName the fully qualified JRuby spout implementation class name
42
+ * @param fields the output fields names
32
43
  */
33
44
  public JRubySpout(String baseClassPath, String realSpoutClassName, String[] fields) {
34
- _baseClassPath = baseClassPath;
35
45
  _realSpoutClassName = realSpoutClassName;
36
46
  _fields = fields;
47
+ _bootstrap = "require '" + baseClassPath + "'";
37
48
  }
38
49
 
39
50
  @Override
40
51
  public void open(final Map conf, final TopologyContext context, final SpoutOutputCollector collector) {
41
- // create instance of the jruby proxy class here, after deserialization in the workers.
42
- _proxySpout = newProxySpout(_baseClassPath, _realSpoutClassName);
43
- _proxySpout.open(conf, context, collector);
52
+ _ruby_spout = initialize_ruby_spout();
53
+ IRubyObject ruby_conf = JavaUtil.convertJavaToRuby(__ruby__, conf);
54
+ IRubyObject ruby_context = JavaUtil.convertJavaToRuby(__ruby__, context);
55
+ IRubyObject ruby_collector = JavaUtil.convertJavaToRuby(__ruby__, collector);
56
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "open", ruby_conf, ruby_context, ruby_collector);
44
57
  }
45
58
 
46
59
  @Override
47
60
  public void close() {
48
- _proxySpout.close();
61
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "close");
49
62
  }
50
63
 
51
64
  @Override
52
65
  public void activate() {
53
- _proxySpout.activate();
66
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "activate");
54
67
  }
55
68
 
56
69
  @Override
57
70
  public void deactivate() {
58
- _proxySpout.deactivate();
71
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "deactivate");
59
72
  }
60
73
 
61
74
  @Override
62
75
  public void nextTuple() {
63
- _proxySpout.nextTuple();
76
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "next_tuple");
64
77
  }
65
78
 
66
79
  @Override
67
80
  public void ack(Object msgId) {
68
- _proxySpout.ack(msgId);
81
+ IRubyObject ruby_msg_id = JavaUtil.convertJavaToRuby(__ruby__, msgId);
82
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "ack", ruby_msg_id);
69
83
  }
70
84
 
71
85
  @Override
72
86
  public void fail(Object msgId) {
73
- _proxySpout.fail(msgId);
87
+ IRubyObject ruby_msg_id = JavaUtil.convertJavaToRuby(__ruby__, msgId);
88
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_spout, "fail", ruby_msg_id);
74
89
  }
75
90
 
76
91
  @Override
77
92
  public void declareOutputFields(OutputFieldsDeclarer declarer) {
78
- // declareOutputFields is executed in the topology creation time before serialisation.
79
- // do not set the _proxySpout instance variable here to avoid JRuby serialization
80
- // issues. Just create tmp spout instance to call declareOutputFields.
93
+ // declareOutputFields is executed in the topology creation time, before serialisation.
94
+ // just create tmp spout instance to call declareOutputFields.
95
+
81
96
  if (_fields.length > 0) {
82
97
  declarer.declare(new Fields(_fields));
83
98
  } else {
84
- IRichSpout spout = newProxySpout(_baseClassPath, _realSpoutClassName);
85
- spout.declareOutputFields(declarer);
99
+ IRubyObject ruby_spout = initialize_ruby_spout();
100
+ IRubyObject ruby_declarer = JavaUtil.convertJavaToRuby(__ruby__, declarer);
101
+ Helpers.invoke(__ruby__.getCurrentContext(), ruby_spout, "declare_output_fields", ruby_declarer);
86
102
  }
87
- }
103
+ }
88
104
 
89
105
  @Override
90
106
  public Map<String, Object> getComponentConfiguration() {
91
- // getComponentConfiguration is executed in the topology creation time before serialisation.
92
- // do not set the _proxySpout instance variable here to avoid JRuby serialization
93
- // issues. Just create tmp spout instance to call declareOutputFields.
94
- IRichSpout spout = newProxySpout(_baseClassPath, _realSpoutClassName);
95
- return spout.getComponentConfiguration();
107
+ // getComponentConfiguration is executed in the topology creation time, before serialisation.
108
+ // just create tmp spout instance to call getComponentConfiguration.
109
+
110
+ IRubyObject ruby_spout = initialize_ruby_spout();
111
+ IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), ruby_spout, "get_component_configuration");
112
+ return (Map)ruby_result.toJava(Map.class);
96
113
  }
97
-
98
- private static IRichSpout newProxySpout(String baseClassPath, String realSpoutClassName) {
114
+
115
+ private IRubyObject initialize_ruby_spout() {
116
+ __ruby__ = Ruby.getGlobalRuntime();
117
+
118
+ RubyModule ruby_class;
99
119
  try {
100
- redstorm.proxy.Spout proxy = new redstorm.proxy.Spout(baseClassPath, realSpoutClassName);
101
- return proxy;
120
+ ruby_class = __ruby__.getClassFromPath(_realSpoutClassName);
102
121
  }
103
- catch (Exception e) {
104
- throw new RuntimeException(e);
122
+ catch (RaiseException e) {
123
+ // after deserialization we need to recreate ruby environment
124
+ __ruby__.evalScriptlet(_bootstrap);
125
+ ruby_class = __ruby__.getClassFromPath(_realSpoutClassName);
105
126
  }
127
+ return Helpers.invoke(__ruby__.getCurrentContext(), ruby_class, "new");
106
128
  }
107
129
  }
@@ -11,80 +11,102 @@ import backtype.storm.tuple.Tuple;
11
11
  import backtype.storm.tuple.Fields;
12
12
  import java.util.Map;
13
13
 
14
+ import org.jruby.Ruby;
15
+ import org.jruby.RubyObject;
16
+ import org.jruby.runtime.Helpers;
17
+ import org.jruby.runtime.builtin.IRubyObject;
18
+ import org.jruby.javasupport.JavaUtil;
19
+ import org.jruby.RubyModule;
20
+ import org.jruby.exceptions.RaiseException;
21
+
14
22
  /**
15
- * the JRubyBolt class is a simple proxy class to the actual bolt implementation in JRuby.
16
- * this proxy is required to bypass the serialization/deserialization process when dispatching
17
- * the bolts to the workers. JRuby does not yet support serialization from Java
18
- * (Java serialization call on a JRuby class).
23
+ * the JRubyBolt class is a proxy class to the actual bolt implementation in JRuby.
24
+ * this proxy is required to bypass the serialization/deserialization issues of JRuby objects.
25
+ * JRuby classes do not support Java serialization.
19
26
  *
20
- * Note that the JRuby bolt proxy class is instanciated in the prepare method which is called after
21
- * deserialization at the worker and in the declareOutputFields method which is called once before
22
- * serialization at topology creation.
27
+ * Note that the JRuby bolt class is instanciated in the prepare method which is called after
28
+ * deserialization at the worker and in the declareOutputFields & getComponentConfiguration
29
+ * methods which are called once before serialization at topology creation.
23
30
  */
24
31
  public class JRubyTransactionalBolt extends BaseTransactionalBolt {
25
- IBatchBolt _proxyBolt;
26
- String _realBoltClassName;
27
- String _baseClassPath;
28
- String[] _fields;
32
+ private final String _realBoltClassName;
33
+ private final String[] _fields;
34
+ private final String _bootstrap;
35
+
36
+ // transient to avoid serialization
37
+ protected transient IRubyObject _ruby_bolt;
38
+ protected transient Ruby __ruby__;
29
39
 
30
- /**
40
+ /**
31
41
  * create a new JRubyBolt
32
- *
33
- * @param baseClassPath the topology/project base JRuby class file path
42
+ *
43
+ * @param baseClassPath the topology/project base JRuby class file path
34
44
  * @param realBoltClassName the fully qualified JRuby bolt implementation class name
45
+ * @param fields the output fields names
35
46
  */
36
47
  public JRubyTransactionalBolt(String baseClassPath, String realBoltClassName, String[] fields) {
37
- _baseClassPath = baseClassPath;
38
48
  _realBoltClassName = realBoltClassName;
39
49
  _fields = fields;
50
+ _bootstrap = "require '" + baseClassPath + "'";
40
51
  }
41
52
 
42
53
  @Override
43
- public void prepare(final Map stormConf, final TopologyContext context, final BatchOutputCollector collector, final TransactionAttempt id) {
44
- // create instance of the jruby class here, after deserialization in the workers.
45
- _proxyBolt = newProxyBolt(_baseClassPath, _realBoltClassName);
46
- _proxyBolt.prepare(stormConf, context, collector, id);
54
+ public void prepare(final Map conf, final TopologyContext context, final BatchOutputCollector collector, final TransactionAttempt id) {
55
+ _ruby_bolt = initialize_ruby_bolt();
56
+ IRubyObject ruby_conf = JavaUtil.convertJavaToRuby(__ruby__, conf);
57
+ IRubyObject ruby_context = JavaUtil.convertJavaToRuby(__ruby__, context);
58
+ IRubyObject ruby_collector = JavaUtil.convertJavaToRuby(__ruby__, collector);
59
+ IRubyObject ruby_id = JavaUtil.convertJavaToRuby(__ruby__, id);
60
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "prepare", ruby_conf, ruby_context, ruby_collector, ruby_id);
47
61
  }
48
62
 
49
63
  @Override
50
64
  public void execute(Tuple input) {
51
- _proxyBolt.execute(input);
65
+ IRubyObject ruby_input = JavaUtil.convertJavaToRuby(__ruby__, input);
66
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "execute", ruby_input);
52
67
  }
53
68
 
54
69
  @Override
55
70
  public void finishBatch() {
56
- _proxyBolt.finishBatch();
71
+ Helpers.invoke(__ruby__.getCurrentContext(), _ruby_bolt, "finish_batch");
57
72
  }
58
73
 
59
74
  @Override
60
75
  public void declareOutputFields(OutputFieldsDeclarer declarer) {
61
76
  // declareOutputFields is executed in the topology creation time, before serialisation.
62
- // do not set the _proxyBolt instance variable here to avoid JRuby serialization
63
- // issues. Just create tmp bolt instance to call declareOutputFields.
77
+ // just create tmp bolt instance to call declareOutputFields.
78
+
64
79
  if (_fields.length > 0) {
65
80
  declarer.declare(new Fields(_fields));
66
81
  } else {
67
- IBatchBolt bolt = newProxyBolt(_baseClassPath, _realBoltClassName);
68
- bolt.declareOutputFields(declarer);
82
+ IRubyObject ruby_bolt = initialize_ruby_bolt();
83
+ IRubyObject ruby_declarer = JavaUtil.convertJavaToRuby(__ruby__, declarer);
84
+ Helpers.invoke(__ruby__.getCurrentContext(), ruby_bolt, "declare_output_fields", ruby_declarer);
69
85
  }
70
86
  }
71
87
 
72
88
  @Override
73
89
  public Map<String, Object> getComponentConfiguration() {
74
90
  // getComponentConfiguration is executed in the topology creation time, before serialisation.
75
- // do not set the _proxyBolt instance variable here to avoid JRuby serialization
76
- // issues. Just create tmp bolt instance to call declareOutputFields.
77
- IBatchBolt bolt = newProxyBolt(_baseClassPath, _realBoltClassName);
78
- return bolt.getComponentConfiguration();
91
+ // just create tmp bolt instance to call getComponentConfiguration.
92
+
93
+ IRubyObject ruby_bolt = initialize_ruby_bolt();
94
+ IRubyObject ruby_result = Helpers.invoke(__ruby__.getCurrentContext(), ruby_bolt, "get_component_configuration");
95
+ return (Map)ruby_result.toJava(Map.class);
79
96
  }
80
-
81
- private static IBatchBolt newProxyBolt(String baseClassPath, String realBoltClassName) {
97
+
98
+ protected IRubyObject initialize_ruby_bolt() {
99
+ __ruby__ = Ruby.getGlobalRuntime();
100
+
101
+ RubyModule ruby_class;
82
102
  try {
83
- redstorm.proxy.BatchBolt proxy = new redstorm.proxy.BatchBolt(baseClassPath, realBoltClassName);
84
- return proxy;
103
+ ruby_class = __ruby__.getClassFromPath(_realBoltClassName);
85
104
  }
86
- catch (Exception e) {
87
- throw new RuntimeException(e);
105
+ catch (RaiseException e) {
106
+ // after deserialization we need to recreate ruby environment
107
+ __ruby__.evalScriptlet(_bootstrap);
108
+ ruby_class = __ruby__.getClassFromPath(_realBoltClassName);
88
109
  }
110
+ return Helpers.invoke(__ruby__.getCurrentContext(), ruby_class, "new");
89
111
  }
90
112
  }
@@ -5,27 +5,16 @@ import backtype.storm.transactional.TransactionAttempt;
5
5
  import backtype.storm.transactional.ICommitter;
6
6
 
7
7
  /**
8
- * the JRubyBolt class is a simple proxy class to the actual bolt implementation in JRuby.
9
- * this proxy is required to bypass the serialization/deserialization process when dispatching
10
- * the bolts to the workers. JRuby does not yet support serialization from Java
11
- * (Java serialization call on a JRuby class).
8
+ * the JRubyBolt class is a proxy class to the actual bolt implementation in JRuby.
9
+ * this proxy is required to bypass the serialization/deserialization issues of JRuby objects.
10
+ * JRuby classes do not support Java serialization.
12
11
  *
13
- * Note that the JRuby bolt proxy class is instanciated in the prepare method which is called after
14
- * deserialization at the worker and in the declareOutputFields method which is called once before
15
- * serialization at topology creation.
12
+ * Note that the JRuby bolt class is instanciated in the prepare method which is called after
13
+ * deserialization at the worker and in the declareOutputFields & getComponentConfiguration
14
+ * methods which are called once before serialization at topology creation.
16
15
  */
17
16
  public class JRubyTransactionalCommitterBolt extends JRubyTransactionalBolt implements ICommitter {
18
17
  public JRubyTransactionalCommitterBolt(String baseClassPath, String realBoltClassName, String[] fields) {
19
18
  super(baseClassPath, realBoltClassName, fields);
20
19
  }
21
-
22
- private static IBatchBolt newProxyBolt(String baseClassPath, String realBoltClassName) {
23
- try {
24
- redstorm.proxy.BatchCommitterBolt proxy = new redstorm.proxy.BatchCommitterBolt(baseClassPath, realBoltClassName);
25
- return proxy;
26
- }
27
- catch (Exception e) {
28
- throw new RuntimeException(e);
29
- }
30
- }
31
20
  }