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.
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
  }