rtext 0.9.3 → 0.9.4

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: 5a5cc8d9398e6453bbc549caf640e38dabf76b56
4
- data.tar.gz: bf45a3cb45e7dda6964b516ff71ad6f09ac02ca3
3
+ metadata.gz: a0e14d27070197af864d0b24a38f9d41cb4115c3
4
+ data.tar.gz: '0984afc951a23e67def08c00be574c3b9b92647d'
5
5
  SHA512:
6
- metadata.gz: b6330b11b5cd1f8fa761db136ef272aa07d0994c1fef3739a8a689d0b28dfd5d363196fdf6ea04b8d7319d863f21c4ee3c875b59409a04b93e825d3abf782fe7
7
- data.tar.gz: c61c3e48987ec0dc6ea4cebdfeb381764e5447ccda48cd6634158611ebb6a18f80a747c92fb748c582cd3344edb6eb87e8c30acf1dffaedb0c07650fa4b59485
6
+ metadata.gz: a8ad0fbe93721f12c413f839d4448cc606e50c0ad001272d35f47f67c57fe54b404472a7164f2abee3dec526d9dbd33c60bc16ea80a2b68fc0b7c486ce1ac43f
7
+ data.tar.gz: bc569b6b09999d14abf10f05c606b738880ffe6f480c520982b052ef3a39124548932e9dfd7901bc92b6f99e6495d6ddf3f87e88a04a97e4f52ec405caeb5b67
data/CHANGELOG CHANGED
@@ -109,5 +109,8 @@
109
109
 
110
110
  =0.9.3
111
111
 
112
- * Fixed frontend log file path issue
112
+ * Added lock file for backend service
113
113
 
114
+ =0.9.4
115
+
116
+ * Fixed issue with unquoted multiline strings
data/Project.yaml CHANGED
@@ -1,5 +1,5 @@
1
1
  name: rtext
2
- version: 0.9.3
2
+ version: 0.9.4
3
3
  git: https://github.com/mthiede/rtext.git
4
4
  summary: Ruby Textual Modelling
5
5
  email: martin dot thiede at gmx de
@@ -8,7 +8,8 @@ description: RText can be used to derive textual languages from an RGen metamode
8
8
  authors: [Martin Thiede]
9
9
  dependencies:
10
10
  http://rubygems.org:
11
- - {name: rgen, version: '~> 0.8.0'}
11
+ - {name: rgen, version: '~> 0.8.0'}
12
+ - {name: filelock, version: '~> 1.1.0'}
12
13
  rdoc_options: [--main, README.rdoc, -x, test]
13
14
  extra_rdoc_files: [README.rdoc, CHANGELOG, MIT-LICENSE, RText_Users_Guide, RText_Protocol]
14
15
  encrypt_sources: false
@@ -39,6 +39,7 @@ def execute_command(obj, options={})
39
39
  obj["invocation_id"] = @invocation_id
40
40
  obj["type"] = "request"
41
41
  @socket.send(serialize_message(obj), 0)
42
+ @logger.debug('Sent request') if @logger
42
43
  result = nil
43
44
  @busy = true
44
45
  @busy_start_time = Time.now
@@ -72,6 +73,7 @@ def execute_command(obj, options={})
72
73
  result
73
74
  end
74
75
  else
76
+ @logger.debug('connecting')
75
77
  :connecting
76
78
  end
77
79
  end
@@ -87,7 +89,7 @@ def stop
87
89
  end
88
90
  if connected?
89
91
  execute_command({"type" => "request", "command" => "stop"})
90
- while do_work
92
+ while do_work
91
93
  sleep(0.1)
92
94
  end
93
95
  end
@@ -184,6 +186,7 @@ def connect
184
186
  if @process_id.nil?
185
187
  File.unlink(@out_file) if File.exist?(@out_file)
186
188
  Dir.chdir(File.dirname(@config.file)) do
189
+ @logger.debug(@config.command.strip + " > #{@out_file} 2>&1") if @logger
187
190
  @process_id = spawn(@config.command.strip + " > #{@out_file} 2>&1")
188
191
  @state = :wait_for_file
189
192
  end
@@ -191,8 +194,9 @@ def connect
191
194
  end
192
195
 
193
196
  def do_work
194
- if @process_id.nil?
197
+ unless @process_id
195
198
  @state = :off
199
+ @logger.debug('No process id') if @logger
196
200
  return false
197
201
  end
198
202
  if @state == :wait_for_port && !File.exist?(@out_file)
@@ -263,6 +267,7 @@ def do_work
263
267
  @logger.info "server socket closed (end of file)" if @logger
264
268
  end
265
269
  if data
270
+ @logger.debug('Got data') if @logger
266
271
  repeat = true
267
272
  response_data.concat(data)
268
273
  while obj = extract_message(response_data)
@@ -277,6 +282,7 @@ def do_work
277
282
  elsif !backend_running? || socket_closed
278
283
  cleanup
279
284
  @state = :off
285
+ @logger.debug("backend_running?: #{backend_running?}, socket_closed: #{socket_closed}") if @logger
280
286
  return false
281
287
  end
282
288
  end
@@ -291,7 +297,8 @@ def cleanup
291
297
  break unless backend_running?
292
298
  sleep(0.1)
293
299
  end
294
- ensure_process_cleanup(@process_id, @keep_outfile ? @out_file : nil, 10)
300
+ ensure_process_cleanup(@process_id, @keep_outfile ? nil : @out_file, 10)
301
+ @process_id = nil
295
302
  end
296
303
 
297
304
  end
@@ -152,7 +152,7 @@ class Serializer
152
152
  result << v.to_s
153
153
  end
154
154
  elsif feature.eType.instanceClass == String
155
- if @lang.unquoted?(feature) && v.to_s =~ /^[a-zA-Z_]\w*$/ && v.to_s != "true" && v.to_s != "false"
155
+ if @lang.unquoted?(feature) && v.to_s =~ /^[a-zA-Z_]\w*$/m && v.to_s != "true" && v.to_s != "false"
156
156
  result << v.to_s
157
157
  else
158
158
  result << "\"#{v.gsub("\\","\\\\\\\\").gsub("\"","\\\"").gsub("\n","\\n").
@@ -166,7 +166,7 @@ class Serializer
166
166
  # formatting not available for BigDecimals
167
167
  else
168
168
  if arg_format
169
- result << sprintf(arg_format, v)
169
+ result << sprintf(arg_format, v)
170
170
  else
171
171
  result << v.to_s
172
172
  end
data/lib/rtext/service.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'socket'
2
+ require 'yaml'
3
+ require 'filelock'
2
4
  require 'rtext/context_builder'
3
5
  require 'rtext/message_helper'
4
6
  require 'rtext/link_detector'
@@ -6,7 +8,7 @@ require 'rtext/link_detector'
6
8
  # optimization: garbage collect while service is idle
7
9
 
8
10
  module RText
9
-
11
+
10
12
  class Service
11
13
  include RText::MessageHelper
12
14
 
@@ -33,62 +35,77 @@ class Service
33
35
  @timeout = options[:timeout] || 60
34
36
  @logger = options[:logger]
35
37
  @on_startup = options[:on_startup]
38
+ @lock_file_path = options[:lock_file_path] || File.expand_path('.rtext.lock')
39
+ @config_file_path = options[:config_file_path] || File.expand_path('.rtext.config')
40
+ @lock_file = nil
36
41
  end
37
42
 
38
43
  def run
39
- server = create_server
40
- puts "RText service, listening on port #{server.addr[1]}"
41
- @on_startup.call if @on_startup
42
- $stdout.flush
43
-
44
- last_access_time = Time.now
45
- last_flush_time = Time.now
46
- @stop_requested = false
47
- sockets = []
48
- request_data = {}
49
- while !@stop_requested
44
+ Filelock @lock_file_path, :timeout => 0, :wait => 1 do
45
+ server = create_server
46
+ puts "RText service, listening on port #{server.addr[1]}"
47
+ @logger.debug('Server started') if @logger
48
+ File.write(@config_file_path, YAML.dump({'port' => server.addr[1], 'pid' => Process.pid}))
50
49
  begin
51
- sock = server.accept_nonblock
52
- sock.sync = true
53
- sockets << sock
54
- @logger.info "accepted connection" if @logger
55
- rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR, Errno::EWOULDBLOCK
56
- rescue Exception => e
57
- @logger.warn "unexpected exception during socket accept: #{e.class}"
58
- end
59
- sockets.dup.each do |sock|
60
- data = nil
61
- begin
62
- data = sock.read_nonblock(100000)
63
- rescue Errno::EWOULDBLOCK
64
- rescue IOError, EOFError, Errno::ECONNRESET, Errno::ECONNABORTED
65
- sock.close
66
- request_data[sock] = nil
67
- sockets.delete(sock)
68
- rescue Exception => e
69
- # catch Exception to make sure we don't crash due to unexpected exceptions
70
- @logger.warn "unexpected exception during socket read: #{e.class}"
71
- sock.close
72
- request_data[sock] = nil
73
- sockets.delete(sock)
74
- end
75
- if data
76
- last_access_time = Time.now
77
- request_data[sock] ||= ""
78
- request_data[sock].concat(data)
79
- while obj = extract_message(request_data[sock])
80
- message_received(sock, obj)
81
- end
82
- end
83
- end
84
- IO.select([server] + sockets, [], [], 1)
85
- if Time.now > last_access_time + @timeout
86
- @logger.info("RText service, stopping now (timeout)") if @logger
87
- break
88
- end
89
- if Time.now > last_flush_time + FlushInterval
50
+ @on_startup.call if @on_startup
90
51
  $stdout.flush
52
+
53
+ last_access_time = Time.now
91
54
  last_flush_time = Time.now
55
+ @stop_requested = false
56
+ sockets = []
57
+ request_data = {}
58
+ while !@stop_requested
59
+ begin
60
+ sock = server.accept_nonblock
61
+ sock.sync = true
62
+ sockets << sock
63
+ @logger.info "accepted connection" if @logger
64
+ rescue Errno::EAGAIN, Errno::ECONNABORTED, Errno::EPROTO, Errno::EINTR, Errno::EWOULDBLOCK
65
+ rescue Exception => e
66
+ @logger.warn "unexpected exception during socket accept: #{e.class}"
67
+ end
68
+ sockets.dup.each do |sock|
69
+ data = nil
70
+ begin
71
+ data = sock.read_nonblock(100000)
72
+ @logger.debug('Got data') if @logger
73
+ rescue Errno::EWOULDBLOCK
74
+ rescue IOError, EOFError, Errno::ECONNRESET, Errno::ECONNABORTED
75
+ sock.close
76
+ request_data[sock] = nil
77
+ sockets.delete(sock)
78
+ rescue Exception => e
79
+ # catch Exception to make sure we don't crash due to unexpected exceptions
80
+ @logger.warn "unexpected exception during socket read: #{e.class}"
81
+ sock.close
82
+ request_data[sock] = nil
83
+ sockets.delete(sock)
84
+ end
85
+ if data
86
+ last_access_time = Time.now
87
+ request_data[sock] ||= ""
88
+ request_data[sock].concat(data)
89
+ @logger.debug("Data available: #{request_data[sock]}") if @logger
90
+ while obj = extract_message(request_data[sock])
91
+ @logger.debug("Got message #{obj.inspect}") if @logger
92
+ message_received(sock, obj)
93
+ end
94
+ end
95
+ end
96
+ IO.select([server] + sockets, [], [], 1)
97
+ if Time.now > last_access_time + @timeout
98
+ @logger.info("RText service, stopping now (timeout)") if @logger
99
+ break
100
+ end
101
+ if Time.now > last_flush_time + FlushInterval
102
+ $stdout.flush
103
+ last_flush_time = Time.now
104
+ end
105
+ end
106
+ ensure
107
+ @logger.warn("Config file doesn't exist, but lock is acquired, it could be a bug") unless File.exist?(@config_file_path)
108
+ File.unlink(@config_file_path) if File.exist?(@config_file_path)
92
109
  end
93
110
  end
94
111
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rtext
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Thiede
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-11-28 00:00:00.000000000 Z
11
+ date: 2021-07-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rgen
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: filelock
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.1.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.1.0
27
41
  description: RText can be used to derive textual languages from an RGen metamodel
28
42
  with very little effort.
29
43
  email:
@@ -84,7 +98,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
84
98
  version: '0'
85
99
  requirements: []
86
100
  rubyforge_project:
87
- rubygems_version: 2.5.2
101
+ rubygems_version: 2.6.14
88
102
  signing_key:
89
103
  specification_version: 4
90
104
  summary: Ruby Textual Modelling