speednode 0.8.2 → 0.9.0
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 +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 +11 -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
|
@@ -154,6 +158,7 @@ module Speednode
|
|
154
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])
|
158
163
|
Process.detach(@pid)
|
159
164
|
|
@@ -184,8 +189,7 @@ module Speednode
|
|
184
189
|
|
185
190
|
@started = true
|
186
191
|
|
187
|
-
exit_proc = self.class.finalize(@socket, @socket_dir, @socket_path, @pid)
|
188
|
-
|
192
|
+
exit_proc = self.class.finalize(@socket, @socket_dir, @socket_path, @pid, @spawner_pid)
|
189
193
|
Kernel.at_exit { exit_proc.call }
|
190
194
|
end
|
191
195
|
|
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.
|