flok 0.0.36 → 0.0.38
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/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
|