flok 0.0.72 → 0.0.73

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: d06f92c68324984f4e293390562ef487283971fd
4
- data.tar.gz: 40c7e7f381e3a6630c1bac4935ce0c660adb183b
3
+ metadata.gz: 6c9f17f929ac1f53925b9f3a7f1d8eb69db61d3f
4
+ data.tar.gz: c156cf2897629e2d04a2a368eb3d0685ed3ceb29
5
5
  SHA512:
6
- metadata.gz: a15900ee9f4ef22c576c48ab195f1669495450e211ec2b2c8791cc845fca3208e30513b08cb8878064ef75eaca787f34c6c8c621040b2824c65a494ce8da663e
7
- data.tar.gz: 45edc71adc819e2d0b994e7ee746aa6d4da654b57fbcd5e5bbcdbd49cd3731303342a885a5df5781aa91473878089b8f43b4d65a8a02fc9f4591585ca65a3e97
6
+ metadata.gz: 11bdbc991e2c88768af5b24e0c23471029f9f797ba139b3eabf84367d16fa9cc6c3ae185c2c3eaae870afca42244cd3a63687bb1a7acdc95ac31ab771cb96104
7
+ data.tar.gz: 876fb2e35de2c656e9f53e9d503ee9f44d7ee4cfc091c848d4e4101be853b2afcef22b4c4a55ef7067ca542908b51d5e47ada3b29083bc3b1ac298cbac92f0de
@@ -1,5 +1,31 @@
1
1
  //Configure pg_sockio
2
2
  <% [0].each do |i| %>
3
+ //Destination for events sent from the sockio driver
4
+ function __pg_sockio<%= i %>_xevent_handler(ep, ename, einfo) {
5
+ if (ename === "update") {
6
+ //If changes_id was given
7
+ if (einfo.changes_id !== undefined) {
8
+ vm_mark_changes_synced(vm_cache[pg_sockio<%= i %>_ns][einfo.page._id], einfo.changes_id)
9
+ }
10
+
11
+ //If page exists, then we need to rebase the page, this will actually
12
+ //modify einfo.page. If the cached entry has no changes, then nothing
13
+ //is done.
14
+ if (vm_cache[pg_sockio<%= i %>_ns][einfo.page._id] !== undefined) {
15
+ vm_rebase(vm_cache[pg_sockio<%= i %>_ns][einfo.page._id], einfo.page);
16
+ }
17
+
18
+ //Write out page
19
+ vm_transaction_begin();
20
+ vm_cache_write(pg_sockio<%= i %>_ns, einfo.page);
21
+ vm_transaction_end();
22
+ } else {
23
+ <% if @debug %>
24
+ throw "pg_sockio<%= i %>_xevent_handler received an event called: " + ename + "that it does not know how to handle. This event should never have even been forwarded, but you may have missed adding the handler code if you did request a forward"
25
+ <% end %>
26
+ }
27
+ }
28
+
3
29
  function pg_sockio<%= i %>_init(ns, options) {
4
30
  pg_sockio<%= i %>_ns = ns;
5
31
 
@@ -11,22 +37,9 @@
11
37
  pg_sockio<%= i %>_spec_did_init = true;
12
38
  <% end %>
13
39
 
14
- //Destination for events sent from the sockio driver
15
- function pg_sockio<%= i %>_xevent_handler(ep, ename, einfo) {
16
- if (ename === "update") {
17
- vm_transaction_begin();
18
- vm_cache_write(pg_sockio<%= i %>_ns, einfo.page);
19
- vm_transaction_end();
20
- } else {
21
- <% if @debug %>
22
- throw "pg_sockio<%= i %>_xevent_handler received an event called: " + ename + "that it does not know how to handle. This event should never have even been forwarded, but you may have missed adding the handler code if you did request a forward"
23
- <% end %>
24
- }
25
- }
26
-
27
40
  //Register the base address for the socket and the destination for events
28
41
  pg_sockio<%= i %>_bp = tels(1);
29
- reg_evt(pg_sockio<%= i %>_bp, pg_sockio<%= i %>_xevent_handler);
42
+ reg_evt(pg_sockio<%= i %>_bp, __pg_sockio<%= i %>_xevent_handler);
30
43
 
31
44
  SEND("main", "if_sockio_init", options.url, pg_sockio<%= i %>_bp);
32
45
 
@@ -80,6 +80,7 @@ This pager connects to a socket.io server via the `sockio` module.
80
80
  * writes directly to `vm_cache` and notifies the server of the creation via `/create` with `page:`
81
81
  * **Socket.IO Event Handlers **
82
82
  * `update` - A page has been updated. This may either indicate an update or write. The page will be integrated into `vm_cache` via a rebased if it
83
- already exists or a direct write if it dosen't already exist. Contains one field `page:` that contains the page.
83
+ already exists or a direct write if it dosen't already exist. Contains one field `page:` that contains the page and a possible `changes_id`
84
+ if the update is in response to some pages commited to the page.
84
85
  * **Spec**
85
86
  * If `@debug`, then `sockio{N}_spec_did_init` will be true
data/lib/flok/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Flok
2
- VERSION = "0.0.72"
2
+ VERSION = "0.0.73"
3
3
  end
@@ -0,0 +1,22 @@
1
+ controller :my_controller do
2
+ services :vm
3
+
4
+ on_entry %{
5
+ read_res_params = [];
6
+ }
7
+
8
+ action :my_action do
9
+ on_entry %{
10
+ var watch_info = {
11
+ ns: "sockio",
12
+ id: "test",
13
+ };
14
+
15
+ Request("vm", "watch", watch_info);
16
+ }
17
+
18
+ on "read_res", %{
19
+ read_res_params.push(JSON.parse(JSON.stringify(params)));
20
+ }
21
+ end
22
+ end
@@ -77,7 +77,344 @@ RSpec.describe "kern:sockio_pager" do
77
77
  }], 1
78
78
  end
79
79
 
80
- it "Does write a page to vm_cache that dosen't already exist when the page receives an 'update' response from the external socket.io" do
80
+ it "Does write a page to vm_cache that **does** already exist as <unbased, nochanges> the page receives an 'update' response from the external socket.io without a changes id" do
81
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/watch2.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
82
+ dump = ctx.evald %{
83
+ //Call embed on main root view
84
+ dump.base = _embed("my_controller", 0, {}, null);
85
+
86
+ //Drain queue
87
+ int_dispatch([]);
88
+
89
+ //pg_sockio0 socket address & the endpoint for the event callback
90
+ dump.pg_sockio0_bp = pg_sockio0_bp;
91
+ }
92
+
93
+ #sockio driver should have been signaled (which it should respond asynchronously, and presumabely, after the disk)
94
+ @driver.ignore_up_to "if_sockio_send"
95
+ @driver.mexpect "if_sockio_send", [Integer, "watch", {
96
+ "page_id" => "test"
97
+ }], 1
98
+
99
+ #The disk should have been signaled
100
+ @driver.ignore_up_to "if_per_get"
101
+ @driver.mexpect "if_per_get", ["vm", "sockio", "test"], 2
102
+
103
+
104
+ #The disk should respond with a page
105
+ @driver.int "int_per_get_res", ["vm", "sockio", "test", {
106
+ "_id" => "test",
107
+ "_next" => nil,
108
+ "_head" => nil,
109
+ "entries" => [
110
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
111
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
112
+ ]
113
+ }]
114
+
115
+ #We (driver sockio) received a watch request for a page with the id 'test'
116
+ #Now we are imagining that the socket.io driver received back some
117
+ #data and is now signaling to the kernel that data is available (as it sends to an
118
+ #event endpoint equal to the socket bp)
119
+ @driver.int "int_event", [dump["pg_sockio0_bp"], "update", {page: {
120
+ _id: "test",
121
+ _next: nil,
122
+ _head: nil,
123
+ entries: [
124
+ {"_id" => "foo3", "_sig" => "foo3", "value" => "bar3"}
125
+ ],
126
+ }}]
127
+
128
+ post_read_res_dump = ctx.evald %{
129
+ for (var i = 0; i < 100; ++i) {
130
+ //Drain queue (vm_cache_write defers to controller)
131
+ int_dispatch([]);
132
+ }
133
+
134
+ dump.read_res_params = read_res_params;
135
+ }
136
+
137
+ #The controller should have received a notification that a page was updated twice, one
138
+ #for the disk response and one for the pager response
139
+ expect(post_read_res_dump["read_res_params"].length).to eq(2)
140
+ expect(post_read_res_dump["read_res_params"][0]["entries"]).to eq([
141
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
142
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
143
+ ])
144
+ expect(post_read_res_dump["read_res_params"][1]["entries"]).to eq([
145
+ {"_id" => "foo3", "_sig" => "foo3", "value" => "bar3"}
146
+ ])
147
+ end
148
+
149
+ it "Does write a page to vm_cache that **does** already exist as <unbased, changes> receives an 'update' response from the external socket.io without a changes_id" do
150
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/watch2.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
151
+ dump = ctx.evald %{
152
+ //Call embed on main root view
153
+ dump.base = _embed("my_controller", 0, {}, null);
154
+
155
+ //Drain queue
156
+ int_dispatch([]);
157
+
158
+ //pg_sockio0 socket address & the endpoint for the event callback
159
+ dump.pg_sockio0_bp = pg_sockio0_bp;
160
+ }
161
+
162
+ #sockio driver should have been signaled (which it should respond asynchronously, and presumabely, after the disk)
163
+ @driver.ignore_up_to "if_sockio_send"
164
+ @driver.mexpect "if_sockio_send", [Integer, "watch", {
165
+ "page_id" => "test"
166
+ }], 1
167
+
168
+ #The disk should have been signaled
169
+ @driver.ignore_up_to "if_per_get"
170
+ @driver.mexpect "if_per_get", ["vm", "sockio", "test"], 2
171
+
172
+
173
+ #The disk should respond with a page that contains changes
174
+ @driver.int "int_per_get_res", ["vm", "sockio", "test", {
175
+ "_id" => "test",
176
+ "_next" => nil,
177
+ "_head" => nil,
178
+ "entries" => [
179
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
180
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
181
+ ],
182
+ "__changes" => [
183
+ ["+", 0, {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"}],
184
+ ["+", 1, {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}],
185
+ ["-", "foo3"],
186
+ ],
187
+ "__changes_id" => "foo"
188
+ }]
189
+
190
+ #We (driver sockio) received a watch request for a page with the id 'test'
191
+ #Now we are imagining that the socket.io driver received back some
192
+ #data and is now signaling to the kernel that data is available (as it sends to an
193
+ #event endpoint equal to the socket bp)
194
+ @driver.int "int_event", [dump["pg_sockio0_bp"], "update", {page: {
195
+ _id: "test",
196
+ _next: nil,
197
+ _head: nil,
198
+ entries: [
199
+ {"_id" => "foo3", "_sig" => "foo3", "value" => "bar3"},
200
+ {"_id" => "foo4", "_sig" => "foo4", "value" => "bar4"}
201
+ ],
202
+ }}]
203
+
204
+ post_read_res_dump = ctx.evald %{
205
+ for (var i = 0; i < 100; ++i) {
206
+ //Drain queue (vm_cache_write defers to controller)
207
+ int_dispatch([]);
208
+ }
209
+
210
+ dump.read_res_params = read_res_params;
211
+ }
212
+
213
+ #The controller should have received a notification that a page was updated twice, one
214
+ #for the disk response and one for the pager response
215
+ expect(post_read_res_dump["read_res_params"].length).to eq(2)
216
+ expect(post_read_res_dump["read_res_params"][0]["entries"]).to eq([
217
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
218
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
219
+ ])
220
+
221
+ #Next page should be rebased ontop of the incomming page, such that changes are played *over* it
222
+ #which includes deletion of foo3
223
+ expect(post_read_res_dump["read_res_params"][1]["entries"]).to eq([
224
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
225
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"},
226
+ {"_id" => "foo4", "_sig" => "foo4", "value" => "bar4"},
227
+ ])
228
+ end
229
+
230
+ it "Does write a page to vm_cache that **does** already exist as <based<unbased, changes>, changes> receives an 'update' response from the external socket.io without a changes_id" do
231
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/watch2.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
232
+ dump = ctx.evald %{
233
+ //Call embed on main root view
234
+ dump.base = _embed("my_controller", 0, {}, null);
235
+
236
+ //Drain queue
237
+ int_dispatch([]);
238
+
239
+ //pg_sockio0 socket address & the endpoint for the event callback
240
+ dump.pg_sockio0_bp = pg_sockio0_bp;
241
+ }
242
+
243
+ #sockio driver should have been signaled (which it should respond asynchronously, and presumabely, after the disk)
244
+ @driver.ignore_up_to "if_sockio_send"
245
+ @driver.mexpect "if_sockio_send", [Integer, "watch", {
246
+ "page_id" => "test"
247
+ }], 1
248
+
249
+ #The disk should have been signaled
250
+ @driver.ignore_up_to "if_per_get"
251
+ @driver.mexpect "if_per_get", ["vm", "sockio", "test"], 2
252
+
253
+
254
+ #The disk should respond with a page that contains <based<nobase, changes>, changes>
255
+ @driver.int "int_per_get_res", ["vm", "sockio", "test", {
256
+ "_id" => "test",
257
+ "_next" => nil,
258
+ "_head" => nil,
259
+ "entries" => [
260
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
261
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
262
+ ],
263
+ "__changes" => [
264
+ ["+", 0, {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"}],
265
+ ["+", 1, {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}],
266
+ ["-", "foo3"],
267
+ ],
268
+ "__changes_id" => "foo",
269
+ "__base" => {
270
+ "_id" => "test",
271
+ "_next" => nil,
272
+ "_head" => nil,
273
+ "entries" => [
274
+ {"_id" => "fooX", "_sig" => "fooX", "value" => "barX"},
275
+ {"_id" => "foo3", "_sig" => "foo3", "value" => "bar3"}
276
+ ],
277
+ "__changes_id" => "foo2",
278
+ "__changes" => [
279
+ ["-", "fooX"],
280
+ ["+", 1, {"_id" => "foo3", "_sig" => "foo3", "value" => "bar3"}]
281
+ ]
282
+ }
283
+ }]
284
+
285
+ #We (driver sockio) received a watch request for a page with the id 'test'
286
+ #Now we are imagining that the socket.io driver received back some
287
+ #data and is now signaling to the kernel that data is available (as it sends to an
288
+ #event endpoint equal to the socket bp)
289
+ @driver.int "int_event", [dump["pg_sockio0_bp"], "update", {page: {
290
+ _id: "test",
291
+ _next: nil,
292
+ _head: nil,
293
+ entries: [
294
+ {"_id" => "foo4", "_sig" => "foo4", "value" => "bar4"},
295
+ {"_id" => "foo5", "_sig" => "foo5", "value" => "bar5"},
296
+ {"_id" => "fooX", "_sig" => "fooX", "value" => "barX"},
297
+ ],
298
+ }}]
299
+
300
+ post_read_res_dump = ctx.evald %{
301
+ for (var i = 0; i < 100; ++i) {
302
+ //Drain queue (vm_cache_write defers to controller)
303
+ int_dispatch([]);
304
+ }
305
+
306
+ dump.read_res_params = read_res_params;
307
+ }
308
+
309
+ #The controller should have received a notification that a page was updated twice, one
310
+ #for the disk response and one for the pager response
311
+ expect(post_read_res_dump["read_res_params"].length).to eq(2)
312
+ expect(post_read_res_dump["read_res_params"][0]["entries"]).to eq([
313
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
314
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
315
+ ])
316
+
317
+ #Next version is a double replay. First, the server page is called the new 'base', then changes from the
318
+ #old base are played ontop of the server page. Then the top-level changes are recalculated based on this new page,
319
+ #and then replayed on the server's page *again* (a linked copy where the first replayed sits at __base.
320
+ expect(post_read_res_dump["read_res_params"][1]["entries"]).to eq([
321
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
322
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"},
323
+ {"_id" => "foo4", "_sig" => "foo4", "value" => "bar4"},
324
+ {"_id" => "foo5", "_sig" => "foo5", "value" => "bar5"},
325
+ ])
326
+ end
327
+
328
+ it "Does write a page to vm_cache that **does** already exist as <unbased, changes> receives an 'update' response from the external socket.io **with** an existing changes_id" do
329
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/watch2.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
330
+ dump = ctx.evald %{
331
+ //Call embed on main root view
332
+ dump.base = _embed("my_controller", 0, {}, null);
333
+
334
+ //Drain queue
335
+ int_dispatch([]);
336
+
337
+ //pg_sockio0 socket address & the endpoint for the event callback
338
+ dump.pg_sockio0_bp = pg_sockio0_bp;
339
+ }
340
+
341
+ #sockio driver should have been signaled (which it should respond asynchronously, and presumabely, after the disk)
342
+ @driver.ignore_up_to "if_sockio_send"
343
+ @driver.mexpect "if_sockio_send", [Integer, "watch", {
344
+ "page_id" => "test"
345
+ }], 1
346
+
347
+ #The disk should have been signaled
348
+ @driver.ignore_up_to "if_per_get"
349
+ @driver.mexpect "if_per_get", ["vm", "sockio", "test"], 2
350
+
351
+
352
+ #The disk should respond with a page that contains changes
353
+ @driver.int "int_per_get_res", ["vm", "sockio", "test", {
354
+ "_id" => "test",
355
+ "_next" => nil,
356
+ "_head" => nil,
357
+ "entries" => [
358
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
359
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
360
+ ],
361
+ "__changes" => [
362
+ ["+", 0, {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"}],
363
+ ["+", 1, {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}],
364
+ ["-", "foo3"],
365
+ ],
366
+ "__changes_id" => "foo"
367
+ }]
368
+
369
+ #We (driver sockio) received a watch request for a page with the id 'test'
370
+ #Now we are imagining that the socket.io driver received back some
371
+ #data and is now signaling to the kernel that data is available (as it sends to an
372
+ #event endpoint equal to the socket bp)
373
+ @driver.int "int_event", [dump["pg_sockio0_bp"], "update", {
374
+ page: {
375
+ _id: "test",
376
+ _next: nil,
377
+ _head: nil,
378
+ entries: [
379
+ {"_id" => "foo3", "_sig" => "foo3", "value" => "bar3"},
380
+ {"_id" => "foo4", "_sig" => "foo4", "value" => "bar4"}
381
+ ],
382
+ },
383
+ changes_id: "foo"
384
+ }]
385
+
386
+ post_read_res_dump = ctx.evald %{
387
+ for (var i = 0; i < 100; ++i) {
388
+ //Drain queue (vm_cache_write defers to controller)
389
+ int_dispatch([]);
390
+ }
391
+
392
+ dump.read_res_params = read_res_params;
393
+ }
394
+
395
+ #The controller should have received a notification that a page was updated twice, one
396
+ #for the disk response and one for the pager response
397
+ expect(post_read_res_dump["read_res_params"].length).to eq(2)
398
+ expect(post_read_res_dump["read_res_params"][0]["entries"]).to eq([
399
+ {"_id" => "foo1", "_sig" => "foo1", "value" => "bar1"},
400
+ {"_id" => "foo2", "_sig" => "foo2", "value" => "bar2"}
401
+ ])
402
+ #Changes should be present in second copy
403
+ expect(post_read_res_dump["read_res_params"][0]["__changes_id"]).not_to eq(nil)
404
+
405
+
406
+ #Next page should be rebased ontop of the incomming page, however, since changes_id matches
407
+ #current changes on the page, the page is just replaced (as changes were aknowledged and there
408
+ #is nothing to repair)
409
+ expect(post_read_res_dump["read_res_params"][1]["entries"]).to eq([
410
+ {"_id" => "foo3", "_sig" => "foo3", "value" => "bar3"},
411
+ {"_id" => "foo4", "_sig" => "foo4", "value" => "bar4"},
412
+ ])
413
+ #Changes should not be present in second copy
414
+ expect(post_read_res_dump["read_res_params"][1]["__changes_id"]).to eq(nil)
415
+ end
416
+
417
+ it "Does write a page to vm_cache that **does not** already exist when the page receives an 'update' response from the external socket.io" do
81
418
  ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/watch.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
82
419
  dump = ctx.evald %{
83
420
  //Call embed on main root view
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.72
4
+ version: 0.0.73
5
5
  platform: ruby
6
6
  authors:
7
7
  - seo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-07-22 00:00:00.000000000 Z
11
+ date: 2015-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: execjs
@@ -1260,6 +1260,7 @@ files:
1260
1260
  - spec/kern/assets/vm/pg_sockio/config_no_url.rb
1261
1261
  - spec/kern/assets/vm/pg_sockio/nothing.rb
1262
1262
  - spec/kern/assets/vm/pg_sockio/watch.rb
1263
+ - spec/kern/assets/vm/pg_sockio/watch2.rb
1263
1264
  - spec/kern/assets/vm/service0.rb
1264
1265
  - spec/kern/assets/vm/service_controller0.rb
1265
1266
  - spec/kern/assets/vm/vm_commit_pages.js
@@ -2197,6 +2198,7 @@ test_files:
2197
2198
  - spec/kern/assets/vm/pg_sockio/config_no_url.rb
2198
2199
  - spec/kern/assets/vm/pg_sockio/nothing.rb
2199
2200
  - spec/kern/assets/vm/pg_sockio/watch.rb
2201
+ - spec/kern/assets/vm/pg_sockio/watch2.rb
2200
2202
  - spec/kern/assets/vm/service0.rb
2201
2203
  - spec/kern/assets/vm/service_controller0.rb
2202
2204
  - spec/kern/assets/vm/vm_commit_pages.js