driq 0.1.0 → 0.2.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 928a688785848c1ee8fd6ab30a97dcff67841258534ee7ab5ba693eafceb4435
4
- data.tar.gz: c47f7acca5bb201da01d2d0a6b387970472933921789d8e3cfa5630ffb8d9978
3
+ metadata.gz: beb5ee5b3d3bdf18dc5f0f228868d99aaa915f72b023d0054c38842730773be3
4
+ data.tar.gz: 3d5b872a9d5e94e9ea7ffbb70764b312a484b9f66c3f2e55c9430ca4a80977ba
5
5
  SHA512:
6
- metadata.gz: 3749819f51a541b94e40b67f3722ab68493ac71984a9b68af9403ac9885645472778918bbceae17ec7b33b2c63a05e40d63c60be63fe018172b21d9a628f8ae1
7
- data.tar.gz: b6d3ddd4c45f8f25a971f9e49d024ce8cb30489b57d6c9fb6fd4068c3b7c0cdfc6bcd59690b3a19105d6b71d52b552e56ec120f014b804d1e5ae291c7ddc8c5d
6
+ metadata.gz: 21f8fcdead5170e9ddae226845bde6af3225fce7776cde26463f57eb45fa3c6ac04e278cbf2d82c2854e827ba3873a892a2a47d3614762f49229e70a59b5f0b8
7
+ data.tar.gz: f83aed8ea7c7c7adefa6db38ad976f89f8d08a6e80911fc057adeef3033f5c644701cbd7c052708832359a447e6187303fac6d11c9a2f7b0ff92e10449ff80fd
@@ -1,5 +1,6 @@
1
1
  require "driq/version"
2
2
  require "monitor"
3
+ require "json"
3
4
 
4
5
  class Driq
5
6
  include MonitorMixin
@@ -33,6 +34,10 @@ class Driq
33
34
  end
34
35
  end
35
36
 
37
+ def last_key
38
+ @last
39
+ end
40
+
36
41
  def readpartial(key, size)
37
42
  synchronize do
38
43
  key = @last unless key
@@ -66,3 +71,63 @@ class Driq
66
71
  @list.bsearch_index {|x| x.first > key}
67
72
  end
68
73
  end
74
+
75
+ class Driq
76
+ class EventSource
77
+ def initialize(driq = nil)
78
+ @driq = driq || Driq.new
79
+ end
80
+ attr_reader :driq
81
+
82
+ def write(value)
83
+ @driq.write([nil, value])
84
+ end
85
+
86
+ def first_line(str)
87
+ str.to_s.lines.first.chomp
88
+ end
89
+
90
+ def event(ev, value)
91
+ @driq.write([first_line(ev), value])
92
+ end
93
+
94
+ def ping
95
+ comment
96
+ end
97
+
98
+ def comment(str="ping")
99
+ @driq.write([:ping, first_line(str)])
100
+ end
101
+
102
+ def build_packet(cursor, ev, value)
103
+ case ev
104
+ when :ping
105
+ ": #{value}\n\n"
106
+ when nil
107
+ "id: #{cursor}\ndata: #{value.to_json}\n\n"
108
+ else
109
+ "id: #{cursor}\nevent: #{ev}\ndata: #{value.to_json}\n\n"
110
+ end
111
+ end
112
+
113
+ def read(cursor)
114
+ cursor, value = @driq.read(cursor)
115
+ return cursor, build_packet(cursor, value[0], value[1])
116
+ end
117
+ end
118
+
119
+ class EventStream
120
+ def initialize(src, seek=nil)
121
+ @src = src
122
+ @cursor = Integer(seek) rescue (src.driq.last_key - 1)
123
+ end
124
+
125
+ def pop
126
+ @cursor, buf = @src.read(@cursor)
127
+ buf
128
+ end
129
+
130
+ def close; end
131
+ end
132
+ end
133
+
@@ -1,3 +1,3 @@
1
1
  class Driq
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,90 @@
1
+ require 'webrick'
2
+
3
+ module WEBrick
4
+ class ChunkedStream
5
+ def initialize(stream)
6
+ @data = nil
7
+ @cursor = 0
8
+ @stream = stream
9
+ end
10
+
11
+ def next_chunk
12
+ @stream.pop
13
+ rescue
14
+ raise EOFError
15
+ end
16
+
17
+ def close
18
+ @stream.close
19
+ end
20
+
21
+ def readpartial(size, buf='')
22
+ buf.clear
23
+ unless @data
24
+ @cursor = 0
25
+ @data = next_chunk
26
+ @data.force_encoding("ascii-8bit")
27
+ end
28
+ if @data.bytesize <= size
29
+ buf << @data
30
+ @data = nil
31
+ else
32
+ slice = @data.byteslice(@cursor, size)
33
+ @cursor += slice.bytesize
34
+ buf << slice
35
+ if @data.bytesize <= @cursor
36
+ @data = nil
37
+ end
38
+ end
39
+ buf
40
+ end
41
+ end
42
+ end
43
+
44
+ if __FILE__ == $0
45
+ require 'webrick'
46
+ require 'driq'
47
+ require 'drb'
48
+
49
+ src = Driq::EventSource.new
50
+ svr = WEBrick::HTTPServer.new(:Port => 8086)
51
+ body = <<EOS
52
+ <!DOCTYPE html>
53
+ <html>
54
+ <head>
55
+ <title>SSE</title>
56
+ </head>
57
+ <body>
58
+ <h1>It Works!</h1>
59
+ <ul id="list">
60
+ </ul>
61
+ </body>
62
+ <script>
63
+ var evt = new EventSource('/stream');
64
+ evt.onmessage = function(e) {
65
+ var newElement = document.createElement("li");
66
+ var eventList = document.getElementById('list');
67
+
68
+ newElement.innerHTML = "message: " + e.data;
69
+ eventList.appendChild(newElement);
70
+ };
71
+ </script>
72
+ </html>
73
+ EOS
74
+
75
+ front = {"src" => src, "webrick" => svr, "body" => body}
76
+
77
+ DRb.start_service('druby://localhost:54321', front)
78
+
79
+ svr.mount_proc '/' do |req, res|
80
+ res.body = front['body']
81
+ end
82
+
83
+ svr.mount_proc('/stream') {|req, res|
84
+ last_event_id = req["Last-Event-ID"]
85
+ res.content_type = 'text/event-stream'
86
+ res.chunked = true
87
+ res.body = WEBrick::ChunkedStream.new(Driq::EventStream.new(src, last_event_id))
88
+ }
89
+ svr.start
90
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: driq
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Masatoshi SEKI
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-09-01 00:00:00.000000000 Z
11
+ date: 2020-01-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: test-unit
@@ -80,6 +80,7 @@ files:
80
80
  - driq.gemspec
81
81
  - lib/driq.rb
82
82
  - lib/driq/version.rb
83
+ - lib/driq/webrick.rb
83
84
  homepage: https://github.com/seki/Driq
84
85
  licenses: []
85
86
  metadata: {}
@@ -98,7 +99,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
98
99
  - !ruby/object:Gem::Version
99
100
  version: '0'
100
101
  requirements: []
101
- rubygems_version: 3.0.4
102
+ rubygems_version: 3.1.2
102
103
  signing_key:
103
104
  specification_version: 4
104
105
  summary: simple rd-stream