flok 0.0.38 → 0.0.39
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 +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
|