speednode 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -2
- data/lib/speednode/runner.js +5 -3
- data/lib/speednode/runtime/context.rb +5 -9
- data/lib/speednode/runtime/vm.rb +14 -7
- data/lib/speednode/runtime.rb +6 -3
- data/lib/speednode/version.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3cb17f3391d9416c0a92291be8beaa42b25d8df70528e400d28a41984e3693bf
|
4
|
+
data.tar.gz: 463169b3ceb3d42703cbee80aa56c7edf2e1196a0114f8607eed173d0d6af583
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fc644dbb0581167a2d03fe19b157cdd82fc2da2af2de29e80b4676e21097c2437e9da5acdb7bd6bdf0d6c52391bea5ad04b5a392e3717c2fb72cf0bc8004f1d5
|
7
|
+
data.tar.gz: 5e391001e4d7b42accf5c4b29ed424637fce9193871feb65a2c145ebc2ac082a94711031e70bf0221d9e70bc77cf40602f916f3571eb7a8d7624624deea52b06
|
data/README.md
CHANGED
@@ -48,7 +48,7 @@ ExecJS.permissive_eval('1+1')
|
|
48
48
|
```
|
49
49
|
|
50
50
|
#### Stopping Contexts
|
51
|
-
Contexts
|
51
|
+
Contexts should be stopped programmatically when no longer needed.
|
52
52
|
```ruby
|
53
53
|
context = ExecJS.compile('Test = "test"') # will start a node process
|
54
54
|
ExecJS::Runtimes::Speednode.stop_context(context) # will kill the node process
|
@@ -80,7 +80,7 @@ context.await("foo('test')") # => 'test'
|
|
80
80
|
|
81
81
|
### Attaching ruby methods to Permissive Contexts
|
82
82
|
|
83
|
-
Ruby methods can be attached to
|
83
|
+
Ruby methods can be attached to permissive contexts using Context#attach:
|
84
84
|
```ruby
|
85
85
|
context = ExecJS.permissive_compile(SOURCE)
|
86
86
|
context.attach('foo') { |v| v }
|
data/lib/speednode/runner.js
CHANGED
@@ -9,8 +9,8 @@ try {
|
|
9
9
|
crypto_var = require('crypto');
|
10
10
|
} catch (err) {}
|
11
11
|
const crypto = crypto_var;
|
12
|
-
let contexts =
|
13
|
-
let scripts =
|
12
|
+
let contexts = Object.create(null);
|
13
|
+
let scripts = Object.create(null);
|
14
14
|
let process_exit = false;
|
15
15
|
|
16
16
|
/*** circular-json, originally taken from https://raw.githubusercontent.com/WebReflection/circular-json/
|
@@ -41,7 +41,7 @@ let process_exit = false;
|
|
41
41
|
|
42
42
|
*/
|
43
43
|
|
44
|
-
const CircularJSON =
|
44
|
+
const CircularJSON = Object.create(null);
|
45
45
|
CircularJSON.specialChar = '~';
|
46
46
|
CircularJSON.safeSpecialChar = '\\x' + ('0' + CircularJSON.specialChar.charCodeAt(0).toString(16)).slice(-2);
|
47
47
|
CircularJSON.escapedSafeSpecialChar = '\\' + CircularJSON.safeSpecialChar;
|
@@ -240,6 +240,8 @@ function getContext(uuid) {
|
|
240
240
|
|
241
241
|
function getContextOptions(uuid) {
|
242
242
|
let options = { filename: "(execjs)", displayErrors: true };
|
243
|
+
if (!contexts[uuid])
|
244
|
+
throw new Error(`Context ${uuid} not found`);
|
243
245
|
if (contexts[uuid].options.timeout)
|
244
246
|
options.timeout = contexts[uuid].options.timeout;
|
245
247
|
return options;
|
@@ -1,12 +1,6 @@
|
|
1
1
|
module Speednode
|
2
2
|
class Runtime < ExecJS::Runtime
|
3
3
|
class Context < ::ExecJS::Runtime::Context
|
4
|
-
def self.finalize(runtime, uuid)
|
5
|
-
proc do
|
6
|
-
runtime.unregister_context(uuid)
|
7
|
-
end
|
8
|
-
end
|
9
|
-
|
10
4
|
def initialize(runtime, source = "", options = {})
|
11
5
|
@runtime = runtime
|
12
6
|
@uuid = SecureRandom.uuid
|
@@ -16,7 +10,7 @@ module Speednode
|
|
16
10
|
@debug = false unless ENV['NODE_OPTIONS']&.include?('--inspect')
|
17
11
|
@vm = @runtime.vm
|
18
12
|
@timeout = options[:timeout] ? options[:timeout]/1000 : 600
|
19
|
-
|
13
|
+
|
20
14
|
filename = options.delete(:filename)
|
21
15
|
source = File.read(filename) if filename
|
22
16
|
|
@@ -26,8 +20,6 @@ module Speednode
|
|
26
20
|
source = source.force_encoding('UTF-8')
|
27
21
|
end
|
28
22
|
|
29
|
-
ObjectSpace.define_finalizer(self, self.class.finalize(@runtime, @uuid))
|
30
|
-
|
31
23
|
if @debug && @permissive
|
32
24
|
raw_created(source, options)
|
33
25
|
elsif @permissive
|
@@ -105,6 +97,10 @@ module Speednode
|
|
105
97
|
raw_exec("(function(){#{source}})()")
|
106
98
|
end
|
107
99
|
|
100
|
+
def available?
|
101
|
+
@runtime.context_registered?(@uuid)
|
102
|
+
end
|
103
|
+
|
108
104
|
def stop
|
109
105
|
@runtime.unregister_context(@uuid)
|
110
106
|
end
|
data/lib/speednode/runtime/vm.rb
CHANGED
@@ -40,14 +40,17 @@ end
|
|
40
40
|
module Speednode
|
41
41
|
class Runtime < ExecJS::Runtime
|
42
42
|
class VM
|
43
|
-
def self.finalize(socket, socket_dir, socket_path, pid)
|
43
|
+
def self.finalize(socket, socket_dir, socket_path, pid, spawner_pid)
|
44
44
|
proc do
|
45
|
-
|
46
|
-
|
45
|
+
if spawner_pid == Process.pid
|
46
|
+
::Speednode::Runtime.responders[socket_path].kill if ::Speednode::Runtime.responders[socket_path]
|
47
|
+
exit_node(socket, socket_dir, socket_path, pid, spawner_pid)
|
48
|
+
end
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
50
|
-
def self.exit_node(socket, socket_dir, socket_path, pid)
|
52
|
+
def self.exit_node(socket, socket_dir, socket_path, pid, spawner_pid)
|
53
|
+
return if spawner_pid != Process.pid
|
51
54
|
VMCommand.new(socket, "exit", 0).execute rescue nil
|
52
55
|
socket.close
|
53
56
|
File.unlink(socket_path) if File.exist?(socket_path)
|
@@ -135,8 +138,9 @@ module Speednode
|
|
135
138
|
|
136
139
|
def stop
|
137
140
|
return unless @started
|
141
|
+
return if @spawner_pid != Process.pid
|
138
142
|
@mutex.synchronize do
|
139
|
-
self.class.exit_node(@socket, @socket_dir, @socket_path, @pid)
|
143
|
+
self.class.exit_node(@socket, @socket_dir, @socket_path, @pid, @spawner_pid)
|
140
144
|
@socket_path = nil
|
141
145
|
@started = false
|
142
146
|
@socket = nil
|
@@ -151,10 +155,12 @@ module Speednode
|
|
151
155
|
@socket_dir = nil
|
152
156
|
@socket_path = SecureRandom.uuid
|
153
157
|
else
|
154
|
-
@socket_dir = Dir.mktmpdir("
|
158
|
+
@socket_dir = Dir.mktmpdir("speednode-")
|
155
159
|
@socket_path = File.join(@socket_dir, "socket")
|
156
160
|
end
|
161
|
+
@spawner_pid = Process.pid
|
157
162
|
@pid = Process.spawn({"SOCKET_PATH" => @socket_path}, @options[:binary], '--expose-gc', @options[:source_maps], @options[:runner_path])
|
163
|
+
Process.detach(@pid)
|
158
164
|
|
159
165
|
retries = 500
|
160
166
|
|
@@ -183,7 +189,8 @@ module Speednode
|
|
183
189
|
|
184
190
|
@started = true
|
185
191
|
|
186
|
-
|
192
|
+
exit_proc = self.class.finalize(@socket, @socket_dir, @socket_path, @pid, @spawner_pid)
|
193
|
+
Kernel.at_exit { exit_proc.call }
|
187
194
|
end
|
188
195
|
|
189
196
|
def create_responder(context)
|
data/lib/speednode/runtime.rb
CHANGED
@@ -24,7 +24,11 @@ module Speednode
|
|
24
24
|
@popen_options = {}
|
25
25
|
@popen_options[:external_encoding] = @encoding if @encoding
|
26
26
|
@popen_options[:internal_encoding] = ::Encoding.default_internal || 'UTF-8'
|
27
|
-
@contexts = {}
|
27
|
+
@contexts = {}
|
28
|
+
end
|
29
|
+
|
30
|
+
def context_registered?(uuid)
|
31
|
+
@contexts.key?(uuid)
|
28
32
|
end
|
29
33
|
|
30
34
|
def register_context(uuid, context)
|
@@ -33,8 +37,7 @@ module Speednode
|
|
33
37
|
|
34
38
|
def unregister_context(uuid)
|
35
39
|
context = @contexts.delete(uuid)
|
36
|
-
if context
|
37
|
-
ObjectSpace.undefine_finalizer(context)
|
40
|
+
if context
|
38
41
|
@vm.delete_context(uuid) rescue nil # if delete_context fails, the vm exited before probably
|
39
42
|
end
|
40
43
|
@vm.stop if @contexts.size == 0 && @vm.started?
|
data/lib/speednode/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: speednode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jan Biedermann
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: execjs
|
@@ -78,28 +78,28 @@ dependencies:
|
|
78
78
|
requirements:
|
79
79
|
- - "~>"
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: 5.
|
81
|
+
version: 5.23.0
|
82
82
|
type: :development
|
83
83
|
prerelease: false
|
84
84
|
version_requirements: !ruby/object:Gem::Requirement
|
85
85
|
requirements:
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
|
-
version: 5.
|
88
|
+
version: 5.23.0
|
89
89
|
- !ruby/object:Gem::Dependency
|
90
90
|
name: rake
|
91
91
|
requirement: !ruby/object:Gem::Requirement
|
92
92
|
requirements:
|
93
|
-
- - "
|
93
|
+
- - ">="
|
94
94
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
95
|
+
version: '0'
|
96
96
|
type: :development
|
97
97
|
prerelease: false
|
98
98
|
version_requirements: !ruby/object:Gem::Requirement
|
99
99
|
requirements:
|
100
|
-
- - "
|
100
|
+
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version:
|
102
|
+
version: '0'
|
103
103
|
- !ruby/object:Gem::Dependency
|
104
104
|
name: uglifier
|
105
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -114,8 +114,8 @@ dependencies:
|
|
114
114
|
- - ">="
|
115
115
|
- !ruby/object:Gem::Version
|
116
116
|
version: '0'
|
117
|
-
description: A fast ExecJS
|
118
|
-
|
117
|
+
description: A fast ExecJS, almost as fast as mini_racer, but without the need to
|
118
|
+
compile the js engine, because it uses the system provided nodejs.
|
119
119
|
email: jan@kursator.de
|
120
120
|
executables: []
|
121
121
|
extensions: []
|
@@ -156,7 +156,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
156
156
|
- !ruby/object:Gem::Version
|
157
157
|
version: '0'
|
158
158
|
requirements: []
|
159
|
-
rubygems_version: 3.5.
|
159
|
+
rubygems_version: 3.5.9
|
160
160
|
signing_key:
|
161
161
|
specification_version: 4
|
162
162
|
summary: A fast ExecJS runtime based on nodejs.
|