flok 0.0.74 → 0.0.75
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/kern/pagers/pg_dummy.js +5 -0
- data/app/kern/pagers/pg_sockio.js +6 -0
- data/app/kern/services/vm.rb +48 -6
- data/docs/dispatch.md +2 -1
- data/docs/known_issues.md +2 -1
- data/docs/services/vm.md +2 -0
- data/docs/services/vm/pagers.md +8 -6
- data/lib/flok/version.rb +1 -1
- data/spec/env/kern.rb +2 -0
- data/spec/kern/assets/vm/config5b.rb +12 -0
- data/spec/kern/assets/vm/controller23.rb +17 -0
- data/spec/kern/assets/vm/controller23b.rb +18 -0
- data/spec/kern/assets/vm/pg_dummy/controller0.rb +18 -0
- data/spec/kern/assets/vm/pg_sockio/write2.rb +4 -0
- data/spec/kern/assets/vm/pg_sockio/write3.rb +24 -0
- data/spec/kern/dummy_pager_spec.rb +39 -0
- data/spec/kern/vm_service_spec.rb +125 -0
- data/spec/kern/vm_sockio_pager_spec.rb +63 -1
- metadata +14 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2ebb7df87c6ad3bd41410cc2feb00b57ec31ce99
|
4
|
+
data.tar.gz: 690eb61b2fa1857439255f483f640697792b05c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 911ea2b457dad557faff40142fb337fea5d833b8d42bd5198e503b4c1850ddf38b003d5e02f78b830d6c546cec19f4548153184bd7f013244b227a0dba4e4b47
|
7
|
+
data.tar.gz: c77b2513cc8ee15c1f0569d402841ca09cbce328def48c2e2dc04db41f93a6fc48c37ffce6ef2fa6fbc7b699634a19892060e63494168cc35897fce45e292e98
|
data/app/kern/pagers/pg_dummy.js
CHANGED
@@ -5,6 +5,8 @@
|
|
5
5
|
pg_dummy<%= i %>_ns = ns;
|
6
6
|
|
7
7
|
pg_dummy<%= i %>_spec_did_init = true;
|
8
|
+
|
9
|
+
pg_dummy<%= i %>_write_vm_cache_clone = [];
|
8
10
|
}
|
9
11
|
|
10
12
|
function pg_dummy<%= i %>_watch(id, page) {
|
@@ -14,5 +16,8 @@
|
|
14
16
|
}
|
15
17
|
|
16
18
|
function pg_dummy<%= i %>_write(page) {
|
19
|
+
//Deep clone vm_cache at call time
|
20
|
+
//Used by specs looking to see if HD lookup happends
|
21
|
+
pg_dummy<%= i %>_write_vm_cache_clone.push(JSON.parse(JSON.stringify(vm_cache)));
|
17
22
|
}
|
18
23
|
<% end %>
|
@@ -66,7 +66,13 @@
|
|
66
66
|
vm_commit(cached_page, page);
|
67
67
|
}
|
68
68
|
|
69
|
+
//Write (Which will *not* copy the page)
|
69
70
|
vm_cache_write(pg_sockio<%= i %>_ns, page);
|
70
71
|
vm_transaction_end();
|
72
|
+
|
73
|
+
//Clone page and send a copy to the server
|
74
|
+
var copied = vm_copy_page(page);
|
75
|
+
var info = {page: copied, changes: page.__changes, changes_id: page.__changes_id};
|
76
|
+
SEND("net", "if_sockio_send", pg_sockio<%= i %>_bp, "write", info);
|
71
77
|
}
|
72
78
|
<% end %>
|
data/app/kern/services/vm.rb
CHANGED
@@ -13,7 +13,15 @@ service :vm do
|
|
13
13
|
<% end %>
|
14
14
|
};
|
15
15
|
|
16
|
+
//See 'Datatypes & Structures' in ./docs/services/vm.md
|
17
|
+
////////////////////////////////////////////////////////////////////////////////////////////
|
16
18
|
vm_bp_to_nmap = {};
|
19
|
+
vm_pager_waiting_read = {
|
20
|
+
<% @options[:pagers].each do |p| %>
|
21
|
+
<%= p[:namespace] %>: {},
|
22
|
+
<% end %>
|
23
|
+
};
|
24
|
+
vm_cache_write_sync_pending = {};
|
17
25
|
|
18
26
|
//Notification listeners, converts ns+key to an array of base pointers
|
19
27
|
vm_notify_map = {
|
@@ -21,8 +29,7 @@ service :vm do
|
|
21
29
|
<%= p[:namespace] %>: {},
|
22
30
|
<% end %>
|
23
31
|
};
|
24
|
-
|
25
|
-
vm_cache_write_sync_pending = {};
|
32
|
+
////////////////////////////////////////////////////////////////////////////////////////////
|
26
33
|
|
27
34
|
//Cache
|
28
35
|
function vm_cache_write(ns, page) {
|
@@ -115,6 +122,7 @@ service :vm do
|
|
115
122
|
vm_transaction_begin();
|
116
123
|
vm_cache_write(ns, res);
|
117
124
|
vm_transaction_end();
|
125
|
+
|
118
126
|
} else {
|
119
127
|
//Result was blank, signal all controllers that read synchronously
|
120
128
|
var sync_waiting_controllers = vm_cache_write_sync_pending[id];
|
@@ -130,6 +138,25 @@ service :vm do
|
|
130
138
|
//Remove all controllers from notification list
|
131
139
|
delete vm_cache_write_sync_pending[id];
|
132
140
|
}
|
141
|
+
|
142
|
+
//Check if a pager is waiting for this read to complete a write request
|
143
|
+
var page_awaiting_write = vm_pager_waiting_read[ns][id];
|
144
|
+
if (page_awaiting_write !== undefined) {
|
145
|
+
<% @options[:pagers].each_with_index do |p, i| %>
|
146
|
+
<% if i == 0 %>
|
147
|
+
if ("<%= p[:namespace] %>" === ns) {
|
148
|
+
<%= p[:name] %>_write(page_awaiting_write);
|
149
|
+
}
|
150
|
+
<% else %>
|
151
|
+
else if ("<%= p[:namespace] %>" === ns) {
|
152
|
+
<%= p[:name] %>_write(page_awaiting_write);
|
153
|
+
}
|
154
|
+
<% end %>
|
155
|
+
<% end %>
|
156
|
+
|
157
|
+
//Clear waiting entry
|
158
|
+
delete vm_pager_waiting_read[ns][id];
|
159
|
+
}
|
133
160
|
}
|
134
161
|
|
135
162
|
<% if @debug %>
|
@@ -543,11 +570,26 @@ service :vm do
|
|
543
570
|
vm_write_list.push(params.page);
|
544
571
|
<% end %>
|
545
572
|
|
546
|
-
|
547
|
-
|
548
|
-
|
573
|
+
//If the page does not exist, we need to send a disk request for a read because we may
|
574
|
+
//need to commit to the page
|
575
|
+
if (vm_cache[params.ns][params.page._id] === undefined) {
|
576
|
+
//Save the page into the waiting list or throw an exception if there's already a write
|
577
|
+
//queued, at this time, we do not support multiple writes in the same frame
|
578
|
+
if (vm_pager_waiting_read[params.ns][params.page._id] !== undefined) {
|
579
|
+
throw "vm on_write was called multiple times within the same frame (I.e. page did not exist, so we read it from disk, but that disk read didn't come back before the page was attempted to written again). This is not terribly illegal but it can lead to undefined behavior.";
|
549
580
|
}
|
550
|
-
|
581
|
+
vm_pager_waiting_read[params.ns][params.page._id] = params.page;
|
582
|
+
|
583
|
+
//Notify the disk
|
584
|
+
SEND("disk", "if_per_get", "vm", params.ns, params.page._id);
|
585
|
+
} else {
|
586
|
+
//Else, just notify the pager right away
|
587
|
+
<% @options[:pagers].each do |p| %>
|
588
|
+
if (params.ns === "<%= p[:namespace] %>") {
|
589
|
+
<%= p[:name] %>_write(params.page);
|
590
|
+
}
|
591
|
+
<% end %>
|
592
|
+
}
|
551
593
|
}
|
552
594
|
|
553
595
|
on "watch", %{
|
data/docs/dispatch.md
CHANGED
@@ -14,7 +14,8 @@ There are various stages of message processing so it can be confusing as to what
|
|
14
14
|
1. The disptach mechanism, `int_dispatch`, is always called by the client synchronously, and the javascript core will always respond synchronously to `if_disptach`.
|
15
15
|
2. The client `if_dispatch` handler will then process the main queue on it's same synchronous thread and then dispatch, asynchronously, the remaining queues; the queues may either each dispatch messages asynchronously or synchronously w.r.t to the original queue. (out of order and parallel are supported)
|
16
16
|
|
17
|
-
Additionally, it is
|
17
|
+
Additionally, it is **never** ok to downgrade an asynchronous request to a synchronous request. Some functions, particularly the `vm` and
|
18
|
+
`controller` systems rely on ordering. You can also **never** downgrade a synhcronous request to an asynchronous request. Synchronous requests must be done in order and on a single thread; additionally, they can be UI requests which are typically handled on the main thread.
|
18
19
|
|
19
20
|
For example, if we dispatch on the `main` queue a disk read request, flok would expect that the disk read would block the javascript core and return execution as soon as the disk read completed. Flok would also presume that the disk read was done at the fastest
|
20
21
|
and highest priority of IO and CPU.
|
data/docs/known_issues.md
CHANGED
@@ -3,4 +3,5 @@
|
|
3
3
|
0000. A `every` event used in a controller's action will time correctly on the first action, but subsequent actions will be off by at most 3 ticks.
|
4
4
|
This is because we do not have any way (currently) to reset the timing queue in the controller as it reisters for all timing events at init. See
|
5
5
|
"Does not call intervals of other actions; and still works when switching back actions" in `spec/kern/controller_spec.rb`
|
6
|
-
|
6
|
+
0002. `vm_cache_write_sync_pending` in the `vm` service relies on page_ids, but this would cause a collision on two pages named the same thing. This
|
7
|
+
needs to integrate the namespace.
|
data/docs/services/vm.md
CHANGED
@@ -157,6 +157,8 @@ Pageout is embodied in the function named `vm_pageout()`. This will asynchronous
|
|
157
157
|
* `vm_cache_write_sync_pending` - A hash mapping page_ids to controllers awaiting synchronous responeses, e.g.
|
158
158
|
`vm_cache_write_sync_pending[page_id][0..N] := bp`. Usually set via the `watch` request
|
159
159
|
during a sync call for disk reads or the synchronous `read_sync` request. The format for each element in the array is `{"page_id": [bp1, bp2], ...}`
|
160
|
+
* `vm_pager_waiting_read` - A hash that maps `[ns][page_id]` into a hash that represents a the page that was trying to be written.
|
161
|
+
needed to be read before notifying the pager. Multiple write attempts on the same page before the disk response will undefined behavior.
|
160
162
|
|
161
163
|
##Helper Methods
|
162
164
|
|
data/docs/services/vm/pagers.md
CHANGED
@@ -56,7 +56,11 @@ This pager provides you with local memory that will be automatically cached to d
|
|
56
56
|
* `write` - Writes the given page to `vm_cache_write`
|
57
57
|
|
58
58
|
####Dummy pager | `pg_dummy0`
|
59
|
-
This pager doesn't do anything. Used by some specs which manually write to the vm_cache in leu of the pager
|
59
|
+
This pager doesn't do anything beyond save data during calls. Used by some specs which manually write to the vm_cache in leu of the pager
|
60
|
+
* `init` - Does nothing
|
61
|
+
* `watch` - Does nothing
|
62
|
+
* `unwatch` - Does nothing
|
63
|
+
* `write` - Pushes `vm_cache` (deep clone) into `pg_dummyN_write_vm_cache_clone` array
|
60
64
|
|
61
65
|
####Sockio pager | `pg_sockio0`
|
62
66
|
This pager connects to a socket.io server via the `sockio` module.
|
@@ -73,11 +77,9 @@ This pager connects to a socket.io server via the `sockio` module.
|
|
73
77
|
* `watch` - Signals to the socket.io server that a page is being watched via `watch` event with parameters `{page_id:}`
|
74
78
|
* `unwatch` - Signals to the socket.io server that a page is no longer being watched via `unwatch` event with parameters `{page_id:}`
|
75
79
|
* `write` -
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
* If the page does not exist:
|
80
|
-
* writes directly to `vm_cache` and notifies the server of the creation via `/create` with `page:`
|
80
|
+
* Sends the sockio server the `write` event with a hash containing `page`, and optionally (`changes`, and `changes_id`). The `page` contains only the basic
|
81
|
+
page, `changes` is the vm_diff array (originally `page.__changes`) and `changes_id` was originally `page.__changes_id`. The page is a copy
|
82
|
+
of the original request (without __changes ([vm_diff] or __changes_id (string) in the hash if they exist)
|
81
83
|
* **Socket.IO Event Handlers **
|
82
84
|
* `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
85
|
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`
|
data/lib/flok/version.rb
CHANGED
data/spec/env/kern.rb
CHANGED
@@ -39,11 +39,13 @@ shared_context "kern" do
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def dump_log
|
42
|
+
$stderr.puts "---------------------------------------------------"
|
42
43
|
out = self.dump "kern_log_stdout"
|
43
44
|
self.eval "kern_log_stdout = []"
|
44
45
|
out.each_with_index do |e, i|
|
45
46
|
ap e
|
46
47
|
end
|
48
|
+
$stderr.puts "---------------------------------------------------"
|
47
49
|
end
|
48
50
|
end
|
49
51
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
services :vm
|
3
|
+
|
4
|
+
action :my_action do
|
5
|
+
on_entry %{
|
6
|
+
//Page to write
|
7
|
+
var page = vm_create_page("test");
|
8
|
+
|
9
|
+
//Dispatch write request
|
10
|
+
var info = {
|
11
|
+
ns: "dummy",
|
12
|
+
page: page
|
13
|
+
}
|
14
|
+
Request("vm", "write", info);
|
15
|
+
}
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
services :vm
|
3
|
+
|
4
|
+
action :my_action do
|
5
|
+
on_entry %{
|
6
|
+
//Page to write
|
7
|
+
var page = vm_create_page("test");
|
8
|
+
|
9
|
+
//Dispatch write request
|
10
|
+
var info = {
|
11
|
+
ns: "dummy",
|
12
|
+
page: page
|
13
|
+
}
|
14
|
+
Request("vm", "write", info);
|
15
|
+
Request("vm", "write", info);
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
services :vm
|
3
|
+
|
4
|
+
action :my_action do
|
5
|
+
on "do_write", %{
|
6
|
+
var page = vm_create_page("lol");
|
7
|
+
|
8
|
+
//Cheat and put the page in
|
9
|
+
vm_cache["dummy"]["lol"] = page;
|
10
|
+
|
11
|
+
var info = {
|
12
|
+
ns: "dummy",
|
13
|
+
page: page
|
14
|
+
}
|
15
|
+
Request("vm", "write", info);
|
16
|
+
}
|
17
|
+
end
|
18
|
+
end
|
@@ -4,7 +4,10 @@ controller :my_controller do
|
|
4
4
|
on_entry %{
|
5
5
|
read_res_params = [];
|
6
6
|
|
7
|
+
/////////////////////////////////////////////////////////////////////////
|
7
8
|
//Create a page and commit it to the sockio cache (cheating)
|
9
|
+
//This way we know a commit should be performed when a write goes through
|
10
|
+
/////////////////////////////////////////////////////////////////////////
|
8
11
|
var page = vm_create_page("test");
|
9
12
|
page.entries.push(
|
10
13
|
{"_id": "test", "_sig": "test", "val": "test"}
|
@@ -12,6 +15,7 @@ controller :my_controller do
|
|
12
15
|
vm_reindex_page(page);
|
13
16
|
vm_rehash_page(page);
|
14
17
|
vm_cache["sockio"]["test"] = page;
|
18
|
+
/////////////////////////////////////////////////////////////////////////
|
15
19
|
}
|
16
20
|
|
17
21
|
action :my_action do
|
@@ -0,0 +1,24 @@
|
|
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 page = vm_create_page("test");
|
11
|
+
|
12
|
+
var info = {
|
13
|
+
ns: "sockio",
|
14
|
+
page: page,
|
15
|
+
};
|
16
|
+
|
17
|
+
Request("vm", "write", info);
|
18
|
+
}
|
19
|
+
|
20
|
+
on "read_res", %{
|
21
|
+
read_res_params.push(JSON.parse(JSON.stringify(params)));
|
22
|
+
}
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
#The dummy pager
|
2
|
+
|
3
|
+
Dir.chdir File.join File.dirname(__FILE__), '../../'
|
4
|
+
require 'zlib'
|
5
|
+
require './spec/env/kern.rb'
|
6
|
+
require './spec/lib/helpers.rb'
|
7
|
+
require './spec/lib/io_extensions.rb'
|
8
|
+
require './spec/lib/rspec_extensions.rb'
|
9
|
+
|
10
|
+
RSpec.describe "kern:dummy_pager" do
|
11
|
+
include Zlib
|
12
|
+
include_context "kern"
|
13
|
+
|
14
|
+
it "Writes to the dummy pager end up in the pg_dummyN_write_vm_cache_clone array" do
|
15
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_dummy/controller0.rb'), File.read("./spec/kern/assets/vm/pg_dummy/config.rb")
|
16
|
+
dump = ctx.evald %{
|
17
|
+
dump.base = _embed("my_controller", 0, {}, null);
|
18
|
+
|
19
|
+
//Drain queue
|
20
|
+
int_dispatch([]);
|
21
|
+
|
22
|
+
dump.pg_dummy0_write_vm_cache_clone = pg_dummy0_write_vm_cache_clone;
|
23
|
+
}
|
24
|
+
|
25
|
+
#Should be empty at first
|
26
|
+
expect(dump["pg_dummy0_write_vm_cache_clone"]).to eq([])
|
27
|
+
|
28
|
+
@driver.int "int_event", [
|
29
|
+
dump["base"],
|
30
|
+
"do_write",
|
31
|
+
{}
|
32
|
+
]
|
33
|
+
|
34
|
+
#Should have gotten the write request and cloned the vm_cache
|
35
|
+
pg_dummy0_write_vm_cache_clone = ctx.dump "pg_dummy0_write_vm_cache_clone"
|
36
|
+
expect(pg_dummy0_write_vm_cache_clone.length).to eq(1)
|
37
|
+
expect(pg_dummy0_write_vm_cache_clone[0]["dummy"]["lol"]["_id"]).to eq("lol")
|
38
|
+
end
|
39
|
+
end
|
@@ -1390,4 +1390,129 @@ RSpec.describe "kern:vm_service" do
|
|
1390
1390
|
"options" => {"foo" => "bar"}
|
1391
1391
|
})
|
1392
1392
|
end
|
1393
|
+
|
1394
|
+
it "Does send a disk read request when attempting to write to a page that dosen't exist in vm_cache (that page may exist on disk and will need to be commited over)" do
|
1395
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/controller23.rb'), File.read("./spec/kern/assets/vm/config5b.rb")
|
1396
|
+
ctx.eval %{
|
1397
|
+
base = _embed("my_controller", 0, {}, null);
|
1398
|
+
|
1399
|
+
//Drain queue
|
1400
|
+
int_dispatch([]);
|
1401
|
+
}
|
1402
|
+
|
1403
|
+
#Expect a if_per_get request attempt
|
1404
|
+
@driver.ignore_up_to "if_per_get", 2
|
1405
|
+
@driver.mexpect "if_per_get", [
|
1406
|
+
"vm",
|
1407
|
+
"dummy",
|
1408
|
+
"test"
|
1409
|
+
], 2
|
1410
|
+
end
|
1411
|
+
|
1412
|
+
it "Does *not* send a disk read request when attempting to write to a page that dosen't exist in vm_cache (that page may exist on disk and will need to be commited over)" do
|
1413
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/controller23.rb'), File.read("./spec/kern/assets/vm/config5b.rb")
|
1414
|
+
ctx.eval %{
|
1415
|
+
//Fake existance of a page
|
1416
|
+
var page = vm_create_page("test");
|
1417
|
+
vm_rehash_page(page);
|
1418
|
+
vm_reindex_page(page);
|
1419
|
+
vm_cache["dummy"]["test"] = page;
|
1420
|
+
|
1421
|
+
base = _embed("my_controller", 0, {}, null);
|
1422
|
+
|
1423
|
+
//Drain queue
|
1424
|
+
int_dispatch([]);
|
1425
|
+
}
|
1426
|
+
|
1427
|
+
#Expect not to get an if_per_get request attempt (it's already cached)
|
1428
|
+
@driver.expect_not_to_contain "if_per_get"
|
1429
|
+
end
|
1430
|
+
|
1431
|
+
|
1432
|
+
it "Does notify the pager of a write when a controller originally made a write request for a non-cached entry when that disk read returns without a page (null)" do
|
1433
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/controller23.rb'), File.read("./spec/kern/assets/vm/config5b.rb")
|
1434
|
+
ctx.eval %{
|
1435
|
+
base = _embed("my_controller", 0, {}, null);
|
1436
|
+
|
1437
|
+
//Drain queue
|
1438
|
+
int_dispatch([]);
|
1439
|
+
}
|
1440
|
+
|
1441
|
+
#Expect a if_per_get request attempt
|
1442
|
+
@driver.ignore_up_to "if_per_get", 2
|
1443
|
+
@driver.mexpect "if_per_get", [
|
1444
|
+
"vm",
|
1445
|
+
"dummy",
|
1446
|
+
"test"
|
1447
|
+
], 2
|
1448
|
+
|
1449
|
+
#Respond with a blank page (page does not exist on disk)
|
1450
|
+
@driver.int "int_per_get_res", [
|
1451
|
+
"vm",
|
1452
|
+
"dummy",
|
1453
|
+
"test",
|
1454
|
+
nil
|
1455
|
+
]
|
1456
|
+
|
1457
|
+
#Expect the pager to have received a write request by now
|
1458
|
+
dump = ctx.evald %{
|
1459
|
+
dump.pg_dummy0_write_vm_cache_clone = pg_dummy0_write_vm_cache_clone
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
expect(dump["pg_dummy0_write_vm_cache_clone"]).to eq([
|
1463
|
+
{"dummy" => {}}
|
1464
|
+
])
|
1465
|
+
end
|
1466
|
+
|
1467
|
+
it "Does notify the pager of a write when a controller originally made a write request for a non-cached entry when that disk read returns with a page" do
|
1468
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/controller23.rb'), File.read("./spec/kern/assets/vm/config5b.rb")
|
1469
|
+
ctx.eval %{
|
1470
|
+
base = _embed("my_controller", 0, {}, null);
|
1471
|
+
|
1472
|
+
//Drain queue
|
1473
|
+
int_dispatch([]);
|
1474
|
+
}
|
1475
|
+
|
1476
|
+
#Expect a if_per_get request attempt
|
1477
|
+
@driver.ignore_up_to "if_per_get", 2
|
1478
|
+
@driver.mexpect "if_per_get", [
|
1479
|
+
"vm",
|
1480
|
+
"dummy",
|
1481
|
+
"test"
|
1482
|
+
], 2
|
1483
|
+
|
1484
|
+
#Respond with a blank page (page does not exist on disk)
|
1485
|
+
@driver.int "int_per_get_res", [
|
1486
|
+
"vm",
|
1487
|
+
"dummy",
|
1488
|
+
"test",
|
1489
|
+
{
|
1490
|
+
"_id" => "test",
|
1491
|
+
"_next" => nil,
|
1492
|
+
"_head" => nil,
|
1493
|
+
"entries" => []
|
1494
|
+
}
|
1495
|
+
]
|
1496
|
+
|
1497
|
+
#Expect the pager to have received a write request by now, and the dummy pager saves everything
|
1498
|
+
#it gets into a special variable queue (copied via deep clone of vm_cache)
|
1499
|
+
dump = ctx.evald %{
|
1500
|
+
dump.pg_dummy0_write_vm_cache_clone = pg_dummy0_write_vm_cache_clone
|
1501
|
+
}
|
1502
|
+
expect(dump["pg_dummy0_write_vm_cache_clone"].length).to eq(1)
|
1503
|
+
expect(dump["pg_dummy0_write_vm_cache_clone"][0]["dummy"]["test"]).not_to eq(nil)
|
1504
|
+
expect(dump["pg_dummy0_write_vm_cache_clone"][0]["dummy"]["test"]["_id"]).to eq("test")
|
1505
|
+
end
|
1506
|
+
|
1507
|
+
it "Does throw an exception if two writes are attempted in the same frame for a non-cached page" do
|
1508
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/controller23b.rb'), File.read("./spec/kern/assets/vm/config5b.rb")
|
1509
|
+
expect {
|
1510
|
+
ctx.eval %{
|
1511
|
+
base = _embed("my_controller", 0, {}, null);
|
1512
|
+
|
1513
|
+
//Drain queue
|
1514
|
+
int_dispatch([]);
|
1515
|
+
}
|
1516
|
+
}.to raise_error(/.*multiple.*/)
|
1517
|
+
end
|
1393
1518
|
end
|
@@ -452,7 +452,7 @@ RSpec.describe "kern:sockio_pager" do
|
|
452
452
|
])
|
453
453
|
end
|
454
454
|
|
455
|
-
it "Does accept writes of pages that don't currently exist in cache; they go into vm_cache as-is" do
|
455
|
+
it "Does accept writes of pages that don't currently exist in cache; they go into vm_cache as-is and are sent to the sockio driver" do
|
456
456
|
ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/write.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
|
457
457
|
dump = ctx.evald %{
|
458
458
|
//Call embed on main root view
|
@@ -464,8 +464,22 @@ RSpec.describe "kern:sockio_pager" do
|
|
464
464
|
dump.vm_cache = vm_cache;
|
465
465
|
}
|
466
466
|
|
467
|
+
#Driver response
|
468
|
+
@driver.int "int_per_get_res", [
|
469
|
+
"vm",
|
470
|
+
"sockio",
|
471
|
+
"test"
|
472
|
+
], 2
|
473
|
+
|
467
474
|
#The vm_cache should now contain an entry for the page
|
468
475
|
expect(dump["vm_cache"]["sockio"]["test"]).not_to eq(nil)
|
476
|
+
|
477
|
+
@driver.ignore_up_to "if_sockio_send", 1
|
478
|
+
@driver.mexpect "if_sockio_send", [
|
479
|
+
Integer,
|
480
|
+
"page_write",
|
481
|
+
dump["vm_cache"]["sockio"]["test"]
|
482
|
+
], 1
|
469
483
|
end
|
470
484
|
|
471
485
|
it "Does accept writes of pages that **do** currently exist in cache; they go into vm_cache commited" do
|
@@ -487,4 +501,52 @@ RSpec.describe "kern:sockio_pager" do
|
|
487
501
|
expect(dump["vm_cache"]["sockio"]["test"]["__changes"]).not_to eq(nil)
|
488
502
|
expect(dump["vm_cache"]["sockio"]["test"]["__changes_id"]).not_to eq(nil)
|
489
503
|
end
|
504
|
+
|
505
|
+
it "Does write to sockio interface when a page is requested to be written with changes with a page and changes" do
|
506
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/write2.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
|
507
|
+
dump = ctx.evald %{
|
508
|
+
//Call embed on main root view
|
509
|
+
dump.base = _embed("my_controller", 0, {}, null);
|
510
|
+
|
511
|
+
//Drain queue
|
512
|
+
int_dispatch([]);
|
513
|
+
|
514
|
+
dump.vm_cache = vm_cache;
|
515
|
+
}
|
516
|
+
|
517
|
+
#The kernel should have signaled to the driver to send a sockio request with the changes
|
518
|
+
@driver.ignore_up_to "if_sockio_send", 1
|
519
|
+
res = @driver.get "if_sockio_send", 1
|
520
|
+
expect(res[2]["page"]["_id"]).to eq("test")
|
521
|
+
expect(res[2]["changes"]).to eq([["-", "test"]])
|
522
|
+
expect(res[2]["changes_id"].class).to eq(String)
|
523
|
+
end
|
524
|
+
|
525
|
+
it "Does write to sockio interface when a page is requested to be written without changes with a page: and no changes: field" do
|
526
|
+
ctx = flok_new_user File.read('./spec/kern/assets/vm/pg_sockio/write3.rb'), File.read("./spec/kern/assets/vm/pg_sockio/config.rb")
|
527
|
+
dump = ctx.evald %{
|
528
|
+
//Call embed on main root view
|
529
|
+
dump.base = _embed("my_controller", 0, {}, null);
|
530
|
+
|
531
|
+
//Drain queue
|
532
|
+
int_dispatch([]);
|
533
|
+
|
534
|
+
dump.vm_cache = vm_cache;
|
535
|
+
}
|
536
|
+
|
537
|
+
#The HD should have been requested (as it's not cached and it tries to lookup)
|
538
|
+
@driver.int "int_per_get_res", [
|
539
|
+
"vm",
|
540
|
+
"sockio",
|
541
|
+
"test",
|
542
|
+
nil
|
543
|
+
]
|
544
|
+
|
545
|
+
#The kernel should have signaled to the driver to send a sockio request without the changes
|
546
|
+
@driver.ignore_up_to "if_sockio_send", 1
|
547
|
+
res = @driver.get "if_sockio_send", 1
|
548
|
+
expect(res[2]["page"]["_id"]).to eq("test")
|
549
|
+
expect(res[2]["changes"]).to eq(nil)
|
550
|
+
expect(res[2]["changes_id"]).to eq(nil)
|
551
|
+
end
|
490
552
|
end
|
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.
|
4
|
+
version: 0.0.75
|
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-
|
11
|
+
date: 2015-07-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: execjs
|
@@ -1208,6 +1208,7 @@ files:
|
|
1208
1208
|
- spec/kern/assets/vm/config3.rb
|
1209
1209
|
- spec/kern/assets/vm/config4.rb
|
1210
1210
|
- spec/kern/assets/vm/config5.rb
|
1211
|
+
- spec/kern/assets/vm/config5b.rb
|
1211
1212
|
- spec/kern/assets/vm/config6.rb
|
1212
1213
|
- spec/kern/assets/vm/controller0.rb
|
1213
1214
|
- spec/kern/assets/vm/controller0_diff.rb
|
@@ -1234,6 +1235,8 @@ files:
|
|
1234
1235
|
- spec/kern/assets/vm/controller20.rb
|
1235
1236
|
- spec/kern/assets/vm/controller21.rb
|
1236
1237
|
- spec/kern/assets/vm/controller22.rb
|
1238
|
+
- spec/kern/assets/vm/controller23.rb
|
1239
|
+
- spec/kern/assets/vm/controller23b.rb
|
1237
1240
|
- spec/kern/assets/vm/controller3.rb
|
1238
1241
|
- spec/kern/assets/vm/controller4.rb
|
1239
1242
|
- spec/kern/assets/vm/controller5.rb
|
@@ -1263,6 +1266,7 @@ files:
|
|
1263
1266
|
- spec/kern/assets/vm/macros/set_page_head_c.rb
|
1264
1267
|
- spec/kern/assets/vm/macros/set_page_next_c.rb
|
1265
1268
|
- spec/kern/assets/vm/pg_dummy/config.rb
|
1269
|
+
- spec/kern/assets/vm/pg_dummy/controller0.rb
|
1266
1270
|
- spec/kern/assets/vm/pg_mem/config.rb
|
1267
1271
|
- spec/kern/assets/vm/pg_mem/config1.rb
|
1268
1272
|
- spec/kern/assets/vm/pg_mem/config2.rb
|
@@ -1280,6 +1284,7 @@ files:
|
|
1280
1284
|
- spec/kern/assets/vm/pg_sockio/watch2.rb
|
1281
1285
|
- spec/kern/assets/vm/pg_sockio/write.rb
|
1282
1286
|
- spec/kern/assets/vm/pg_sockio/write2.rb
|
1287
|
+
- spec/kern/assets/vm/pg_sockio/write3.rb
|
1283
1288
|
- spec/kern/assets/vm/service0.rb
|
1284
1289
|
- spec/kern/assets/vm/service_controller0.rb
|
1285
1290
|
- spec/kern/assets/vm/vm_commit_pages.js
|
@@ -1291,6 +1296,7 @@ files:
|
|
1291
1296
|
- spec/kern/debug_spec.rb
|
1292
1297
|
- spec/kern/debug_ui_spec.rb
|
1293
1298
|
- spec/kern/dispatch_spec.rb
|
1299
|
+
- spec/kern/dummy_pager_spec.rb
|
1294
1300
|
- spec/kern/event_spec.rb
|
1295
1301
|
- spec/kern/functions_spec.rb
|
1296
1302
|
- spec/kern/global_functions_spec.rb
|
@@ -2151,6 +2157,7 @@ test_files:
|
|
2151
2157
|
- spec/kern/assets/vm/config3.rb
|
2152
2158
|
- spec/kern/assets/vm/config4.rb
|
2153
2159
|
- spec/kern/assets/vm/config5.rb
|
2160
|
+
- spec/kern/assets/vm/config5b.rb
|
2154
2161
|
- spec/kern/assets/vm/config6.rb
|
2155
2162
|
- spec/kern/assets/vm/controller0.rb
|
2156
2163
|
- spec/kern/assets/vm/controller0_diff.rb
|
@@ -2177,6 +2184,8 @@ test_files:
|
|
2177
2184
|
- spec/kern/assets/vm/controller20.rb
|
2178
2185
|
- spec/kern/assets/vm/controller21.rb
|
2179
2186
|
- spec/kern/assets/vm/controller22.rb
|
2187
|
+
- spec/kern/assets/vm/controller23.rb
|
2188
|
+
- spec/kern/assets/vm/controller23b.rb
|
2180
2189
|
- spec/kern/assets/vm/controller3.rb
|
2181
2190
|
- spec/kern/assets/vm/controller4.rb
|
2182
2191
|
- spec/kern/assets/vm/controller5.rb
|
@@ -2206,6 +2215,7 @@ test_files:
|
|
2206
2215
|
- spec/kern/assets/vm/macros/set_page_head_c.rb
|
2207
2216
|
- spec/kern/assets/vm/macros/set_page_next_c.rb
|
2208
2217
|
- spec/kern/assets/vm/pg_dummy/config.rb
|
2218
|
+
- spec/kern/assets/vm/pg_dummy/controller0.rb
|
2209
2219
|
- spec/kern/assets/vm/pg_mem/config.rb
|
2210
2220
|
- spec/kern/assets/vm/pg_mem/config1.rb
|
2211
2221
|
- spec/kern/assets/vm/pg_mem/config2.rb
|
@@ -2223,6 +2233,7 @@ test_files:
|
|
2223
2233
|
- spec/kern/assets/vm/pg_sockio/watch2.rb
|
2224
2234
|
- spec/kern/assets/vm/pg_sockio/write.rb
|
2225
2235
|
- spec/kern/assets/vm/pg_sockio/write2.rb
|
2236
|
+
- spec/kern/assets/vm/pg_sockio/write3.rb
|
2226
2237
|
- spec/kern/assets/vm/service0.rb
|
2227
2238
|
- spec/kern/assets/vm/service_controller0.rb
|
2228
2239
|
- spec/kern/assets/vm/vm_commit_pages.js
|
@@ -2234,6 +2245,7 @@ test_files:
|
|
2234
2245
|
- spec/kern/debug_spec.rb
|
2235
2246
|
- spec/kern/debug_ui_spec.rb
|
2236
2247
|
- spec/kern/dispatch_spec.rb
|
2248
|
+
- spec/kern/dummy_pager_spec.rb
|
2237
2249
|
- spec/kern/event_spec.rb
|
2238
2250
|
- spec/kern/functions_spec.rb
|
2239
2251
|
- spec/kern/global_functions_spec.rb
|