knjrbfw 0.0.110 → 0.0.111

Sign up to get free protection for your applications and to get access to all the features.
Files changed (38) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +2 -2
  4. data/VERSION +1 -1
  5. data/knjrbfw.gemspec +8 -36
  6. data/lib/knj/autoload.rb +1 -2
  7. data/lib/knj/gtk2_window.rb +7 -7
  8. data/lib/knj/unix_proc.rb +35 -35
  9. metadata +33 -62
  10. data/lib/knj/db.rb +0 -1
  11. data/lib/knj/knjdb/dbtime.rb +0 -35
  12. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql.rb +0 -604
  13. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_columns.rb +0 -155
  14. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_indexes.rb +0 -69
  15. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_sqlspecs.rb +0 -5
  16. data/lib/knj/knjdb/drivers/mysql/knjdb_mysql_tables.rb +0 -443
  17. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3.rb +0 -184
  18. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_columns.rb +0 -177
  19. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_indexes.rb +0 -29
  20. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_sqlspecs.rb +0 -5
  21. data/lib/knj/knjdb/drivers/sqlite3/knjdb_sqlite3_tables.rb +0 -449
  22. data/lib/knj/knjdb/dump.rb +0 -122
  23. data/lib/knj/knjdb/idquery.rb +0 -109
  24. data/lib/knj/knjdb/libknjdb.rb +0 -797
  25. data/lib/knj/knjdb/libknjdb_java_sqlite3.rb +0 -83
  26. data/lib/knj/knjdb/libknjdb_row.rb +0 -153
  27. data/lib/knj/knjdb/libknjdb_sqlite3_ironruby.rb +0 -69
  28. data/lib/knj/knjdb/query_buffer.rb +0 -87
  29. data/lib/knj/knjdb/revision.rb +0 -342
  30. data/lib/knj/knjdb/sqlspecs.rb +0 -5
  31. data/lib/knj/objects.rb +0 -957
  32. data/lib/knj/process.rb +0 -480
  33. data/lib/knj/process_meta.rb +0 -569
  34. data/spec/db_spec.rb +0 -282
  35. data/spec/db_spec_encoding_test_file.txt +0 -1
  36. data/spec/objects_spec.rb +0 -394
  37. data/spec/process_meta_spec.rb +0 -172
  38. data/spec/process_spec.rb +0 -115
@@ -1,480 +0,0 @@
1
- require "#{$knjpath}errors"
2
- require "#{$knjpath}thread"
3
- require "tsafe"
4
-
5
- #This class is able to control communicate with another Ruby-process also running Knj::Process.
6
- class Knj::Process
7
- attr_reader :blocks, :blocks_send
8
-
9
- #Constructor. Sets in, out and various other needed variables.
10
- def initialize(args = {})
11
- @args = args
12
- @in = @args[:in]
13
- @out = @args[:out]
14
- @on_rec = @args[:on_rec]
15
- @in_count = 0
16
- @out_count = 0
17
- @out_answers = {}
18
- @out_mutex = Mutex.new
19
- @debug = @args[:debug]
20
- @args[:sleep_answer] = 0.001 if !@args.key?(:sleep_answer)
21
- @thread_error = nil
22
-
23
- #Used when this process is trying to receive block-results from the subprocess.
24
- @blocks = {}
25
-
26
- #Used when the other process is trying to receive block-results from this object.
27
- @blocks_send = {}
28
-
29
- #Else the sockets might hang when waiting for results and stuff like that... - knj.
30
- @in.sync = true
31
- @out.sync = true
32
-
33
- if @args[:err]
34
- @err_thread = Knj::Thread.new do
35
- @args[:err].each_line do |str|
36
- if @args[:on_err]
37
- @args[:on_err].call(str)
38
- else
39
- $stderr.print "Process error: #{str}"
40
- end
41
-
42
- #Try to break out of loop - the process has been destroyed.
43
- break if (!@out_mutex and str.to_s.strip.length <= 0) or (@args and @args[:err] and @args[:err].closed?)
44
- end
45
- end
46
- end
47
-
48
- if @args[:listen]
49
- require "#{$knjpath}/thread"
50
- @listen_thread = Knj::Thread.new do
51
- begin
52
- self.listen
53
- rescue => e
54
- $stderr.print "#{Knj::Errors.error_str(e)}\n\n" if @debug
55
- @thread_error = e
56
- end
57
- end
58
- end
59
- end
60
-
61
- #Kills the listen-thread.
62
- def kill_listen
63
- @listen_thread.kill if @listen_thread
64
- end
65
-
66
- #Joins the listen-thread and the error-thread.
67
- def join
68
- @listen_thread.join if @listen_thread
69
- sleep 0.5
70
- raise @thread_error if @thread_error
71
- end
72
-
73
- #Listens for a new incoming object.
74
- def listen
75
- loop do
76
- self.listen_loop
77
-
78
- #Break out if something is wrong.
79
- break if !@out_mutex or (@in and @in.closed?) or (@out and @out.closed?)
80
- end
81
- end
82
-
83
- #This method is called by listen on every loop.
84
- def listen_loop
85
- $stderr.print "listen-loop called.\n" if @debug
86
-
87
- str = @in.gets("\n")
88
- if str == nil
89
- raise "Socket closed." if @in.closed?
90
- sleep 0.1
91
- return nil
92
- end
93
-
94
-
95
- data = str.strip.split(":")
96
- raise "Expected length of 2 or 3 but got: '#{data.length}'.\n#{data}" if data.length != 2 and data.length != 3
97
-
98
- raise "Invalid ID: '#{data[1]}'." if data[1].to_s.strip.length <= 0
99
- id = data[1].to_i
100
-
101
- raise "Invalid length: '#{data[2]}' (#{str.to_s.strip})." if data[2].to_s.strip.length <= 0
102
- length = data[2].to_i
103
-
104
- $stderr.print "Received ID #{id}.\n" if @debug
105
- res = @in.read(length)
106
-
107
- begin
108
- obj = Marshal.load(res)
109
- $stderr.print "Got content for '#{id}' (#{data[0]}).\n" if @debug
110
-
111
- case data[0]
112
- when "answer"
113
- #raise "Already have answer for '#{id}'." if @out_answers.key?(id)
114
- @out_answers[id] = obj
115
- when "answer_block"
116
- @blocks[id][:mutex].synchronize do
117
- @blocks[id][:results] += obj
118
- end
119
- when "answer_block_end"
120
- $stderr.print "Answer-block-end received!\n" if @debug
121
- @blocks[id][:block_result] = obj
122
- @blocks[id][:finished] = true
123
- when "send"
124
- Knj::Thread.new do
125
- result_obj = Knj::Process::Resultobject.new(:process => self, :id => id, :obj => obj)
126
-
127
- begin
128
- @on_rec.call(result_obj)
129
- rescue SystemExit, Interrupt => e
130
- raise e
131
- rescue Exception => e
132
- #Error was raised - try to forward it to the server.
133
- result_obj.answer("type" => "process_error", "class" => e.class.name, "msg" => e.message, "backtrace" => e.backtrace)
134
- end
135
- end
136
- when "send_block"
137
- result_obj = Knj::Process::Resultobject.new(:process => self, :id => id, :obj => obj)
138
- @blocks_send[id] = {:result_obj => result_obj, :waiting_for_result => false}
139
-
140
- @blocks_send[id][:enum] = Enumerator.new do |y|
141
- @on_rec.call(result_obj) do |answer_block|
142
- $stderr.print "Running enum-block for #{answer_block}\n" if @debug
143
-
144
- #Block has ended on hosts side - break out of block-loop.
145
- break if !@blocks_send.key?(id)
146
-
147
- #Throw the result at the block running.
148
- y << answer_block
149
-
150
- #This is to prevent the block-loop from running again, until host has confirmed it wants another result.
151
- dobreak = false
152
-
153
- loop do
154
- #Block has ended on hosts-side - break of out block-loop.
155
- if !@blocks_send.key?(id)
156
- dobreak = true
157
- break
158
- end
159
-
160
- #If waiting for result then release the loop and return another result.
161
- if @blocks_send[id][:waiting_for_result]
162
- @blocks_send[id][:waiting_for_result] = false
163
- break
164
- end
165
-
166
- #Wait a little with checking for another result to not use 100% CPU.
167
- sleep 0.01
168
- end
169
-
170
- #The block-loop should not run again - it has been prematurely interrupted on the host-side.
171
- break if dobreak
172
- end
173
- end
174
- when "send_block_res"
175
- begin
176
- #The host wants another result. Set the 'waiting-for-result' and wait for the enumerator to run. Then return result from enumerator (code is right above here).
177
- @blocks_send[obj][:waiting_for_result] = true
178
- res = @blocks_send[obj][:enum].next
179
- self.answer(id, {"result" => res})
180
- rescue StopIteration
181
- self.answer(id, "StopIteration")
182
- end
183
- when "send_block_end"
184
- if @blocks_send.key?(obj)
185
- enum = @blocks_send[obj][:enum]
186
- @blocks_send.delete(obj)
187
-
188
- begin
189
- enum.next if enum #this has to be called to stop Enumerator from blocking...
190
- rescue StopIteration
191
- #do nothing.
192
- end
193
- end
194
-
195
- self.answer(id, "ok")
196
- when "send_block_buffer"
197
- Knj::Thread.new do
198
- result_obj = Knj::Process::Resultobject.new(:process => self, :id => id, :obj => obj)
199
- block_res = nil
200
- buffer_done = false
201
-
202
- begin
203
- buffer_answers = Tsafe.std_array #JRuby needs the threadsafety.
204
- buffer_thread = Knj::Thread.new do
205
- loop do
206
- arr = buffer_answers.shift(200)
207
-
208
- if !arr.empty?
209
- $stderr.print "Sending: #{arr.length} results.\n" if @debug
210
- self.answer(id, arr, "answer_block")
211
- else
212
- $stderr.print "Waiting for buffer-stuff (#{arr.length}, #{buffer_done}).\n" if @debug
213
- sleep 0.05
214
- end
215
-
216
- break if buffer_done and buffer_answers.empty?
217
- end
218
- end
219
-
220
- begin
221
- begin
222
- count = 0
223
- block_res = @on_rec.call(result_obj) do |answer_block|
224
- loop do
225
- if buffer_answers.length > 1000
226
- $stderr.print "Buffer is more than 1000 - sleeping and tries again in 0.05 sec.\n" if @debug
227
- sleep 0.05
228
- else
229
- break
230
- end
231
- end
232
-
233
- count += 1
234
- buffer_answers << answer_block
235
-
236
- if count >= 100
237
- count = 0
238
-
239
- loop do
240
- answer = self.send("obj" => id, "type" => "send_block_count")
241
- $stderr.print "Answer was: #{answer}\n" if @debug
242
-
243
- if answer >= 100
244
- $stderr.print "More than 100 results are buffered on the other side - wait for them to be handeled before sending more.\n" if @debug
245
- sleep 0.05
246
- else
247
- $stderr.print "Less than 100 results in buffer - send more.\n" if @debug
248
- break
249
- end
250
- end
251
- end
252
- end
253
- ensure
254
- buffer_done = true
255
- end
256
- ensure
257
- buffer_thread.join
258
- end
259
- rescue => e
260
- $stderr.print Knj::Errors.error_str(e) if @debug
261
- #Error was raised - try to forward it to the server.
262
- result_obj.answer("type" => "process_error", "class" => e.class.name, "msg" => e.message, "backtrace" => e.backtrace)
263
- ensure
264
- $stderr.print "Answering with block-end.\n" if @debug
265
- self.answer(id, block_res, "answer_block_end")
266
- end
267
- end
268
- when "send_block_count"
269
- if @blocks.key?(obj)
270
- count = @blocks[obj][:results].length
271
- else
272
- count = 0
273
- end
274
-
275
- self.answer(id, count)
276
- else
277
- $stderr.print "Unknown command: '#{data[0]}'."
278
- raise "Unknown command: '#{data[0]}'."
279
- end
280
- rescue => e
281
- $stderr.print Knj::Errors.error_str(e) if @debug
282
- #Error was raised - try to forward it to the server.
283
- result_obj = Knj::Process::Resultobject.new(:process => self, :id => id, :obj => obj)
284
- result_obj.answer("type" => "process_error", "class" => e.class.name, "msg" => e.message, "backtrace" => e.backtrace)
285
- end
286
- end
287
-
288
- #Answers a send.
289
- def answer(id, obj, type = "answer")
290
- $stderr.print "Answering #{id} (#{obj}).\n" if @debug
291
- str = Marshal.dump(obj)
292
-
293
- @out_mutex.synchronize do
294
- @out.write("#{type}:#{id}:#{str.length}\n#{str}")
295
- end
296
- end
297
-
298
- #Sends a command to the client.
299
- def send(args, &block)
300
- args = {"obj" => args} if !args.is_a?(Hash)
301
-
302
- my_id = nil
303
- raise "No 'obj' was given." if !args["obj"]
304
- str = Marshal.dump(args["obj"])
305
-
306
- if args.key?("type")
307
- type = args["type"]
308
- else
309
- type = "send"
310
- end
311
-
312
- raise "Invalid type: '#{type}'." if type.to_s.strip.length <= 0
313
- args["wait_for_answer"] = true if !args.key?("wait_for_answer")
314
-
315
- @out_mutex.synchronize do
316
- my_id = @out_count
317
- @out_count += 1
318
-
319
- if block
320
- if type == "send"
321
- if args["buffer_use"]
322
- type = "send_block_buffer"
323
- @blocks[my_id] = {:block => block, :results => [], :finished => false, :buffer => args["buffer_use"], :mutex => Mutex.new}
324
- else
325
- type = "send_block"
326
- end
327
- end
328
- end
329
-
330
- $stderr.print "Writing #{type}:#{my_id}:#{args["obj"]} to socket.\n" if @debug
331
- @out.write("#{type}:#{my_id}:#{str.length}\n#{str}")
332
- end
333
-
334
- #If block is broken it might never give us control to return anything - thats why we use ensure.
335
- begin
336
- if type == "send_block"
337
- loop do
338
- res = self.send("obj" => my_id, "type" => "send_block_res")
339
-
340
- if res == "StopIteration"
341
- break
342
- elsif res.is_a?(Hash) and res.key?("result")
343
- #do nothing.
344
- else
345
- raise "Unknown result: '#{res}'."
346
- end
347
-
348
- block.call(res["result"])
349
- end
350
- end
351
- ensure
352
- #Tell the subprocess we are done with the block (if break, exceptions or anything else like that was used).
353
- if type == "send_block"
354
- res = self.send("obj" => my_id, "type" => "send_block_end")
355
- raise "Unknown result: '#{res}'." if res != "ok"
356
- end
357
-
358
- if args["wait_for_answer"]
359
- #Make very, very short sleep, if the result is almost instant this will heavily optimize the speed, because :sleep_answer-argument wont be used.
360
- sleep 0.00001
361
- return self.read_answer(my_id)
362
- end
363
-
364
- return {:id => my_id}
365
- end
366
- end
367
-
368
- #Returns true if an answer with a certain ID has arrived.
369
- def has_answer?(id)
370
- return @out_answers.key?(id)
371
- end
372
-
373
- #This is used to call the block with results and remove the results from the array.
374
- def exec_block_results(id)
375
- return nil if @blocks[id][:results].empty?
376
-
377
- removes = []
378
- @blocks[id][:mutex].synchronize do
379
- results = @blocks[id][:results]
380
- @blocks[id][:results] = []
381
-
382
- results.each do |res|
383
- removes << res
384
- @blocks[id][:block].call(res)
385
- end
386
- end
387
- end
388
-
389
- #Waits for data with a certain ID and returns it when it exists.
390
- def read_answer(id)
391
- $stderr.print "Reading answer (#{id}).\n" if @debug
392
- block_res = @blocks[id]
393
- $stderr.print "Answer is block for #{id} #{block_res}\n" if @debug and block_res
394
-
395
- loop do
396
- raise "Process destroyed." if !@out_answers
397
-
398
- if block_res
399
- self.exec_block_results(id)
400
- break if block_res and block_res[:finished]
401
- else
402
- break if @out_answers.key?(id)
403
- end
404
-
405
- sleep @args[:sleep_answer]
406
- end
407
-
408
- if block_res
409
- self.exec_block_results(id)
410
- @blocks.delete(id)
411
- end
412
-
413
- ret = @out_answers[id]
414
- @out_answers.delete(id)
415
-
416
- if ret.is_a?(Hash) and ret["type"] == "process_error"
417
- $stderr.print "Process-error - begin generating error...\n" if @debug
418
- err = RuntimeError.new(ret["msg"])
419
- bt = []
420
- ret["backtrace"].each do |subproc_bt|
421
- bt << "Subprocess: #{subproc_bt}"
422
- end
423
-
424
- caller.each do |proc_bt|
425
- bt << proc_bt
426
- end
427
-
428
- err.set_backtrace(bt)
429
-
430
- $stderr.print Knj::Errors.error_str(err) if @debug
431
- raise err
432
- end
433
-
434
- $stderr.print "Returning answer (#{id}).\n" if @debug
435
- return ret
436
- end
437
-
438
- #Closes everything down...
439
- def destroy
440
- self.kill_listen
441
- @err_thread.kill if @err_thread
442
- @out_answers = nil
443
- @out_mutex = nil
444
- end
445
- end
446
-
447
- class Knj::Process::Resultobject
448
- attr_reader :args
449
-
450
- def initialize(args)
451
- @args = args
452
- @answered = false
453
- end
454
-
455
- #The object that was passed to the current process/socket.
456
- def obj
457
- return @args[:obj]
458
- end
459
-
460
- #Returns the process that spawned this resultobject.
461
- def process
462
- return @args[:process]
463
- end
464
-
465
- #Returns the ID this result-object should answer to.
466
- def id
467
- return @args[:id]
468
- end
469
-
470
- #Answers the call with the given object.
471
- def answer(obj)
472
- @answered = true
473
- @args[:process].answer(@args[:id], obj)
474
- end
475
-
476
- #Returns true if this result has been answered.
477
- def answered?
478
- return @answered
479
- end
480
- end