flok 0.0.36 → 0.0.38
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -0
- data/app/drivers/chrome/build_context.rb +1 -1
- data/app/drivers/chrome/config.yml +10 -0
- data/app/drivers/chrome/pipe.rb +24 -1
- data/app/drivers/chrome/src/persist.js +29 -0
- data/app/drivers/chrome/src/sockio.js +3 -1
- data/app/drivers/chrome/src/vendor/store2.js +3 -0
- data/app/kern/callout.js +55 -0
- data/app/kern/controller.js +3 -0
- data/app/kern/crc32.js +22 -0
- data/app/kern/dispatch.js +16 -0
- data/app/kern/mod/event.js +3 -0
- data/app/kern/mod/persist.js +1 -0
- data/app/kern/mod/timer.js +5 -0
- data/app/kern/pagers/mem_pager.js +2 -0
- data/app/kern/pagers/sockio_pager.js +66 -0
- data/app/kern/pagers/spec0.js +35 -0
- data/app/kern/pagers/spec1.js +24 -0
- data/app/kern/pagers/spec2.js +31 -0
- data/app/kern/services/test.rb +7 -0
- data/app/kern/services/vm.rb +141 -0
- data/app/kern/spec_helper.js +5 -0
- data/bin/flok +27 -5
- data/docs/callout.md +8 -0
- data/docs/client_api.md +1 -1
- data/docs/compilation.md +14 -8
- data/docs/controllers.md +2 -1
- data/docs/datatypes.md +3 -1
- data/docs/environmentals.md +6 -0
- data/docs/interactive.md +6 -1
- data/docs/kernel_api.md +3 -0
- data/docs/mod/event.md +5 -1
- data/docs/mod/persist.md +14 -31
- data/docs/mod/timer.md +4 -2
- data/docs/project.md +16 -5
- data/docs/scheduling.md +1 -0
- data/docs/services.md +141 -56
- data/docs/services/vm.md +128 -0
- data/docs/services/vm/pagers.md +46 -0
- data/lib/flok/build.rb +11 -16
- data/lib/flok/platform.rb +29 -6
- data/lib/flok/project_template/app/scripts/script.js +3 -0
- data/lib/flok/project_template/app/services/service.rb +1 -0
- data/lib/flok/project_template/config/config.yml +1 -0
- data/lib/flok/project_template/config/platforms/chrome/config.yml +1 -0
- data/lib/flok/project_template/config/services.rb +1 -0
- data/lib/flok/service_compiler_templates/services.js.erb +78 -9
- data/lib/flok/services_compiler.rb +117 -20
- data/lib/flok/user_compiler.rb +14 -6
- data/lib/flok/user_compiler_templates/ctable.js.erb +10 -0
- data/lib/flok/version.rb +1 -1
- data/spec/env/etc.rb +1 -1
- data/spec/env/global.rb +2 -0
- data/spec/env/iface.rb +20 -4
- data/spec/env/kern.rb +8 -3
- data/spec/etc/cli_spec.rb +319 -165
- data/spec/etc/lib/assets/config.yml +3 -0
- data/spec/etc/lib/platform_spec.rb +14 -10
- data/spec/etc/lib/project_spec.rb +22 -0
- data/spec/etc/service_compiler/config0.rb +1 -0
- data/spec/etc/service_compiler/config1.rb +1 -0
- data/spec/etc/service_compiler/config2.rb +3 -0
- data/spec/etc/service_compiler/service0.rb +22 -6
- data/spec/etc/service_compiler/service1.rb +26 -0
- data/spec/etc/service_compiler/service_bad_type.rb +20 -0
- data/spec/etc/services_compiler_spec.rb +35 -16
- data/spec/etc/user_compiler/data.js +2 -0
- data/spec/etc/user_compiler_spec.rb +7 -1
- data/spec/iface/driver/persist_spec.rb +106 -0
- data/spec/iface/driver/pipe_spec.rb +5 -0
- data/spec/iface/kern/ping_spec.rb +4 -3
- data/spec/kern/assets/blank.rb +0 -0
- data/spec/kern/assets/service0.rb +24 -0
- data/spec/kern/assets/service1.rb +22 -0
- data/spec/kern/assets/service2.rb +27 -0
- data/spec/kern/assets/service_config0.rb +2 -0
- data/spec/kern/assets/service_config1.rb +2 -0
- data/spec/kern/assets/service_controller0.rb +13 -0
- data/spec/kern/assets/service_controller1.rb +32 -0
- data/spec/kern/assets/service_controller2.rb +38 -0
- data/spec/kern/assets/service_controller3.rb +38 -0
- data/spec/kern/assets/vm/config0.rb +2 -0
- data/spec/kern/assets/vm/config1.rb +12 -0
- data/spec/kern/assets/vm/config2.rb +12 -0
- data/spec/kern/assets/vm/config3.rb +12 -0
- data/spec/kern/assets/vm/controller0.rb +8 -0
- data/spec/kern/assets/vm/controller1.rb +18 -0
- data/spec/kern/assets/vm/controller2.rb +18 -0
- data/spec/kern/assets/vm/controller3.rb +20 -0
- data/spec/kern/assets/vm/controller4.rb +22 -0
- data/spec/kern/assets/vm/controller5.rb +22 -0
- data/spec/kern/assets/vm/controller6.rb +21 -0
- data/spec/kern/assets/vm/service0.rb +24 -0
- data/spec/kern/assets/vm/service_controller0.rb +7 -0
- data/spec/kern/callout_spec.rb +153 -0
- data/spec/kern/functions_spec.rb +29 -0
- data/spec/kern/service_controller_spec.rb +213 -0
- data/spec/kern/vm_service_spec.rb +195 -0
- metadata +98 -12
- data/app/kern/services/rest.rb +0 -310
- data/app/kern/services/timer.rb +0 -30
- data/docs/services/timer.md +0 -21
- data/spec/kern/assets/rest_service.rb +0 -20
- data/spec/kern/assets/timer_service.rb +0 -19
- data/spec/kern/timer_service_spec.rb +0 -40
@@ -1,5 +1,6 @@
|
|
1
1
|
Dir.chdir File.join File.dirname(__FILE__), '../../../'
|
2
2
|
require './lib/flok'
|
3
|
+
require './spec/lib/temp_dir'
|
3
4
|
|
4
5
|
#We are using the CHROME module as a test because it's fairly standardized
|
5
6
|
|
@@ -11,23 +12,26 @@ RSpec.describe "lib/platform" do
|
|
11
12
|
expect(platforms).to include("chrome")
|
12
13
|
end
|
13
14
|
|
14
|
-
it "can list
|
15
|
-
debug_yml = Flok::Platform.config_yml("
|
16
|
-
release_yml = Flok::Platform.config_yml("
|
15
|
+
it "can list specific config_yml" do
|
16
|
+
debug_yml = Flok::Platform.config_yml("DEBUG")
|
17
|
+
release_yml = Flok::Platform.config_yml("RELEASE")
|
17
18
|
|
18
|
-
expect(debug_yml.keys).not_to eq(0)
|
19
|
+
expect(debug_yml.keys.count).not_to eq(0)
|
19
20
|
|
20
21
|
#Should not have same modules (at least for chrome)
|
21
22
|
expect(release_yml["mods"].count).not_to eq(release_yml.keys.count)
|
22
23
|
end
|
23
24
|
|
24
|
-
it "can list modules specific to
|
25
|
-
|
26
|
-
|
25
|
+
it "can list modules specific to an environment" do
|
26
|
+
config_yml = File.read("./spec/etc/lib/assets/config.yml")
|
27
|
+
Dir.chdir new_temp_dir do
|
28
|
+
File.write "config.yml", config_yml
|
29
|
+
ENV['FLOK_CONFIG'] = './config.yml'
|
27
30
|
|
28
|
-
|
31
|
+
debug_mods = Flok::Platform.mods("DEBUG")
|
29
32
|
|
30
|
-
|
31
|
-
|
33
|
+
expect(debug_mods).to include("hello")
|
34
|
+
ENV['FLOK_CONFIG'] = nil
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
@@ -22,4 +22,26 @@ RSpec.describe "lib/project" do
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
25
|
+
|
26
|
+
it "Does contain a copy of the config.yml for the currently active platform in ./config/platforms/$PLATFORM/config.yml" do
|
27
|
+
platform = ENV['PLATFORM']
|
28
|
+
|
29
|
+
dir = new_temp_dir
|
30
|
+
Dir.chdir dir do
|
31
|
+
Flok::Project.create "test"
|
32
|
+
Dir.chdir "test" do
|
33
|
+
#Directory ./config/platforms/$PLATFORM should exist
|
34
|
+
expect(dirs).to include("config/platforms/#{platform}")
|
35
|
+
|
36
|
+
#File ./config/platforms/$PLATFORM/config.yml should exist
|
37
|
+
Dir.chdir "./config/platforms/#{platform}" do
|
38
|
+
expect(files).to include("config.yml")
|
39
|
+
end
|
40
|
+
|
41
|
+
#Files should match in config
|
42
|
+
platform_config_path = File.join(File.dirname(__FILE__), "../../../app/drivers/#{platform}/config.yml")
|
43
|
+
expect(File.read("./config/platforms/#{platform}/config.yml").strip).to eq(File.read(platform_config_path).strip)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
25
47
|
end
|
@@ -0,0 +1 @@
|
|
1
|
+
service_instance :test, :my_service
|
@@ -0,0 +1 @@
|
|
1
|
+
service_instance :blah, :my_service
|
@@ -1,10 +1,26 @@
|
|
1
|
-
service
|
2
|
-
|
3
|
-
|
1
|
+
service :my_service do
|
2
|
+
on_wakeup %{
|
3
|
+
on_wakeup_called = true;
|
4
4
|
}
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
on_sleep %{
|
7
|
+
on_sleep_called = true;
|
8
|
+
}
|
9
|
+
|
10
|
+
on_connect %{
|
11
|
+
on_connect_called_bp = bp;
|
12
|
+
}
|
13
|
+
|
14
|
+
on_disconnect %{
|
15
|
+
on_disconnect_called_bp = bp;
|
16
|
+
}
|
17
|
+
|
18
|
+
on "hello", %{
|
19
|
+
on_hello_called_bp = bp;
|
20
|
+
on_hello_called_params = JSON.stringify(params);
|
21
|
+
}
|
22
|
+
|
23
|
+
every 5.seconds, %{
|
24
|
+
on_every_5_sec_called = true;
|
9
25
|
}
|
10
26
|
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
service :my_service do
|
2
|
+
on_wakeup %{
|
3
|
+
on_wakeup_called = '#{@options[:hello]}';
|
4
|
+
}
|
5
|
+
|
6
|
+
on_sleep %{
|
7
|
+
on_sleep_called = true;
|
8
|
+
}
|
9
|
+
|
10
|
+
on_connect %{
|
11
|
+
on_connect_called_bp = bp;
|
12
|
+
}
|
13
|
+
|
14
|
+
on_disconnect %{
|
15
|
+
on_disconnect_called_bp = bp;
|
16
|
+
}
|
17
|
+
|
18
|
+
on "hello", %{
|
19
|
+
on_hello_called_bp = bp;
|
20
|
+
on_hello_called_params = JSON.stringify(params);
|
21
|
+
}
|
22
|
+
|
23
|
+
every 5.seconds, %{
|
24
|
+
on_every_5_sec_called = true;
|
25
|
+
}
|
26
|
+
end
|
@@ -4,13 +4,14 @@ require './spec/env/etc'
|
|
4
4
|
|
5
5
|
RSpec.describe "lib/services_compiler" do
|
6
6
|
#Return a v8 instance of a compiled js file
|
7
|
-
def compile fn
|
7
|
+
def compile fn, config
|
8
8
|
compiler = Flok::ServicesCompiler
|
9
9
|
js_src(fn)
|
10
|
-
js_res = compiler.compile(js_src(fn))
|
10
|
+
js_res = compiler.compile(js_src(fn), js_src(config))
|
11
11
|
ctx = V8::Context.new
|
12
12
|
ctx.eval js_res
|
13
|
-
|
13
|
+
|
14
|
+
return ctx, js_res
|
14
15
|
end
|
15
16
|
|
16
17
|
#Get the source for a file in ./service_compiler/*.rb
|
@@ -20,22 +21,40 @@ RSpec.describe "lib/services_compiler" do
|
|
20
21
|
end
|
21
22
|
end
|
22
23
|
|
23
|
-
it "
|
24
|
-
|
25
|
-
|
26
|
-
#The service defines a variable in on_init, this should be always accessible
|
27
|
-
res = ctx.eval("test_service_var")
|
28
|
-
expect(res).to eq(true)
|
24
|
+
it "Does fail to compile a controller with a non-existant type" do
|
25
|
+
expect { compile "service_bad_type" }.to raise_exception
|
29
26
|
end
|
30
27
|
|
31
|
-
it "Can call compile method and get
|
32
|
-
|
28
|
+
it "Can call compile method and get a copy of all the functions" do
|
29
|
+
ctx, _ = compile "service0", "config0"
|
30
|
+
|
31
|
+
#on_wakeup
|
32
|
+
res = ctx.eval("test_on_wakeup")
|
33
|
+
expect(res).not_to eq(nil)
|
34
|
+
|
35
|
+
#on_sleep
|
36
|
+
res = ctx.eval("test_on_sleep")
|
37
|
+
expect(res).not_to eq(nil)
|
33
38
|
|
34
|
-
#
|
35
|
-
ctx.eval(
|
39
|
+
#on_connect
|
40
|
+
res = ctx.eval("test_on_connect");
|
41
|
+
expect(res).not_to eq(nil)
|
42
|
+
|
43
|
+
#on_disconnect
|
44
|
+
res = ctx.eval("test_on_disconnect")
|
45
|
+
expect(res).not_to eq(nil)
|
46
|
+
|
47
|
+
#on_event
|
48
|
+
res = ctx.eval("test_on_hello");
|
49
|
+
expect(res).not_to eq(nil)
|
50
|
+
|
51
|
+
#on_handle_timer_events
|
52
|
+
res = ctx.eval("test_handle_timer_events");
|
53
|
+
expect(res).not_to eq(nil)
|
54
|
+
end
|
36
55
|
|
37
|
-
|
38
|
-
|
39
|
-
expect(
|
56
|
+
it "Can call compile method with options" do
|
57
|
+
ctx, js = compile "service1", "config2"
|
58
|
+
expect(js).to include("23rntoheuh3nthoeunthn23th");
|
40
59
|
end
|
41
60
|
end
|
@@ -40,6 +40,13 @@ RSpec.describe "User compiler" do
|
|
40
40
|
expect(actions).to eq(1)
|
41
41
|
end
|
42
42
|
|
43
|
+
it "Can compile a controller and contain an __init__ function" do
|
44
|
+
ctx = compile "controller0"
|
45
|
+
actions = ctx.eval "ctable.my_controller.__init__"
|
46
|
+
expect(actions).not_to eq(nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
|
43
50
|
it "Can compile a controller with an action that contains an on_entry" do
|
44
51
|
ctx = compile "controller0"
|
45
52
|
on_entry = ctx.eval "ctable.my_controller.actions.my_action.on_entry"
|
@@ -52,7 +59,6 @@ RSpec.describe "User compiler" do
|
|
52
59
|
expect(on_entry).to eq("my_controller")
|
53
60
|
end
|
54
61
|
|
55
|
-
|
56
62
|
it "Can compile a controller with an action that contains an event that responds to hello" do
|
57
63
|
ctx = compile "controller0"
|
58
64
|
hello_event_function = ctx.eval "ctable.my_controller.actions.my_action.handlers.hello"
|
@@ -0,0 +1,106 @@
|
|
1
|
+
Dir.chdir File.join File.dirname(__FILE__), '../../../'
|
2
|
+
require './spec/env/iface.rb'
|
3
|
+
require './spec/lib/helpers.rb'
|
4
|
+
require './spec/lib/io_extensions.rb'
|
5
|
+
require './spec/lib/rspec_extensions.rb'
|
6
|
+
|
7
|
+
RSpec.describe "iface:driver:persist" do
|
8
|
+
module_dep "persist"
|
9
|
+
include_context "iface:driver"
|
10
|
+
|
11
|
+
it "Can receive persist API messages without crashing" do
|
12
|
+
#Disk is scheduling class 2
|
13
|
+
@pipe.puts [[2, 3, "if_per_set", "my_ns", "my_key", "my_value"]].to_json
|
14
|
+
@pipe.puts [[2, 3, "if_per_get", "session", "my_ns", "my_key"]].to_json
|
15
|
+
@pipe.puts [[2, 2, "if_per_del", "my_ns", "my_key"]].to_json
|
16
|
+
@pipe.puts [[2, 1, "if_per_del_ns", "my_ns"]].to_json
|
17
|
+
|
18
|
+
#These are from the get requests
|
19
|
+
@pipe.readline_timeout
|
20
|
+
|
21
|
+
@pipe.puts [[0, 0, "ping"]].to_json;
|
22
|
+
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([0, "pong"], 5.seconds)
|
23
|
+
end
|
24
|
+
|
25
|
+
it "Can set a persist, and then synchronously get" do
|
26
|
+
key = SecureRandom.hex
|
27
|
+
value = SecureRandom.hex
|
28
|
+
|
29
|
+
#Disk is scheduling class 2
|
30
|
+
@pipe.puts [[2, 3, "if_per_set", "my_ns", key, value]].to_json
|
31
|
+
restart_driver_but_persist
|
32
|
+
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key]].to_json
|
33
|
+
|
34
|
+
#Expect a response
|
35
|
+
res = [2, "int_per_get_res", "session", value]
|
36
|
+
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
37
|
+
end
|
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
|
55
|
+
key = SecureRandom.hex
|
56
|
+
value = SecureRandom.hex
|
57
|
+
|
58
|
+
#Disk is scheduling class 2
|
59
|
+
@pipe.puts [[2, 3, "if_per_set", "my_ns", key, value]].to_json
|
60
|
+
@pipe.puts [[2, 2, "if_per_del", "my_ns", key]].to_json
|
61
|
+
restart_driver_but_persist
|
62
|
+
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key]].to_json
|
63
|
+
|
64
|
+
#Expect a response
|
65
|
+
res = [2, "int_per_get_res", "session", nil]
|
66
|
+
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "Can set two persists, delete one key, and then synchronously get" do
|
70
|
+
key = SecureRandom.hex
|
71
|
+
key2 = SecureRandom.hex
|
72
|
+
value = SecureRandom.hex
|
73
|
+
value2 = SecureRandom.hex
|
74
|
+
|
75
|
+
#Disk is scheduling class 2
|
76
|
+
@pipe.puts [[2, 3, "if_per_set", "my_ns", key, value]].to_json
|
77
|
+
@pipe.puts [[2, 3, "if_per_set", "my_ns", key2, value2]].to_json
|
78
|
+
@pipe.puts [[2, 2, "if_per_del", "my_ns", key]].to_json
|
79
|
+
restart_driver_but_persist
|
80
|
+
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key]].to_json
|
81
|
+
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key2]].to_json
|
82
|
+
|
83
|
+
#Results for first key
|
84
|
+
res = [2, "int_per_get_res", "session", nil]
|
85
|
+
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
86
|
+
|
87
|
+
#Expect a response
|
88
|
+
res = [2, "int_per_get_res", "session", value2]
|
89
|
+
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "Can set a persist, delete the key via ns, and then synchronously get" do
|
93
|
+
key = SecureRandom.hex
|
94
|
+
value = SecureRandom.hex
|
95
|
+
|
96
|
+
#Disk is scheduling class 2
|
97
|
+
@pipe.puts [[2, 3, "if_per_set", "my_ns", key, value]].to_json
|
98
|
+
@pipe.puts [[2, 1, "if_per_del_ns", "my_ns"]].to_json
|
99
|
+
restart_driver_but_persist
|
100
|
+
@pipe.puts [[0, 3, "if_per_get", "session", "my_ns", key]].to_json
|
101
|
+
|
102
|
+
#Expect a response
|
103
|
+
res = [2, "int_per_get_res", "session", nil]
|
104
|
+
expect(@pipe).to readline_and_equal_json_x_within_y_seconds(res, 5.seconds)
|
105
|
+
end
|
106
|
+
end
|
@@ -28,4 +28,9 @@ RSpec.describe "iface:driver:pipe_spec" do
|
|
28
28
|
|
29
29
|
expect(pid).to die_within(6.seconds)
|
30
30
|
end
|
31
|
+
|
32
|
+
it "does have the ability to receive a RESTART command" do
|
33
|
+
@pipe.puts "RESTART"
|
34
|
+
expect(@pipe).to readline_and_equal_x_within_y_seconds("RESTART OK", 5.seconds)
|
35
|
+
end
|
31
36
|
end
|
@@ -70,7 +70,8 @@ RSpec.describe "iface:kern:ping_spec" do
|
|
70
70
|
"net" => 1,
|
71
71
|
"disk" => 2,
|
72
72
|
"cpu" => 3,
|
73
|
-
"gpu" => 4
|
73
|
+
"gpu" => 4,
|
74
|
+
"async" => 5
|
74
75
|
}
|
75
76
|
|
76
77
|
queue_name_to_index.each do |name, index|
|
@@ -78,7 +79,7 @@ RSpec.describe "iface:kern:ping_spec" do
|
|
78
79
|
#Don't redo last one because it's part of the first term (queue_name_b)
|
79
80
|
unless index == queue_name_to_index.count-1
|
80
81
|
queue_name_a = name
|
81
|
-
queue_name_b = @last_queue_name || "
|
82
|
+
queue_name_b = @last_queue_name || "async"
|
82
83
|
index_a = index
|
83
84
|
index_b = queue_name_to_index[queue_name_b]
|
84
85
|
@pipe.puts [1, "ping3", queue_name_a, 1, "ping3", queue_name_a, 1, "ping3", queue_name_b].to_json
|
@@ -104,7 +105,7 @@ RSpec.describe "iface:kern:ping_spec" do
|
|
104
105
|
queue_name_to_index.each do |name, index|
|
105
106
|
it "supports ping-over-commit" do
|
106
107
|
#Main queue always queues all
|
107
|
-
if name != "main"
|
108
|
+
if name != "main" and name != "async" #main and async don't have scheduling
|
108
109
|
@pipe.puts ([1, "ping4", name]*6).to_json
|
109
110
|
expect(@pipe).to readline_and_equal_json_x_within_y_seconds([[index, *[0, "pong4"]*5]], 6.seconds)
|
110
111
|
@pipe.puts ([1, "ping4", name]).to_json
|
File without changes
|
@@ -0,0 +1,24 @@
|
|
1
|
+
service :my_service do
|
2
|
+
on_wakeup %{
|
3
|
+
on_wakeup_called = true;
|
4
|
+
}
|
5
|
+
|
6
|
+
on_sleep %{
|
7
|
+
on_sleep_called = true;
|
8
|
+
}
|
9
|
+
|
10
|
+
on_connect %{
|
11
|
+
on_connect_called = true;
|
12
|
+
}
|
13
|
+
|
14
|
+
on_disconnect %{
|
15
|
+
on_disconnect_called = true;
|
16
|
+
}
|
17
|
+
|
18
|
+
every 1.seconds, %{
|
19
|
+
for (var i = 0; i < Object.keys(sessions).length; ++i) {
|
20
|
+
var bp = Object.keys(sessions)[i];
|
21
|
+
int_event(bp, "ping", {});
|
22
|
+
}
|
23
|
+
}
|
24
|
+
end
|