h8 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +11 -3
- data/ext/h8/h8.h +1 -1
- data/ext/h8/{JsCatcher.cpp → js_catcher.cpp} +1 -1
- data/ext/h8/{JsCatcher.h → js_catcher.h} +0 -0
- data/ext/h8/js_gate.cpp +1 -1
- data/ext/h8/ruby_gate.cpp +10 -8
- data/lib/h8/version.rb +1 -1
- data/spec/context_spec.rb +10 -11
- data/spec/threading_spec.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c54c93dc0687b6b01be98f4eeeebd6ea57143214
|
4
|
+
data.tar.gz: ecae54d59be0a790345400f28f83efa9f35e6bb4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
41
|
-
|
42
|
-
|
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
|
|
data/ext/h8/h8.h
CHANGED
File without changes
|
data/ext/h8/js_gate.cpp
CHANGED
data/ext/h8/ruby_gate.cpp
CHANGED
@@ -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
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
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
|
data/lib/h8/version.rb
CHANGED
data/spec/context_spec.rb
CHANGED
@@ -96,28 +96,27 @@ describe 'context' do
|
|
96
96
|
|
97
97
|
it 'should work in many threads' do
|
98
98
|
# pending
|
99
|
-
sum
|
99
|
+
sum = 0
|
100
100
|
mutex = Mutex.new
|
101
|
-
valid
|
102
|
-
n
|
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
|
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
|
-
|
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|
|
data/spec/threading_spec.rb
CHANGED
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.
|
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
|