flok 0.0.38 → 0.0.39
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/drivers/chrome/src/dispatch.js +41 -6
- data/app/drivers/chrome/src/persist.js +1 -10
- data/app/kern/dispatch.js +17 -23
- data/app/kern/gen_id.js +8 -0
- data/app/kern/macro.rb +20 -18
- data/app/kern/pagers/pg_spec0.js +20 -0
- data/app/kern/services/vm.rb +176 -30
- data/docs/client_api.md +3 -1
- data/docs/compilation.md +1 -1
- data/docs/dispatch.md +91 -0
- data/docs/kernel_api.md +3 -2
- data/docs/messaging.md +6 -1
- data/docs/mod/persist.md +4 -3
- data/docs/project_layout.md +2 -2
- data/docs/services/vm.md +116 -41
- data/docs/services/vm/pagers.md +38 -46
- data/lib/flok.rb +1 -0
- data/lib/flok/build.rb +3 -4
- data/lib/flok/macro.rb +27 -0
- data/lib/flok/services_compiler.rb +12 -8
- data/lib/flok/user_compiler.rb +131 -4
- data/lib/flok/version.rb +1 -1
- data/spec/env/kern.rb +71 -0
- data/spec/etc/macro_spec.rb +3 -8
- data/spec/etc/service_compiler/service3.rb +27 -0
- data/spec/etc/services_compiler_spec.rb +35 -27
- data/spec/iface/driver/dispatch_spec.rb +20 -0
- data/spec/iface/driver/persist_spec.rb +9 -24
- data/spec/iface/kern/ping_spec.rb +3 -24
- data/spec/kern/assets/vm/config4.rb +12 -0
- data/spec/kern/assets/vm/controller10.rb +26 -0
- data/spec/kern/assets/vm/controller11.rb +33 -0
- data/spec/kern/assets/vm/controller12.rb +45 -0
- data/spec/kern/assets/vm/controller13.rb +40 -0
- data/spec/kern/assets/vm/controller14.rb +14 -0
- data/spec/kern/assets/vm/controller15.rb +15 -0
- data/spec/kern/assets/vm/controller16.rb +29 -0
- data/spec/kern/assets/vm/controller17.rb +30 -0
- data/spec/kern/assets/vm/controller18.rb +28 -0
- data/spec/kern/assets/vm/controller19.rb +14 -0
- data/spec/kern/assets/vm/controller19b.rb +15 -0
- data/spec/kern/assets/vm/controller20.rb +19 -0
- data/spec/kern/assets/vm/controller21.rb +40 -0
- data/spec/kern/assets/vm/controller7.rb +18 -0
- data/spec/kern/assets/vm/controller8.rb +38 -0
- data/spec/kern/assets/vm/controller8b.rb +18 -0
- data/spec/kern/assets/vm/controller9.rb +20 -0
- data/spec/kern/assets/vm/controller_exc_2watch.rb +15 -0
- data/spec/kern/assets/vm/controller_exc_ewatch.rb +14 -0
- data/spec/kern/assets/vm/macros/copy_page_c.rb +23 -0
- data/spec/kern/assets/vm/macros/entry_del_c.rb +18 -0
- data/spec/kern/assets/vm/macros/entry_insert_c.rb +21 -0
- data/spec/kern/assets/vm/macros/entry_mutable_c.rb +33 -0
- data/spec/kern/assets/vm/macros/new_page_c.rb +7 -0
- data/spec/kern/assets/vm/macros/new_page_c2.rb +7 -0
- data/spec/kern/assets/vm/macros/set_page_head_c.rb +18 -0
- data/spec/kern/assets/vm/macros/set_page_next_c.rb +18 -0
- data/spec/kern/controller_macro_spec.rb +186 -0
- data/spec/kern/dispatch_spec.rb +125 -0
- data/spec/kern/functions_spec.rb +15 -0
- data/spec/kern/vm_service_spec.rb +874 -173
- metadata +70 -5
- data/docs/scheduling.md +0 -46
- data/spec/kern/rest_service_spec.rb +0 -45
@@ -21,40 +21,48 @@ RSpec.describe "lib/services_compiler" do
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
it "Does fail to compile a controller with a non-existant type" do
|
25
|
-
expect { compile "service_bad_type" }.to raise_exception
|
26
|
-
end
|
24
|
+
#it "Does fail to compile a controller with a non-existant type" do
|
25
|
+
#expect { compile "service_bad_type" }.to raise_exception
|
26
|
+
#end
|
27
27
|
|
28
|
-
it "Can call compile method and get a copy of all the functions" do
|
29
|
-
ctx, _ = compile "service0", "config0"
|
28
|
+
#it "Can call compile method and get a copy of all the functions" do
|
29
|
+
#ctx, _ = compile "service0", "config0"
|
30
30
|
|
31
|
-
|
32
|
-
res = ctx.eval("test_on_wakeup")
|
33
|
-
expect(res).not_to eq(nil)
|
31
|
+
##on_wakeup
|
32
|
+
#res = ctx.eval("test_on_wakeup")
|
33
|
+
#expect(res).not_to eq(nil)
|
34
34
|
|
35
|
-
|
36
|
-
res = ctx.eval("test_on_sleep")
|
37
|
-
expect(res).not_to eq(nil)
|
35
|
+
##on_sleep
|
36
|
+
#res = ctx.eval("test_on_sleep")
|
37
|
+
#expect(res).not_to eq(nil)
|
38
38
|
|
39
|
-
|
40
|
-
res = ctx.eval("test_on_connect");
|
41
|
-
expect(res).not_to eq(nil)
|
39
|
+
##on_connect
|
40
|
+
#res = ctx.eval("test_on_connect");
|
41
|
+
#expect(res).not_to eq(nil)
|
42
42
|
|
43
|
-
|
44
|
-
res = ctx.eval("test_on_disconnect")
|
45
|
-
expect(res).not_to eq(nil)
|
43
|
+
##on_disconnect
|
44
|
+
#res = ctx.eval("test_on_disconnect")
|
45
|
+
#expect(res).not_to eq(nil)
|
46
46
|
|
47
|
-
|
48
|
-
res = ctx.eval("test_on_hello");
|
49
|
-
expect(res).not_to eq(nil)
|
47
|
+
##on_event
|
48
|
+
#res = ctx.eval("test_on_hello");
|
49
|
+
#expect(res).not_to eq(nil)
|
50
50
|
|
51
|
-
|
52
|
-
res = ctx.eval("test_handle_timer_events");
|
53
|
-
expect(res).not_to eq(nil)
|
54
|
-
end
|
51
|
+
##on_handle_timer_events
|
52
|
+
#res = ctx.eval("test_handle_timer_events");
|
53
|
+
#expect(res).not_to eq(nil)
|
54
|
+
#end
|
55
|
+
|
56
|
+
#it "Can call compile method with options" do
|
57
|
+
#ctx, js = compile "service1", "config2"
|
58
|
+
#expect(js).to include("23rntoheuh3nthoeunthn23th");
|
59
|
+
#end
|
60
|
+
|
61
|
+
#If SEND works, then all kernel macros should work
|
62
|
+
it "Can compile with a SEND macro" do
|
63
|
+
ctx, src = compile "service3", "config0"
|
55
64
|
|
56
|
-
|
57
|
-
|
58
|
-
expect(js).to include("23rntoheuh3nthoeunthn23th");
|
65
|
+
expect(src).not_to include("SEND")
|
66
|
+
expect(src).to include("_q.push")
|
59
67
|
end
|
60
68
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Dir.chdir File.join File.dirname(__FILE__), '../../../'
|
2
|
+
require './spec/env/iface.rb'
|
3
|
+
|
4
|
+
RSpec.describe "iface:driver:dispatch_spec" do
|
5
|
+
include_context "iface:driver"
|
6
|
+
|
7
|
+
it "Does automatically dispatch a blank array (signaling int_disptach) when a bulk queue is received prefixed with 'r' indicating incomplete-ness" do
|
8
|
+
@pipe.puts ['i', [0, 0, "ping_nothing"]].to_json
|
9
|
+
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([], 6.seconds)
|
10
|
+
end
|
11
|
+
|
12
|
+
it "Does not dispatch a blank array (signaling int_disptach) when a bulk queue is received prefixed without 'r' indicating incomplete-ness" do
|
13
|
+
@pipe.puts [[0, 0, "ping_nothing"]].to_json
|
14
|
+
expect(@pipe).not_to readline_and_equal_json_x_within_y_seconds([], 6.seconds)
|
15
|
+
end
|
16
|
+
|
17
|
+
#While at first you might think we need to test that int_dispatch called intra-respond of our if_event needs to test whether or not we still send
|
18
|
+
#out blank [] to int_dispatch; this is not the case. In the real world, flok is supposed to also make any necessary if_disptach calls during all
|
19
|
+
#int_dispatch calls. We would always receive back if_dispatch; and thus it would follow the same rules as layed out here
|
20
|
+
end
|
@@ -22,7 +22,7 @@ RSpec.describe "iface:driver:persist" do
|
|
22
22
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([0, "pong"], 5.seconds)
|
23
23
|
end
|
24
24
|
|
25
|
-
it "Can set a persist, and then
|
25
|
+
it "Can set a persist, and then get" do
|
26
26
|
key = SecureRandom.hex
|
27
27
|
value = SecureRandom.hex
|
28
28
|
|
@@ -32,26 +32,11 @@ RSpec.describe "iface:driver:persist" do
|
|
32
32
|
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key]].to_json
|
33
33
|
|
34
34
|
#Expect a response
|
35
|
-
res = [2, "int_per_get_res", "session", value]
|
35
|
+
res = [2, "int_per_get_res", "session", "my_ns", value]
|
36
36
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
37
37
|
end
|
38
38
|
|
39
|
-
|
40
|
-
it "Can set a persist, and then asynchronously get" do
|
41
|
-
key = SecureRandom.hex
|
42
|
-
value = SecureRandom.hex
|
43
|
-
|
44
|
-
#Disk is scheduling class 2
|
45
|
-
@pipe.puts [[2, 3, "if_per_set", "my_ns", key, value]].to_json
|
46
|
-
restart_driver_but_persist
|
47
|
-
@pipe.puts [[2, 3, "if_per_get", "session", "my_ns", key]].to_json
|
48
|
-
|
49
|
-
#Expect a response
|
50
|
-
res = [2, "int_per_get_res", "session", value]
|
51
|
-
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
52
|
-
end
|
53
|
-
|
54
|
-
it "Can set a persist, delete the key, and then synchronously get" do
|
39
|
+
it "Can set a persist, delete the key, and then get" do
|
55
40
|
key = SecureRandom.hex
|
56
41
|
value = SecureRandom.hex
|
57
42
|
|
@@ -62,11 +47,11 @@ it "Can set a persist, delete the key, and then synchronously get" do
|
|
62
47
|
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key]].to_json
|
63
48
|
|
64
49
|
#Expect a response
|
65
|
-
res = [2, "int_per_get_res", "session", nil]
|
50
|
+
res = [2, "int_per_get_res", "session", "my_ns", nil]
|
66
51
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
67
52
|
end
|
68
53
|
|
69
|
-
it "Can set two persists, delete one key, and then
|
54
|
+
it "Can set two persists, delete one key, and then get" do
|
70
55
|
key = SecureRandom.hex
|
71
56
|
key2 = SecureRandom.hex
|
72
57
|
value = SecureRandom.hex
|
@@ -81,15 +66,15 @@ it "Can set a persist, delete the key, and then synchronously get" do
|
|
81
66
|
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key2]].to_json
|
82
67
|
|
83
68
|
#Results for first key
|
84
|
-
res = [2, "int_per_get_res", "session", nil]
|
69
|
+
res = [2, "int_per_get_res", "session", "my_ns", nil]
|
85
70
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
86
71
|
|
87
72
|
#Expect a response
|
88
|
-
res = [2, "int_per_get_res", "session", value2]
|
73
|
+
res = [2, "int_per_get_res", "session", "my_ns", value2]
|
89
74
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
90
75
|
end
|
91
76
|
|
92
|
-
it "Can set a persist, delete the key via ns, and then
|
77
|
+
it "Can set a persist, delete the key via ns, and then get" do
|
93
78
|
key = SecureRandom.hex
|
94
79
|
value = SecureRandom.hex
|
95
80
|
|
@@ -100,7 +85,7 @@ it "Can set a persist, delete the key, and then synchronously get" do
|
|
100
85
|
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key]].to_json
|
101
86
|
|
102
87
|
#Expect a response
|
103
|
-
res = [2, "int_per_get_res", "session", nil]
|
88
|
+
res = [2, "int_per_get_res", "session", "my_ns", nil]
|
104
89
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
105
90
|
end
|
106
91
|
end
|
@@ -3,6 +3,7 @@ require './spec/env/iface.rb'
|
|
3
3
|
require 'securerandom'
|
4
4
|
|
5
5
|
RSpec.describe "iface:kern:ping_spec" do
|
6
|
+
MAX_Q = 5
|
6
7
|
include_context "iface:kern"
|
7
8
|
|
8
9
|
it "supports ping" do
|
@@ -70,8 +71,7 @@ RSpec.describe "iface:kern:ping_spec" do
|
|
70
71
|
"net" => 1,
|
71
72
|
"disk" => 2,
|
72
73
|
"cpu" => 3,
|
73
|
-
"gpu" => 4
|
74
|
-
"async" => 5
|
74
|
+
"gpu" => 4
|
75
75
|
}
|
76
76
|
|
77
77
|
queue_name_to_index.each do |name, index|
|
@@ -79,7 +79,7 @@ RSpec.describe "iface:kern:ping_spec" do
|
|
79
79
|
#Don't redo last one because it's part of the first term (queue_name_b)
|
80
80
|
unless index == queue_name_to_index.count-1
|
81
81
|
queue_name_a = name
|
82
|
-
queue_name_b = @last_queue_name ||
|
82
|
+
queue_name_b = @last_queue_name || queue_name_to_index.keys.last
|
83
83
|
index_a = index
|
84
84
|
index_b = queue_name_to_index[queue_name_b]
|
85
85
|
@pipe.puts [1, "ping3", queue_name_a, 1, "ping3", queue_name_a, 1, "ping3", queue_name_b].to_json
|
@@ -100,25 +100,4 @@ RSpec.describe "iface:kern:ping_spec" do
|
|
100
100
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([[index, 0, "pong3"]], 6.seconds)
|
101
101
|
end
|
102
102
|
end
|
103
|
-
|
104
|
-
#Now make sure the max_n queuing works correctly
|
105
|
-
queue_name_to_index.each do |name, index|
|
106
|
-
it "supports ping-over-commit" do
|
107
|
-
#Main queue always queues all
|
108
|
-
if name != "main" and name != "async" #main and async don't have scheduling
|
109
|
-
@pipe.puts ([1, "ping4", name]*6).to_json
|
110
|
-
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([[index, *[0, "pong4"]*5]], 6.seconds)
|
111
|
-
@pipe.puts ([1, "ping4", name]).to_json
|
112
|
-
|
113
|
-
#Semantics aren't exact, but it should be nothing happens after 2 seconds (no response)
|
114
|
-
expect(@pipe).not_to readline_and_equal_json_x_within_y_seconds([], 1.seconds)
|
115
|
-
|
116
|
-
@pipe.puts ([1, "ping4_int", name]).to_json
|
117
|
-
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([[index, 0, "pong4"]], 6.seconds)
|
118
|
-
else
|
119
|
-
@pipe.puts ([1, "ping4", name]*6).to_json
|
120
|
-
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([[index, *[0, "pong4"]*6]], 6.seconds)
|
121
|
-
end
|
122
|
-
end
|
123
|
-
end
|
124
103
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
services :vm
|
3
|
+
|
4
|
+
action :my_action do
|
5
|
+
on_entry %{
|
6
|
+
var entry = {
|
7
|
+
hello: "world"
|
8
|
+
}
|
9
|
+
|
10
|
+
page = NewPage("test");
|
11
|
+
SetPageHead(page, "head");
|
12
|
+
SetPageNext(page, "next");
|
13
|
+
EntryInsert(page, 0, entry);
|
14
|
+
|
15
|
+
var info = {
|
16
|
+
ns: "spec",
|
17
|
+
page: page
|
18
|
+
};
|
19
|
+
|
20
|
+
Request("vm", "write", info);
|
21
|
+
}
|
22
|
+
|
23
|
+
on "read_res", %{
|
24
|
+
}
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
services :vm
|
3
|
+
|
4
|
+
action :my_action do
|
5
|
+
on_entry %{
|
6
|
+
var entry = {
|
7
|
+
hello: "world"
|
8
|
+
}
|
9
|
+
|
10
|
+
page = NewPage("test");
|
11
|
+
SetPageHead(page, "head");
|
12
|
+
SetPageNext(page, "next");
|
13
|
+
EntryInsert(page, 0, entry);
|
14
|
+
|
15
|
+
var watch_info = {
|
16
|
+
ns: "spec",
|
17
|
+
id: "test"
|
18
|
+
}
|
19
|
+
|
20
|
+
var write_info = {
|
21
|
+
ns: "spec",
|
22
|
+
page: page
|
23
|
+
};
|
24
|
+
|
25
|
+
Request("vm", "watch", watch_info);
|
26
|
+
Request("vm", "write", write_info);
|
27
|
+
}
|
28
|
+
|
29
|
+
on "read_res", %{
|
30
|
+
read_res_params = params;
|
31
|
+
}
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
services :vm
|
3
|
+
|
4
|
+
action :my_action do
|
5
|
+
on_entry %{
|
6
|
+
var entry = {
|
7
|
+
hello: "world"
|
8
|
+
}
|
9
|
+
|
10
|
+
page = NewPage("test");
|
11
|
+
SetPageHead(page, "head");
|
12
|
+
SetPageNext(page, "next");
|
13
|
+
EntryInsert(page, 0, entry);
|
14
|
+
|
15
|
+
page2 = CopyPage(page)
|
16
|
+
EntryInsert(page, 0, entry);
|
17
|
+
|
18
|
+
|
19
|
+
var watch_info = {
|
20
|
+
ns: "spec",
|
21
|
+
id: "test"
|
22
|
+
}
|
23
|
+
|
24
|
+
var write_info = {
|
25
|
+
ns: "spec",
|
26
|
+
page: page
|
27
|
+
};
|
28
|
+
|
29
|
+
var write_info2 = {
|
30
|
+
ns: "spec",
|
31
|
+
page: page2
|
32
|
+
};
|
33
|
+
|
34
|
+
|
35
|
+
read_res_params = [];
|
36
|
+
Request("vm", "write", write_info);
|
37
|
+
Request("vm", "watch", watch_info);
|
38
|
+
Request("vm", "write", write_info2);
|
39
|
+
}
|
40
|
+
|
41
|
+
on "read_res", %{
|
42
|
+
read_res_params.push(params);
|
43
|
+
}
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
services :vm
|
3
|
+
|
4
|
+
action :my_action do
|
5
|
+
on_entry %{
|
6
|
+
var entry = {
|
7
|
+
hello: "world"
|
8
|
+
}
|
9
|
+
|
10
|
+
page = NewPage("test");
|
11
|
+
SetPageHead(page, "head");
|
12
|
+
SetPageNext(page, "next");
|
13
|
+
EntryInsert(page, 0, entry);
|
14
|
+
|
15
|
+
page2 = CopyPage(page)
|
16
|
+
EntryInsert(page, 0, entry);
|
17
|
+
|
18
|
+
|
19
|
+
var watch_info = {
|
20
|
+
ns: "spec",
|
21
|
+
id: "test"
|
22
|
+
}
|
23
|
+
|
24
|
+
var write_info = {
|
25
|
+
ns: "spec",
|
26
|
+
page: page
|
27
|
+
};
|
28
|
+
|
29
|
+
//We are writing the same thing twice
|
30
|
+
read_res_params = [];
|
31
|
+
Request("vm", "write", write_info);
|
32
|
+
Request("vm", "watch", watch_info);
|
33
|
+
Request("vm", "write", write_info);
|
34
|
+
}
|
35
|
+
|
36
|
+
on "read_res", %{
|
37
|
+
read_res_params.push(params);
|
38
|
+
}
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
controller :my_controller do
|
2
|
+
spots "content"
|
3
|
+
|
4
|
+
action :a do
|
5
|
+
|
6
|
+
on_entry %{
|
7
|
+
Embed("a", "content", {});
|
8
|
+
}
|
9
|
+
|
10
|
+
on "next", %{
|
11
|
+
Goto("b");
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
action :b do
|
16
|
+
on_entry %{
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
controller :a do
|
22
|
+
services :vm
|
23
|
+
action :index do
|
24
|
+
on_entry %{
|
25
|
+
var info = {ns: "spec", id: "test"}
|
26
|
+
Request("vm", "watch", info);
|
27
|
+
}
|
28
|
+
end
|
29
|
+
end
|