distributor 0.2.0 → 0.3.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.
@@ -1,7 +1,7 @@
1
1
  require "distributor"
2
2
  require "distributor/connector"
3
3
  require "distributor/multiplexer"
4
- require "json"
4
+ require "distributor/okjson"
5
5
  require "thread"
6
6
 
7
7
  class Distributor::Client
@@ -57,13 +57,13 @@ class Distributor::Client
57
57
 
58
58
  def run(command, &handler)
59
59
  id = generate_id
60
- @multiplexer.output 0, JSON.dump({ "id" => id, "command" => "run", "args" => command })
60
+ @multiplexer.output 0, Distributor::OkJson.encode({ "id" => id, "command" => "run", "args" => command })
61
61
  @handlers[id] = handler
62
62
  end
63
63
 
64
64
  def tunnel(port, &handler)
65
65
  id = generate_id
66
- @multiplexer.output 0, JSON.dump({ "id" => id, "command" => "tunnel", "port" => port })
66
+ @multiplexer.output 0, Distributor::OkJson.encode({ "id" => id, "command" => "tunnel", "port" => port })
67
67
  @handlers[id] = handler
68
68
  end
69
69
 
@@ -77,7 +77,7 @@ class Distributor::Client
77
77
  output.write data
78
78
  output.flush
79
79
  rescue EOFError
80
- @multiplexer.output 0, JSON.dump({ "command" => "close", "ch" => ch })
80
+ @multiplexer.output 0, Distributor::OkJson.encode({ "command" => "close", "ch" => ch })
81
81
  end
82
82
  end
83
83
  end
@@ -119,7 +119,7 @@ private
119
119
 
120
120
  def dequeue_json
121
121
  while idx = @json.index("}")
122
- yield JSON.parse(@json[0..idx])
122
+ yield Distributor::OkJson.decode(@json[0..idx])
123
123
  @json = @json[idx+1..-1]
124
124
  end
125
125
  end
@@ -1,4 +1,5 @@
1
1
  require "distributor"
2
+ require "distributor/okjson"
2
3
  require "distributor/packet"
3
4
 
4
5
  class Distributor::Multiplexer
@@ -31,7 +32,7 @@ class Distributor::Multiplexer
31
32
  return if ch.nil?
32
33
  writer(ch).write data
33
34
  rescue IOError
34
- output 0, JSON.dump({ "command" => "close", "ch" => ch })
35
+ output 0, Distributor::OkJson.encode({ "command" => "close", "ch" => ch })
35
36
  end
36
37
 
37
38
  def output(ch, data)
@@ -40,7 +41,7 @@ class Distributor::Multiplexer
40
41
  end
41
42
 
42
43
  def close(ch)
43
- output 0, JSON.dump({ "command" => "close", "ch" => ch })
44
+ output 0, Distributor::OkJson.encode({ "command" => "close", "ch" => ch })
44
45
  rescue IOError
45
46
  end
46
47
 
@@ -0,0 +1,608 @@
1
+ # encoding: UTF-8
2
+ #
3
+ # Copyright 2011, 2012 Keith Rarick
4
+ #
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be included in
13
+ # all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ # THE SOFTWARE.
22
+
23
+ # See https://github.com/kr/okjson for updates.
24
+
25
+ require 'stringio'
26
+
27
+ # Some parts adapted from
28
+ # http://golang.org/src/pkg/json/decode.go and
29
+ # http://golang.org/src/pkg/utf8/utf8.go
30
+ module Distributor
31
+ module OkJson
32
+ extend self
33
+
34
+
35
+ # Decodes a json document in string s and
36
+ # returns the corresponding ruby value.
37
+ # String s must be valid UTF-8. If you have
38
+ # a string in some other encoding, convert
39
+ # it first.
40
+ #
41
+ # String values in the resulting structure
42
+ # will be UTF-8.
43
+ def decode(s)
44
+ ts = lex(s)
45
+ v, ts = textparse(ts)
46
+ if ts.length > 0
47
+ raise Error, 'trailing garbage'
48
+ end
49
+ v
50
+ end
51
+
52
+
53
+ # Parses a "json text" in the sense of RFC 4627.
54
+ # Returns the parsed value and any trailing tokens.
55
+ # Note: this is almost the same as valparse,
56
+ # except that it does not accept atomic values.
57
+ def textparse(ts)
58
+ if ts.length < 0
59
+ raise Error, 'empty'
60
+ end
61
+
62
+ typ, _, val = ts[0]
63
+ case typ
64
+ when '{' then objparse(ts)
65
+ when '[' then arrparse(ts)
66
+ else
67
+ raise Error, "unexpected #{val.inspect}"
68
+ end
69
+ end
70
+
71
+
72
+ # Parses a "value" in the sense of RFC 4627.
73
+ # Returns the parsed value and any trailing tokens.
74
+ def valparse(ts)
75
+ if ts.length < 0
76
+ raise Error, 'empty'
77
+ end
78
+
79
+ typ, _, val = ts[0]
80
+ case typ
81
+ when '{' then objparse(ts)
82
+ when '[' then arrparse(ts)
83
+ when :val,:str then [val, ts[1..-1]]
84
+ else
85
+ raise Error, "unexpected #{val.inspect}"
86
+ end
87
+ end
88
+
89
+
90
+ # Parses an "object" in the sense of RFC 4627.
91
+ # Returns the parsed value and any trailing tokens.
92
+ def objparse(ts)
93
+ ts = eat('{', ts)
94
+ obj = {}
95
+
96
+ if ts[0][0] == '}'
97
+ return obj, ts[1..-1]
98
+ end
99
+
100
+ k, v, ts = pairparse(ts)
101
+ obj[k] = v
102
+
103
+ if ts[0][0] == '}'
104
+ return obj, ts[1..-1]
105
+ end
106
+
107
+ loop do
108
+ ts = eat(',', ts)
109
+
110
+ k, v, ts = pairparse(ts)
111
+ obj[k] = v
112
+
113
+ if ts[0][0] == '}'
114
+ return obj, ts[1..-1]
115
+ end
116
+ end
117
+ end
118
+
119
+
120
+ # Parses a "member" in the sense of RFC 4627.
121
+ # Returns the parsed values and any trailing tokens.
122
+ def pairparse(ts)
123
+ (typ, _, k), ts = ts[0], ts[1..-1]
124
+ if typ != :str
125
+ raise Error, "unexpected #{k.inspect}"
126
+ end
127
+ ts = eat(':', ts)
128
+ v, ts = valparse(ts)
129
+ [k, v, ts]
130
+ end
131
+
132
+
133
+ # Parses an "array" in the sense of RFC 4627.
134
+ # Returns the parsed value and any trailing tokens.
135
+ def arrparse(ts)
136
+ ts = eat('[', ts)
137
+ arr = []
138
+
139
+ if ts[0][0] == ']'
140
+ return arr, ts[1..-1]
141
+ end
142
+
143
+ v, ts = valparse(ts)
144
+ arr << v
145
+
146
+ if ts[0][0] == ']'
147
+ return arr, ts[1..-1]
148
+ end
149
+
150
+ loop do
151
+ ts = eat(',', ts)
152
+
153
+ v, ts = valparse(ts)
154
+ arr << v
155
+
156
+ if ts[0][0] == ']'
157
+ return arr, ts[1..-1]
158
+ end
159
+ end
160
+ end
161
+
162
+
163
+ def eat(typ, ts)
164
+ if ts[0][0] != typ
165
+ raise Error, "expected #{typ} (got #{ts[0].inspect})"
166
+ end
167
+ ts[1..-1]
168
+ end
169
+
170
+
171
+ # Scans s and returns a list of json tokens,
172
+ # excluding white space (as defined in RFC 4627).
173
+ def lex(s)
174
+ ts = []
175
+ while s.length > 0
176
+ typ, lexeme, val = tok(s)
177
+ if typ == nil
178
+ raise Error, "invalid character at #{s[0,10].inspect}"
179
+ end
180
+ if typ != :space
181
+ ts << [typ, lexeme, val]
182
+ end
183
+ s = s[lexeme.length..-1]
184
+ end
185
+ ts
186
+ end
187
+
188
+
189
+ # Scans the first token in s and
190
+ # returns a 3-element list, or nil
191
+ # if s does not begin with a valid token.
192
+ #
193
+ # The first list element is one of
194
+ # '{', '}', ':', ',', '[', ']',
195
+ # :val, :str, and :space.
196
+ #
197
+ # The second element is the lexeme.
198
+ #
199
+ # The third element is the value of the
200
+ # token for :val and :str, otherwise
201
+ # it is the lexeme.
202
+ def tok(s)
203
+ case s[0]
204
+ when ?{ then ['{', s[0,1], s[0,1]]
205
+ when ?} then ['}', s[0,1], s[0,1]]
206
+ when ?: then [':', s[0,1], s[0,1]]
207
+ when ?, then [',', s[0,1], s[0,1]]
208
+ when ?[ then ['[', s[0,1], s[0,1]]
209
+ when ?] then [']', s[0,1], s[0,1]]
210
+ when ?n then nulltok(s)
211
+ when ?t then truetok(s)
212
+ when ?f then falsetok(s)
213
+ when ?" then strtok(s)
214
+ when Spc then [:space, s[0,1], s[0,1]]
215
+ when ?\t then [:space, s[0,1], s[0,1]]
216
+ when ?\n then [:space, s[0,1], s[0,1]]
217
+ when ?\r then [:space, s[0,1], s[0,1]]
218
+ else numtok(s)
219
+ end
220
+ end
221
+
222
+
223
+ def nulltok(s); s[0,4] == 'null' && [:val, 'null', nil] end
224
+ def truetok(s); s[0,4] == 'true' && [:val, 'true', true] end
225
+ def falsetok(s); s[0,5] == 'false' && [:val, 'false', false] end
226
+
227
+
228
+ def numtok(s)
229
+ m = /-?([1-9][0-9]+|[0-9])([.][0-9]+)?([eE][+-]?[0-9]+)?/.match(s)
230
+ if m && m.begin(0) == 0
231
+ if m[3] && !m[2]
232
+ [:val, m[0], Integer(m[1])*(10**Integer(m[3][1..-1]))]
233
+ elsif m[2]
234
+ [:val, m[0], Float(m[0])]
235
+ else
236
+ [:val, m[0], Integer(m[0])]
237
+ end
238
+ end
239
+ end
240
+
241
+
242
+ def strtok(s)
243
+ m = /"([^"\\]|\\["\/\\bfnrt]|\\u[0-9a-fA-F]{4})*"/.match(s)
244
+ if ! m
245
+ raise Error, "invalid string literal at #{abbrev(s)}"
246
+ end
247
+ [:str, m[0], unquote(m[0])]
248
+ end
249
+
250
+
251
+ def abbrev(s)
252
+ t = s[0,10]
253
+ p = t['`']
254
+ t = t[0,p] if p
255
+ t = t + '...' if t.length < s.length
256
+ '`' + t + '`'
257
+ end
258
+
259
+
260
+ # Converts a quoted json string literal q into a UTF-8-encoded string.
261
+ # The rules are different than for Ruby, so we cannot use eval.
262
+ # Unquote will raise an error if q contains control characters.
263
+ def unquote(q)
264
+ q = q[1...-1]
265
+ a = q.dup # allocate a big enough string
266
+ rubydoesenc = false
267
+ # In ruby >= 1.9, a[w] is a codepoint, not a byte.
268
+ if a.class.method_defined?(:force_encoding)
269
+ a.force_encoding('UTF-8')
270
+ rubydoesenc = true
271
+ end
272
+ r, w = 0, 0
273
+ while r < q.length
274
+ c = q[r]
275
+ case true
276
+ when c == ?\\
277
+ r += 1
278
+ if r >= q.length
279
+ raise Error, "string literal ends with a \"\\\": \"#{q}\""
280
+ end
281
+
282
+ case q[r]
283
+ when ?",?\\,?/,?'
284
+ a[w] = q[r]
285
+ r += 1
286
+ w += 1
287
+ when ?b,?f,?n,?r,?t
288
+ a[w] = Unesc[q[r]]
289
+ r += 1
290
+ w += 1
291
+ when ?u
292
+ r += 1
293
+ uchar = begin
294
+ hexdec4(q[r,4])
295
+ rescue RuntimeError => e
296
+ raise Error, "invalid escape sequence \\u#{q[r,4]}: #{e}"
297
+ end
298
+ r += 4
299
+ if surrogate? uchar
300
+ if q.length >= r+6
301
+ uchar1 = hexdec4(q[r+2,4])
302
+ uchar = subst(uchar, uchar1)
303
+ if uchar != Ucharerr
304
+ # A valid pair; consume.
305
+ r += 6
306
+ end
307
+ end
308
+ end
309
+ if rubydoesenc
310
+ a[w] = '' << uchar
311
+ w += 1
312
+ else
313
+ w += ucharenc(a, w, uchar)
314
+ end
315
+ else
316
+ raise Error, "invalid escape char #{q[r]} in \"#{q}\""
317
+ end
318
+ when c == ?", c < Spc
319
+ raise Error, "invalid character in string literal \"#{q}\""
320
+ else
321
+ # Copy anything else byte-for-byte.
322
+ # Valid UTF-8 will remain valid UTF-8.
323
+ # Invalid UTF-8 will remain invalid UTF-8.
324
+ # In ruby >= 1.9, c is a codepoint, not a byte,
325
+ # in which case this is still what we want.
326
+ a[w] = c
327
+ r += 1
328
+ w += 1
329
+ end
330
+ end
331
+ a[0,w]
332
+ end
333
+
334
+
335
+ # Encodes unicode character u as UTF-8
336
+ # bytes in string a at position i.
337
+ # Returns the number of bytes written.
338
+ def ucharenc(a, i, u)
339
+ case true
340
+ when u <= Uchar1max
341
+ a[i] = (u & 0xff).chr
342
+ 1
343
+ when u <= Uchar2max
344
+ a[i+0] = (Utag2 | ((u>>6)&0xff)).chr
345
+ a[i+1] = (Utagx | (u&Umaskx)).chr
346
+ 2
347
+ when u <= Uchar3max
348
+ a[i+0] = (Utag3 | ((u>>12)&0xff)).chr
349
+ a[i+1] = (Utagx | ((u>>6)&Umaskx)).chr
350
+ a[i+2] = (Utagx | (u&Umaskx)).chr
351
+ 3
352
+ else
353
+ a[i+0] = (Utag4 | ((u>>18)&0xff)).chr
354
+ a[i+1] = (Utagx | ((u>>12)&Umaskx)).chr
355
+ a[i+2] = (Utagx | ((u>>6)&Umaskx)).chr
356
+ a[i+3] = (Utagx | (u&Umaskx)).chr
357
+ 4
358
+ end
359
+ end
360
+
361
+
362
+ def hexdec4(s)
363
+ if s.length != 4
364
+ raise Error, 'short'
365
+ end
366
+ (nibble(s[0])<<12) | (nibble(s[1])<<8) | (nibble(s[2])<<4) | nibble(s[3])
367
+ end
368
+
369
+
370
+ def subst(u1, u2)
371
+ if Usurr1 <= u1 && u1 < Usurr2 && Usurr2 <= u2 && u2 < Usurr3
372
+ return ((u1-Usurr1)<<10) | (u2-Usurr2) + Usurrself
373
+ end
374
+ return Ucharerr
375
+ end
376
+
377
+
378
+ def unsubst(u)
379
+ if u < Usurrself || u > Umax || surrogate?(u)
380
+ return Ucharerr, Ucharerr
381
+ end
382
+ u -= Usurrself
383
+ [Usurr1 + ((u>>10)&0x3ff), Usurr2 + (u&0x3ff)]
384
+ end
385
+
386
+
387
+ def surrogate?(u)
388
+ Usurr1 <= u && u < Usurr3
389
+ end
390
+
391
+
392
+ def nibble(c)
393
+ case true
394
+ when ?0 <= c && c <= ?9 then c.ord - ?0.ord
395
+ when ?a <= c && c <= ?z then c.ord - ?a.ord + 10
396
+ when ?A <= c && c <= ?Z then c.ord - ?A.ord + 10
397
+ else
398
+ raise Error, "invalid hex code #{c}"
399
+ end
400
+ end
401
+
402
+
403
+ # Encodes x into a json text. It may contain only
404
+ # Array, Hash, String, Numeric, true, false, nil.
405
+ # (Note, this list excludes Symbol.)
406
+ # X itself must be an Array or a Hash.
407
+ # No other value can be encoded, and an error will
408
+ # be raised if x contains any other value, such as
409
+ # Nan, Infinity, Symbol, and Proc, or if a Hash key
410
+ # is not a String.
411
+ # Strings contained in x must be valid UTF-8.
412
+ def encode(x)
413
+ case x
414
+ when Hash then objenc(x)
415
+ when Array then arrenc(x)
416
+ else
417
+ raise Error, 'root value must be an Array or a Hash'
418
+ end
419
+ end
420
+
421
+
422
+ def valenc(x)
423
+ case x
424
+ when Hash then objenc(x)
425
+ when Array then arrenc(x)
426
+ when String then strenc(x)
427
+ when Numeric then numenc(x)
428
+ when true then "true"
429
+ when false then "false"
430
+ when nil then "null"
431
+ else
432
+ raise Error, "cannot encode #{x.class}: #{x.inspect}"
433
+ end
434
+ end
435
+
436
+
437
+ def objenc(x)
438
+ '{' + x.map{|k,v| keyenc(k) + ':' + valenc(v)}.join(',') + '}'
439
+ end
440
+
441
+
442
+ def arrenc(a)
443
+ '[' + a.map{|x| valenc(x)}.join(',') + ']'
444
+ end
445
+
446
+
447
+ def keyenc(k)
448
+ case k
449
+ when String then strenc(k)
450
+ else
451
+ raise Error, "Hash key is not a string: #{k.inspect}"
452
+ end
453
+ end
454
+
455
+
456
+ def strenc(s)
457
+ t = StringIO.new
458
+ t.putc(?")
459
+ r = 0
460
+
461
+ # In ruby >= 1.9, s[r] is a codepoint, not a byte.
462
+ rubydoesenc = s.class.method_defined?(:encoding)
463
+
464
+ while r < s.length
465
+ case s[r]
466
+ when ?" then t.print('\\"')
467
+ when ?\\ then t.print('\\\\')
468
+ when ?\b then t.print('\\b')
469
+ when ?\f then t.print('\\f')
470
+ when ?\n then t.print('\\n')
471
+ when ?\r then t.print('\\r')
472
+ when ?\t then t.print('\\t')
473
+ else
474
+ c = s[r]
475
+ case true
476
+ when Spc <= c && c <= ?~
477
+ t.putc(c)
478
+ when rubydoesenc
479
+ u = c.ord
480
+ surrenc(t, u)
481
+ else
482
+ u, size = uchardec(s, r)
483
+ r += size - 1 # we add one more at the bottom of the loop
484
+ surrenc(t, u)
485
+ end
486
+ end
487
+ r += 1
488
+ end
489
+ t.putc(?")
490
+ t.string
491
+ end
492
+
493
+
494
+ def surrenc(t, u)
495
+ if u < 0x10000
496
+ t.print('\\u')
497
+ hexenc4(t, u)
498
+ else
499
+ u1, u2 = unsubst(u)
500
+ t.print('\\u')
501
+ hexenc4(t, u1)
502
+ t.print('\\u')
503
+ hexenc4(t, u2)
504
+ end
505
+ end
506
+
507
+
508
+ def hexenc4(t, u)
509
+ t.putc(Hex[(u>>12)&0xf])
510
+ t.putc(Hex[(u>>8)&0xf])
511
+ t.putc(Hex[(u>>4)&0xf])
512
+ t.putc(Hex[u&0xf])
513
+ end
514
+
515
+
516
+ def numenc(x)
517
+ if ((x.nan? || x.infinite?) rescue false)
518
+ raise Error, "Numeric cannot be represented: #{x}"
519
+ end
520
+ "#{x}"
521
+ end
522
+
523
+
524
+ # Decodes unicode character u from UTF-8
525
+ # bytes in string s at position i.
526
+ # Returns u and the number of bytes read.
527
+ def uchardec(s, i)
528
+ n = s.length - i
529
+ return [Ucharerr, 1] if n < 1
530
+
531
+ c0 = s[i].ord
532
+
533
+ # 1-byte, 7-bit sequence?
534
+ if c0 < Utagx
535
+ return [c0, 1]
536
+ end
537
+
538
+ # unexpected continuation byte?
539
+ return [Ucharerr, 1] if c0 < Utag2
540
+
541
+ # need continuation byte
542
+ return [Ucharerr, 1] if n < 2
543
+ c1 = s[i+1].ord
544
+ return [Ucharerr, 1] if c1 < Utagx || Utag2 <= c1
545
+
546
+ # 2-byte, 11-bit sequence?
547
+ if c0 < Utag3
548
+ u = (c0&Umask2)<<6 | (c1&Umaskx)
549
+ return [Ucharerr, 1] if u <= Uchar1max
550
+ return [u, 2]
551
+ end
552
+
553
+ # need second continuation byte
554
+ return [Ucharerr, 1] if n < 3
555
+ c2 = s[i+2].ord
556
+ return [Ucharerr, 1] if c2 < Utagx || Utag2 <= c2
557
+
558
+ # 3-byte, 16-bit sequence?
559
+ if c0 < Utag4
560
+ u = (c0&Umask3)<<12 | (c1&Umaskx)<<6 | (c2&Umaskx)
561
+ return [Ucharerr, 1] if u <= Uchar2max
562
+ return [u, 3]
563
+ end
564
+
565
+ # need third continuation byte
566
+ return [Ucharerr, 1] if n < 4
567
+ c3 = s[i+3].ord
568
+ return [Ucharerr, 1] if c3 < Utagx || Utag2 <= c3
569
+
570
+ # 4-byte, 21-bit sequence?
571
+ if c0 < Utag5
572
+ u = (c0&Umask4)<<18 | (c1&Umaskx)<<12 | (c2&Umaskx)<<6 | (c3&Umaskx)
573
+ return [Ucharerr, 1] if u <= Uchar3max
574
+ return [u, 4]
575
+ end
576
+
577
+ return [Ucharerr, 1]
578
+ end
579
+
580
+
581
+ class Error < ::StandardError
582
+ end
583
+
584
+
585
+ Utagx = 0x80 # 1000 0000
586
+ Utag2 = 0xc0 # 1100 0000
587
+ Utag3 = 0xe0 # 1110 0000
588
+ Utag4 = 0xf0 # 1111 0000
589
+ Utag5 = 0xF8 # 1111 1000
590
+ Umaskx = 0x3f # 0011 1111
591
+ Umask2 = 0x1f # 0001 1111
592
+ Umask3 = 0x0f # 0000 1111
593
+ Umask4 = 0x07 # 0000 0111
594
+ Uchar1max = (1<<7) - 1
595
+ Uchar2max = (1<<11) - 1
596
+ Uchar3max = (1<<16) - 1
597
+ Ucharerr = 0xFFFD # unicode "replacement char"
598
+ Usurrself = 0x10000
599
+ Usurr1 = 0xd800
600
+ Usurr2 = 0xdc00
601
+ Usurr3 = 0xe000
602
+ Umax = 0x10ffff
603
+
604
+ Spc = ' '[0]
605
+ Unesc = {?b=>?\b, ?f=>?\f, ?n=>?\n, ?r=>?\r, ?t=>?\t}
606
+ Hex = '0123456789abcdef'
607
+ end
608
+ end
@@ -1,7 +1,7 @@
1
1
  require "distributor"
2
2
  require "distributor/connector"
3
3
  require "distributor/multiplexer"
4
- require "json"
4
+ require "distributor/okjson"
5
5
  require "pty"
6
6
  require "socket"
7
7
 
@@ -32,12 +32,12 @@ class Distributor::Server
32
32
  when "tunnel" then
33
33
  port = (data["port"] || ENV["PORT"] || 5000).to_i
34
34
  ch = tunnel(port)
35
- @multiplexer.output 0, JSON.dump({ "id" => data["id"], "command" => "ack", "ch" => ch, "port" => port })
35
+ @multiplexer.output 0, Distributor::OkJson.encode({ "id" => data["id"], "command" => "ack", "ch" => ch, "port" => port })
36
36
  when "close" then
37
37
  @multiplexer.close data["ch"]
38
38
  when "run" then
39
39
  ch = run(data["args"])
40
- @multiplexer.output 0, JSON.dump({ "id" => data["id"], "command" => "ack", "ch" => ch })
40
+ @multiplexer.output 0, Distributor::OkJson.encode({ "id" => data["id"], "command" => "ack", "ch" => ch })
41
41
  else
42
42
  raise "no such command: #{command}"
43
43
  end
@@ -93,7 +93,7 @@ class Distributor::Server
93
93
  ch
94
94
  end
95
95
  def start
96
- @multiplexer.output 0, JSON.dump({ "command" => "hello" })
96
+ @multiplexer.output 0, Distributor::OkJson.encode({ "command" => "hello" })
97
97
  loop { @connector.listen }
98
98
  end
99
99
 
@@ -106,7 +106,7 @@ private
106
106
 
107
107
  def dequeue_json
108
108
  while idx = @json.index("}")
109
- yield JSON.parse(@json[0..idx])
109
+ yield Distributor::OkJson.decode(@json[0..idx])
110
110
  @json = @json[idx+1..-1]
111
111
  end
112
112
  end
@@ -1,5 +1,5 @@
1
1
  module Distributor
2
2
 
3
- VERSION = "0.2.0"
3
+ VERSION = "0.3.0"
4
4
 
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: distributor
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-06-15 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
16
- requirement: &70208946341240 !ruby/object:Gem::Requirement
16
+ requirement: &70227170941980 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,7 +21,7 @@ dependencies:
21
21
  version: 0.13.6
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70208946341240
24
+ version_requirements: *70227170941980
25
25
  description: TCP Multiplexer
26
26
  email: ddollar@gmail.com
27
27
  executables: []
@@ -31,6 +31,7 @@ files:
31
31
  - lib/distributor/client.rb
32
32
  - lib/distributor/connector.rb
33
33
  - lib/distributor/multiplexer.rb
34
+ - lib/distributor/okjson.rb
34
35
  - lib/distributor/packet.rb
35
36
  - lib/distributor/server.rb
36
37
  - lib/distributor/version.rb