isomorfeus-speednode 0.6.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 7b3ece9e49e7a5105aef77b28b04445e4d39e2f22d061bfd1f03e43a79e403eb
4
- data.tar.gz: e3d57e156c9d1efa686a18ae784125cc8c9d553e9946cabfd0c1325f20a959f0
3
+ metadata.gz: 91aa4cb54a3cb13afcf15476f841f711ce8de37c0573dfcdbd535aeda3a5dcbd
4
+ data.tar.gz: 4f1f9ccd06769d21ea4f25171cf128a69d8e4ea942f4417b10413f0df830b944
5
5
  SHA512:
6
- metadata.gz: 67a6b031a66b5b29a9db16924087dc013a4c0ce360edbc8c4db3c076766c6c31d00783472a7b6f4d6bde526c61602ff1a78cc4e343c142016ef183005dcb339c
7
- data.tar.gz: c4600a01abe22631455c4dce5209f656409a7931b5295116a551420c03c78906b3d6733afac90ebc87ce3835c9af2228b35c1e3bdb86296dc5aac2ce93b4ecdd
6
+ metadata.gz: ae92dbfa6c44909c8d9b27392cab6ae86854d25343074441b5b5657c54d36bbc5bf332b19c25fd9694f2a58d75abfdc859982cf79a08a7128916943e40c04ae3
7
+ data.tar.gz: b68a5bd5ebc54b333c67918f6a0a51f8fe871d5607c6b36b987163dd195243b1cb21181e4f52f714528b381ea7a81f43160b5327ddbf4380472cfc58daece9f2
data/README.md CHANGED
@@ -53,6 +53,13 @@ Evaluation in a permissive context:
53
53
  ExecJS.permissive_eval('1+1')
54
54
  ```
55
55
 
56
+ #### Stopping Contexts
57
+ Contexts can be stopped programmatically. If all contexts of a VM are stopped, the VM itself will be shut down with Node exiting, freeing memory and resources.
58
+ ```ruby
59
+ context = ExecJS.compile('Test = "test"') # will start a node process
60
+ ExecJS::Runtimes::Speednode.stop_context(context) # will kill the node process
61
+ ```
62
+
56
63
  ### Precompiling and Storing scripts for repeated execution
57
64
 
58
65
  Scripts can be precompiled and stored for repeated execution, which leads to a significant performance improvement, especially for larger scripts:
@@ -309,7 +309,7 @@ let commands = {
309
309
  deleteContext: function(uuid) {
310
310
  delete contexts[uuid];
311
311
  delete scripts[uuid]
312
- return [1];
312
+ return ['ok', Object.keys(contexts).length];
313
313
  },
314
314
  exit: function(code) {
315
315
  process_exit = code;
@@ -4,22 +4,20 @@ module Isomorfeus
4
4
  class Context < ::ExecJS::Runtime::Context
5
5
  def self.finalize(runtime, uuid)
6
6
  proc do
7
- runtime.vm.delete_context(uuid) rescue nil # if delete_context fails, the vm exited before probably
7
+ runtime.unregister_context(uuid)
8
8
  end
9
9
  end
10
10
 
11
11
  def initialize(runtime, source = "", options = {})
12
12
  @runtime = runtime
13
13
  @uuid = SecureRandom.uuid
14
+ @runtime.register_context(@uuid, self)
14
15
  @permissive = !!options.delete(:permissive)
15
16
  @debug = @permissive ? !!options.delete(:debug) { false } : false
16
17
  @debug = false unless ENV['NODE_OPTIONS']&.include?('--inspect')
17
18
  @vm = @runtime.vm
18
- @context = nil
19
19
  @timeout = options[:timeout] ? options[:timeout]/1000 : 600
20
-
21
- ObjectSpace.define_finalizer(self, self.class.finalize(@runtime, @uuid))
22
-
20
+
23
21
  filename = options.delete(:filename)
24
22
  source = File.read(filename) if filename
25
23
 
@@ -28,6 +26,9 @@ module Isomorfeus
28
26
  rescue
29
27
  source = source.force_encoding('UTF-8')
30
28
  end
29
+
30
+ ObjectSpace.define_finalizer(self, self.class.finalize(@runtime, @uuid))
31
+
31
32
  if @debug && @permissive
32
33
  raw_created(source, options)
33
34
  elsif @permissive
@@ -35,7 +36,8 @@ module Isomorfeus
35
36
  else
36
37
  raw_create(source, options)
37
38
  end
38
- self.add_script(key: :_internal_exec_fin, source: '!global.__LastExecutionFinished')
39
+
40
+ add_script(key: :_internal_exec_fin, source: '!global.__LastExecutionFinished')
39
41
  end
40
42
 
41
43
  # def options
@@ -104,6 +106,10 @@ module Isomorfeus
104
106
  raw_exec("(function(){#{source}})()")
105
107
  end
106
108
 
109
+ def stop
110
+ @runtime.unregister_context(@uuid)
111
+ end
112
+
107
113
  protected
108
114
 
109
115
  def raw_bench(source)
@@ -119,26 +125,20 @@ module Isomorfeus
119
125
  end
120
126
 
121
127
  def raw_create(source, options)
122
- return if @context
123
128
  source = encode(source)
124
129
  result = @vm.create(@uuid, source, options)
125
- @context = true
126
130
  extract_result(result)
127
131
  end
128
132
 
129
133
  def raw_created(source, options)
130
- return if @context
131
134
  source = encode(source)
132
135
  result = @vm.created(@uuid, source, options)
133
- @context = true
134
136
  extract_result(result)
135
137
  end
136
138
 
137
139
  def raw_createp(source, options)
138
- return if @context
139
140
  source = encode(source)
140
141
  result = @vm.createp(@uuid, source, options)
141
- @context = true
142
142
  extract_result(result)
143
143
  end
144
144
 
@@ -41,20 +41,6 @@ module Isomorfeus
41
41
  module Speednode
42
42
  class Runtime < ExecJS::Runtime
43
43
  class VM
44
- attr_reader :responder
45
-
46
- def initialize(options)
47
- @mutex = ::Thread::Mutex.new
48
- @socket_path = nil
49
- @options = options
50
- @started = false
51
- @socket = nil
52
- end
53
-
54
- def started?
55
- @started
56
- end
57
-
58
44
  def self.finalize(socket, socket_dir, socket_path, pid)
59
45
  proc do
60
46
  Isomorfeus::Speednode::Runtime.responders[socket_path].kill if Isomorfeus::Speednode::Runtime.responders[socket_path]
@@ -79,6 +65,20 @@ module Isomorfeus
79
65
  nil
80
66
  end
81
67
 
68
+ attr_reader :responder
69
+
70
+ def initialize(options)
71
+ @mutex = ::Thread::Mutex.new
72
+ @socket_path = nil
73
+ @options = options
74
+ @started = false
75
+ @socket = nil
76
+ end
77
+
78
+ def started?
79
+ @started
80
+ end
81
+
82
82
  def evsc(context, key)
83
83
  command('evsc', { 'context' => context, 'key' => key })
84
84
  end
@@ -134,6 +134,16 @@ module Isomorfeus
134
134
  end
135
135
  end
136
136
 
137
+ def stop
138
+ return unless @started
139
+ @mutex.synchronize do
140
+ self.class.exit_node(@socket, @socket_dir, @socket_path, @pid)
141
+ @socket_path = nil
142
+ @started = false
143
+ @socket = nil
144
+ end
145
+ end
146
+
137
147
  private
138
148
 
139
149
  def start_without_synchronization
@@ -19,14 +19,30 @@ module Isomorfeus
19
19
  @name = options[:name]
20
20
  @binary = Isomorfeus::Speednode::NodeCommand.cached(options[:command])
21
21
  @runner_path = options[:runner_path]
22
+ @vm = VM.new(binary: @binary, source_maps: '--enable-source-maps', runner_path: @runner_path)
22
23
  @encoding = options[:encoding]
23
24
  @deprecated = !!options[:deprecated]
24
-
25
- @vm = VM.new(binary: @binary, source_maps: '--enable-source-maps', runner_path: @runner_path)
26
-
27
25
  @popen_options = {}
28
26
  @popen_options[:external_encoding] = @encoding if @encoding
29
27
  @popen_options[:internal_encoding] = ::Encoding.default_internal || 'UTF-8'
28
+ @contexts = {}
29
+ end
30
+
31
+ def register_context(uuid, context)
32
+ @contexts[uuid] = context
33
+ end
34
+
35
+ def unregister_context(uuid)
36
+ context = @contexts.delete(uuid)
37
+ if context && @vm
38
+ ObjectSpace.undefine_finalizer(context)
39
+ _ok, cc = @vm.delete_context(uuid) rescue nil # if delete_context fails, the vm exited before probably
40
+ end
41
+ @vm.stop if @contexts.size == 0 && @vm.started?
42
+ end
43
+
44
+ def stop_context(context)
45
+ unregister_context(context.instance_variable_get(:@uuid))
30
46
  end
31
47
 
32
48
  def available?
@@ -1,5 +1,5 @@
1
1
  module Isomorfeus
2
2
  module Speednode
3
- VERSION = '0.6.3'
3
+ VERSION = '0.7.0'
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: isomorfeus-speednode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.3
4
+ version: 0.7.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: 2023-08-04 00:00:00.000000000 Z
11
+ date: 2023-08-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: execjs