h8 0.2.1 → 0.2.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0d9eec220ddcefcec439cacbc06a3a1aa9df74a4
4
- data.tar.gz: ff56274f0e8f976ea5afe8b35ed01259032330db
3
+ metadata.gz: c54c93dc0687b6b01be98f4eeeebd6ea57143214
4
+ data.tar.gz: ecae54d59be0a790345400f28f83efa9f35e6bb4
5
5
  SHA512:
6
- metadata.gz: 43eecac7e09f262bddbcb68fe49717c82f27778205bc2b6aa2bb0808b1ea6bc2131c7bdb3d808253a7a35134ff8da9c7cb5d92d190b86f6f46b5e39388782f1d
7
- data.tar.gz: 9741491ec26a3698b9a431624c4726db9989afa6ece6e09773eec14a7dcc711ca1fd9163467cc27e27ce2a947daa3af74713f99e17edc6407793a956c965e0ac
6
+ metadata.gz: 2c8cb7c8dc08fdc48b72900b57828661a5f36ea89620bbdbc99c80d2b75eec6759ae8349ac47eee2af01e4db3d93134da8c2c111843362db5970252b0abfd3e2
7
+ data.tar.gz: dcb9671dc11cd23d924e27686fb653703378143c681e9a4b379ab9a176b1e8f78651eb52996f6da2b0175341707edf8d720a8a9ea45c1d26b4a84bb15b44a701
data/README.md CHANGED
@@ -3,6 +3,10 @@
3
3
  _Warning_ this gem is a public beta at the moment - beta testers are welcome!It means, it is not
4
4
  yet production stable - we haven't yet tried.
5
5
 
6
+ _Current implementation is somewhat slower than it could by the price of letting ruby threads
7
+ and javascript codes in different H8::Context instances run in parallel in multicore hardware_.
8
+ Let me know whether it worth degraded performance on ruby-to-js and back calls.
9
+
6
10
  This gem was intended to replace therubyracer for many reasons:
7
11
 
8
12
  * therubyracer has critical bugs that are not fixed for a long time, under load it produces
@@ -37,10 +41,14 @@ uncaught javascript exceptions raise ruby error in ruby code.
37
41
 
38
42
  - Integrated CoffeeScript support
39
43
 
40
- - H8 is thread safe (using Lockers) and releases gvl when executing js code (and reqcquires it as
41
- need), thus other ruby threads can work in parallel with javascript executing threads. Still,
42
- h8 does not releases Locker when calling ruby code from javascript - for performance considerations.
44
+ - H8 is thread safe. It releases gvl lock while executing ruby code and unlocks v8 isolate when
45
+ calling ruby code thus allow maximum possibile parallel execution of ruby and javascript code
46
+ in separate threads.
43
47
 
48
+ Due to v8 and ruby MRI limitations, only one ruby thread can access any given H8::Context (e.g.
49
+ execute javascript code in it), and, as usual, all ruby threads are locked by a single mitex (gvl).
50
+ Still, having multiple H8::Context in different ruby threads let you run java/coffee scripts in
51
+ parallel - what you can not have with pure MRI ruby!
44
52
 
45
53
  ## Main difference from therubyracer/features not ready
46
54
 
@@ -6,7 +6,7 @@
6
6
  #include <iostream>
7
7
  #include <exception>
8
8
  #include "allocated_resource.h"
9
- #include "JsCatcher.h"
9
+ #include "js_catcher.h"
10
10
 
11
11
  using namespace v8;
12
12
  using namespace std;
@@ -5,7 +5,7 @@
5
5
  * Author: sergeych
6
6
  */
7
7
 
8
- #include "JsCatcher.h"
8
+ #include "js_catcher.h"
9
9
 
10
10
  namespace h8 {
11
11
 
File without changes
@@ -1,5 +1,5 @@
1
1
  #include "h8.h"
2
- #include "JsCatcher.h"
2
+ #include "js_catcher.h"
3
3
  #include <ruby/thread.h>
4
4
 
5
5
  using namespace h8;
@@ -13,16 +13,14 @@ static void* unblock_caller(void *param) {
13
13
  return NULL;
14
14
  }
15
15
 
16
- static void with_gvl(RubyGate *gate,
17
- const std::function<void(void)> &block) {
16
+ static void with_gvl(RubyGate *gate, const std::function<void(void)> &block) {
18
17
  // v8::Unlocker unlock(gate->isolate());
19
18
  H8 *h8 = gate->getH8();
20
19
  if (h8->isGvlReleased()) {
21
20
  h8->setGvlReleased(false);
22
21
  rb_thread_call_with_gvl(unblock_caller, (void*) &block);
23
22
  h8->setGvlReleased(true);
24
- }
25
- else
23
+ } else
26
24
  block();
27
25
  }
28
26
 
@@ -107,10 +105,14 @@ void h8::RubyGate::throw_js() {
107
105
 
108
106
  void h8::RubyGate::rescued_call(VALUE rb_args, VALUE (*call)(VALUE),
109
107
  const std::function<void(VALUE)> &block) {
110
- last_ruby_error = Qnil;
111
- VALUE me = Data_Wrap_Struct(ruby_gate_class, 0, 0, this);
112
- VALUE res = rb_rescue((ruby_method) (call), rb_args,
113
- (ruby_method) (rescue_callback), me);
108
+ VALUE res;
109
+ {
110
+ Unlocker u(context->getIsolate());
111
+ last_ruby_error = Qnil;
112
+ VALUE me = Data_Wrap_Struct(ruby_gate_class, 0, 0, this);
113
+ res = rb_rescue((ruby_method) (call), rb_args,
114
+ (ruby_method) (rescue_callback), me);
115
+ }
114
116
  if (last_ruby_error == Qnil)
115
117
  block(res);
116
118
  else
@@ -1,3 +1,3 @@
1
1
  module H8
2
- VERSION = "0.2.1"
2
+ VERSION = "0.2.2"
3
3
  end
@@ -96,28 +96,27 @@ describe 'context' do
96
96
 
97
97
  it 'should work in many threads' do
98
98
  # pending
99
- sum = 0
99
+ sum = 0
100
100
  mutex = Mutex.new
101
- valid = 0
102
- n = 10
103
- tt = []
101
+ valid = 0
102
+ n = 10
103
+ tt = []
104
104
  n.times { |n|
105
- cxt = nil
106
105
  t = Thread.start {
107
106
  cxt = H8::Context.new
107
+ tt << OpenStruct.new({ thread: t, number: n, context: cxt })
108
108
  cxt[:array] = 100024.times.map { |x| x*(n+1) }
109
109
  cxt[:n] = n+1
110
110
  mutex.synchronize {
111
111
  valid += (n+1)*100 + 10
112
- sum += cxt.eval('result = array[100] + 10')
112
+ sum += cxt.eval('result = array[100] + 10')
113
113
  }
114
- tt << OpenStruct.new({ thread: t, number: n, context: cxt })
115
114
  }
116
115
  }
117
- tt.each{ |x| x.thread.join }
118
- mutex.synchronize {
119
- sum.should == valid
120
- }
116
+ tt.each { |x| x.thread.join }
117
+ # mutex.synchronize {
118
+ sum.should == valid
119
+ # }
121
120
  GC.start
122
121
  # Cross-thread access
123
122
  tt.each { |x|
@@ -18,7 +18,7 @@ describe 'threading' do
18
18
  @context[:end] = @end_time
19
19
  end
20
20
 
21
- it 'without tout: should run JS/ruby threads in parallel' do
21
+ it 'should run JS/ruby threads in parallel' do
22
22
  cnt2 = 0
23
23
  Thread.start {
24
24
  cnt2 += 1 while Time.now.to_i < @end_time
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: h8
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - sergeych
@@ -86,13 +86,13 @@ files:
86
86
  - ext/.DS_Store
87
87
  - ext/h8/.cproject
88
88
  - ext/h8/.project
89
- - ext/h8/JsCatcher.cpp
90
- - ext/h8/JsCatcher.h
91
89
  - ext/h8/allocated_resource.h
92
90
  - ext/h8/chain.h
93
91
  - ext/h8/extconf.rb
94
92
  - ext/h8/h8.cpp
95
93
  - ext/h8/h8.h
94
+ - ext/h8/js_catcher.cpp
95
+ - ext/h8/js_catcher.h
96
96
  - ext/h8/js_gate.cpp
97
97
  - ext/h8/js_gate.h
98
98
  - ext/h8/main.cpp