rtext 0.9.3 → 0.9.4

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
  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