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
data/lib/flok/platform.rb
CHANGED
@@ -12,17 +12,40 @@ module Flok
|
|
12
12
|
end
|
13
13
|
|
14
14
|
#Get a list of modules for a particular environment for a platform
|
15
|
-
def self.mods
|
15
|
+
def self.mods environment
|
16
16
|
#Create array that looks like a javascript array with single quotes
|
17
|
-
mods = self.config_yml(
|
17
|
+
mods = self.config_yml(environment)['mods']
|
18
18
|
end
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
def self.defines environment
|
21
|
+
#Just converting an array into a hash of true values for easier lookup
|
22
|
+
hash = {}
|
23
|
+
defines_arr = self.config_yml(environment)['defines']
|
24
|
+
if defines_arr
|
25
|
+
defines_arr.each do |e|
|
26
|
+
hash[e] = true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
return hash
|
31
|
+
end
|
32
|
+
|
33
|
+
#Get all config.yml information for a config_yml file based on FLOK_CONFIG
|
34
|
+
def self.config_yml environment
|
35
|
+
#Get the config.yml path
|
36
|
+
config_yml_path = ENV['FLOK_CONFIG']
|
37
|
+
if config_yml_path
|
38
|
+
raise "You didn't pass a FLOK_CONFIG variable for the config.yml" unless config_yml_path
|
39
|
+
raise "The FLOK_CONFIG given: #{config_yml_path.inspect} does not contain a file (config.yml)" unless File.exists?(config_yml_path)
|
40
|
+
else
|
41
|
+
#$stderr.puts "Warning: You didn't specify FLOK_CONFIG, Using default config of ./app/drivers/#{ENV['PLATFORM']}/config.yml"
|
42
|
+
config_yml_path = "./app/drivers/#{ENV['PLATFORM']}/config.yml"
|
43
|
+
end
|
44
|
+
|
45
|
+
driver_config = YAML.load_file(config_yml_path)
|
24
46
|
return driver_config[environment]
|
25
47
|
end
|
48
|
+
|
26
49
|
end
|
27
50
|
|
28
51
|
#Alias
|
@@ -0,0 +1 @@
|
|
1
|
+
#Your services should go into this file, you may name your files anything and delete this file
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= File.read("./app/drivers/ENV['PLATFORM']/")
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= File.read(File.join(File.dirname(__FILE__), "../../../app/drivers/#{ENV['PLATFORM']}/config.yml")) %>
|
@@ -0,0 +1 @@
|
|
1
|
+
#Services
|
@@ -1,13 +1,82 @@
|
|
1
1
|
<% @services.each do |s| %>
|
2
|
-
|
3
|
-
|
4
|
-
<%= s.
|
5
|
-
//////////////////////////////////////////////////
|
2
|
+
//Variables
|
3
|
+
var <%= s.name %>_sessions = {}; //Currently connected clients
|
4
|
+
var <%= s.name %>_n_sessions = 0; //Number of sessions
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
//Static global
|
7
|
+
<%= s._global %>
|
8
|
+
|
9
|
+
//Start of <%= s.name %> on_wakeup
|
10
|
+
function <%= s.name %>_on_wakeup() {
|
11
|
+
//Timer related
|
12
|
+
/////////////////////////////////////////////////////////////////////////////////////
|
13
|
+
//The timer base pointer for incomming callout events
|
14
|
+
<%= s.name %>_timer_bp = tels(1);
|
15
|
+
reg_evt(<%= s.name %>_timer_bp, <%= s.name %>_handle_timer_events);
|
16
|
+
|
17
|
+
//Tell the timer to notify our timer event handlers
|
18
|
+
//The name is randomly generated for each one
|
19
|
+
<% s.every_handlers.each do |h| %>
|
20
|
+
reg_interval(<%= s.name %>_timer_bp, '<%= h[:name] %>', <%= h[:ticks] %>);
|
21
|
+
<% end %>
|
22
|
+
/////////////////////////////////////////////////////////////////////////////////////
|
23
|
+
|
24
|
+
<%= s._on_wakeup %>
|
25
|
+
}
|
26
|
+
|
27
|
+
function <%= s.name %>_on_sleep() {
|
28
|
+
//Do not receive anymore timer events
|
29
|
+
dereg_evt(<%= s.name %>_timer_bp);
|
30
|
+
|
31
|
+
<%= s._on_sleep %>
|
32
|
+
}
|
33
|
+
|
34
|
+
function <%= s.name %>_on_connect(bp) {
|
35
|
+
var sessions = <%= s.name %>_sessions;
|
36
|
+
<%= s.name %>_n_sessions += 1;
|
37
|
+
|
38
|
+
//First connection
|
39
|
+
if (<%= s.name %>_n_sessions === 1) {
|
40
|
+
<%= s.name %>_on_wakeup();
|
41
|
+
}
|
42
|
+
|
43
|
+
sessions[bp] = true;
|
44
|
+
<%= s._on_connect %>
|
45
|
+
}
|
46
|
+
|
47
|
+
function <%= s.name %>_on_disconnect(bp) {
|
48
|
+
var sessions = <%= s.name %>_sessions;
|
49
|
+
|
50
|
+
<%= s.name %>_n_sessions -= 1;
|
51
|
+
delete sessions[bp];
|
52
|
+
|
53
|
+
<%= s._on_disconnect %>
|
54
|
+
|
55
|
+
//No more connections
|
56
|
+
if (<%= s.name %>_n_sessions === 0) {
|
57
|
+
<%= s.name %>_on_sleep();
|
58
|
+
}
|
59
|
+
|
60
|
+
}
|
61
|
+
|
62
|
+
//'Event' handlers
|
63
|
+
<% s.event_handlers.each do |h| %>
|
64
|
+
function <%= s.name %>_on_<%= h[:name] %>(bp, params) {
|
65
|
+
var sessions = <%= s.name %>_sessions;
|
66
|
+
<%= h[:str] %>
|
67
|
+
}
|
68
|
+
<% end %>
|
69
|
+
|
70
|
+
//Timer receivers
|
71
|
+
/////////////////////////////////////////////////////////////////////
|
72
|
+
function <%= s.name %>_handle_timer_events(ep, ename, info) {
|
73
|
+
var sessions = <%= s.name %>_sessions;
|
74
|
+
|
75
|
+
<% s.every_handlers.each do |h| %>
|
76
|
+
if (ename === '<%= h[:name] %>') {
|
77
|
+
<%= h[:str] %>
|
78
|
+
}
|
79
|
+
<% end %>
|
11
80
|
}
|
12
|
-
|
81
|
+
/////////////////////////////////////////////////////////////////////
|
13
82
|
<% end %>
|
@@ -1,22 +1,28 @@
|
|
1
1
|
#Compile a controller ruby file into a javascript string
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/core_ext/numeric'
|
2
4
|
|
3
5
|
require 'erb'
|
4
6
|
module Flok
|
5
7
|
module ServicesCompiler
|
6
8
|
#Compile a ruby file containing flok controller definitions (from the services)
|
7
|
-
|
9
|
+
#The config is outlined in the documentation under docs/services.md
|
10
|
+
def self.compile rb_src, rb_config
|
11
|
+
#Execute the configuration file first
|
12
|
+
config_context = ServicesCompilerConfigContext.new
|
13
|
+
config_context.instance_eval(rb_config, __FILE__, __LINE__)
|
14
|
+
|
8
15
|
#Execute code in this context, the context will hold all the information
|
9
16
|
#that is used to then generate code
|
10
|
-
context = ServicesCompilerContext.new
|
17
|
+
context = ServicesCompilerContext.new(config_context)
|
11
18
|
context.instance_eval(rb_src, __FILE__, __LINE__)
|
19
|
+
context.ready
|
12
20
|
|
13
21
|
@src = ""
|
14
22
|
services_erb = File.read File.join(File.dirname(__FILE__), "./service_compiler_templates/services.js.erb")
|
15
23
|
services_renderer = ERB.new(services_erb)
|
16
24
|
@src << services_renderer.result(context.get_binding)
|
17
25
|
|
18
|
-
#puts @src
|
19
|
-
|
20
26
|
return @src
|
21
27
|
end
|
22
28
|
end
|
@@ -24,29 +30,71 @@ end
|
|
24
30
|
|
25
31
|
#Compiler executes all rb code inside this context
|
26
32
|
module Flok
|
27
|
-
class
|
28
|
-
|
33
|
+
class ServicesCompilerConfigContext
|
34
|
+
#Each service instance contains a :instance_name and :class
|
35
|
+
attr_accessor :service_instances
|
29
36
|
|
30
37
|
def initialize
|
38
|
+
@service_instances = []
|
39
|
+
end
|
40
|
+
|
41
|
+
def service_instance instance_name, name, options={}
|
42
|
+
@service_instances.push({
|
43
|
+
:instance_name => instance_name,
|
44
|
+
:class => name,
|
45
|
+
:options => options
|
46
|
+
})
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
class ServicesCompilerContext
|
51
|
+
attr_accessor :services, :config
|
52
|
+
|
53
|
+
def initialize config_context
|
54
|
+
@config = config_context
|
55
|
+
|
56
|
+
#A hash containing the 'class' name of the service to a block that can be used with Service.new
|
57
|
+
@_services = {}
|
58
|
+
|
31
59
|
@services = []
|
32
60
|
end
|
33
61
|
|
62
|
+
def ready
|
63
|
+
#Create an array from the service_instances where each element in the array is the full code of the service
|
64
|
+
@config.service_instances.each do |i|
|
65
|
+
#Get the instance name and class name of the service, normally defined in a ./config/services.rb file
|
66
|
+
sname = i[:instance_name]
|
67
|
+
sclass = i[:class]
|
68
|
+
soptions = i[:options]
|
69
|
+
|
70
|
+
sblock = @_services[sclass]
|
71
|
+
raise "No service found for service_name: #{sclass.inspect} when trying to create service with instance name #{sname.inspect}. @_services contained: #{@_services.inspect} \n@config.service_instances contained: #{@config.service_instances.inspect}" unless sblock
|
72
|
+
service = Service.new(sname, soptions)
|
73
|
+
service.instance_eval(&sblock)
|
74
|
+
@services << service
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
34
78
|
def get_binding
|
35
79
|
return binding
|
36
80
|
end
|
37
81
|
|
38
82
|
def service name, &block
|
39
|
-
@
|
83
|
+
@_services[name] = block
|
40
84
|
end
|
41
85
|
end
|
42
86
|
|
43
87
|
class Service
|
44
|
-
attr_accessor :name
|
45
|
-
def initialize name,
|
88
|
+
attr_accessor :name, :_global, :_on_wakeup, :_on_sleep, :_on_connect, :_on_disconnect, :event_handlers, :every_handlers, :options
|
89
|
+
def initialize name, options
|
46
90
|
@name = name
|
47
|
-
@
|
91
|
+
@options = options
|
92
|
+
|
93
|
+
#These are the 'on' handlers
|
94
|
+
@event_handlers = []
|
48
95
|
|
49
|
-
|
96
|
+
#These are for every 5.seconds
|
97
|
+
@every_handlers = []
|
50
98
|
end
|
51
99
|
|
52
100
|
def get_on_init
|
@@ -57,18 +105,67 @@ module Flok
|
|
57
105
|
return @on_request
|
58
106
|
end
|
59
107
|
|
60
|
-
def
|
61
|
-
|
108
|
+
def global(str)
|
109
|
+
render = ERB.new(str)
|
110
|
+
str = render.result(binding)
|
111
|
+
@_global = str
|
112
|
+
end
|
113
|
+
|
114
|
+
def on_wakeup(str)
|
115
|
+
render = ERB.new(str)
|
116
|
+
str = render.result(binding)
|
117
|
+
@_on_wakeup = str
|
118
|
+
end
|
119
|
+
|
120
|
+
def on_sleep(str)
|
121
|
+
render = ERB.new(str)
|
122
|
+
str = render.result(binding)
|
123
|
+
|
124
|
+
@_on_sleep = str
|
125
|
+
end
|
126
|
+
|
127
|
+
def on_connect(str)
|
128
|
+
render = ERB.new(str)
|
129
|
+
str = render.result(binding)
|
130
|
+
@_on_connect = str
|
62
131
|
end
|
63
132
|
|
64
|
-
def
|
65
|
-
|
133
|
+
def on_disconnect(str)
|
134
|
+
render = ERB.new(str)
|
135
|
+
str = render.result(binding)
|
136
|
+
@_on_disconnect = str
|
137
|
+
end
|
138
|
+
|
139
|
+
def on(name, str)
|
140
|
+
render = ERB.new(str)
|
141
|
+
str = render.result(binding)
|
142
|
+
|
143
|
+
@event_handlers << {
|
144
|
+
:name => name,
|
145
|
+
:str => str
|
146
|
+
}
|
147
|
+
end
|
148
|
+
|
149
|
+
def every(seconds, str)
|
150
|
+
@every_handlers << {
|
151
|
+
:name => "#{seconds}_sec_#{SecureRandom.hex[0..6]}",
|
152
|
+
:ticks => seconds*4,
|
153
|
+
:str => str
|
154
|
+
}
|
155
|
+
end
|
156
|
+
|
157
|
+
def type str
|
158
|
+
@_type = str.to_s
|
159
|
+
unless ["daemon", "agent"].include? @_type
|
160
|
+
raise "You gave a type for the service, #{@_type.inspect} but this wasn't a valid type of service. Should be \
|
161
|
+
either 'daemon' or 'agent'"
|
162
|
+
end
|
66
163
|
end
|
67
164
|
|
68
165
|
def macro text
|
69
|
-
out = StringIO.new
|
166
|
+
#out = StringIO.new
|
70
167
|
|
71
|
-
text.split("\n").each do |l|
|
168
|
+
#text.split("\n").each do |l|
|
72
169
|
##Request(vc_name, spot_name, context) macro
|
73
170
|
#if l =~ /Request/
|
74
171
|
#l.strip!
|
@@ -84,11 +181,11 @@ module Flok
|
|
84
181
|
#out << %{
|
85
182
|
#}
|
86
183
|
#else
|
87
|
-
out.puts l
|
184
|
+
#out.puts l
|
88
185
|
#end
|
89
|
-
end
|
186
|
+
#end
|
90
187
|
|
91
|
-
return out.string
|
188
|
+
#return out.string
|
92
189
|
end
|
93
190
|
end
|
94
191
|
end
|
data/lib/flok/user_compiler.rb
CHANGED
@@ -15,8 +15,6 @@ module Flok
|
|
15
15
|
ctable_renderer = ERB.new(ctable_erb)
|
16
16
|
@src << ctable_renderer.result(context.get_binding)
|
17
17
|
|
18
|
-
#puts @src
|
19
|
-
|
20
18
|
return @src
|
21
19
|
end
|
22
20
|
end
|
@@ -194,6 +192,9 @@ module Flok
|
|
194
192
|
//Free +1 because that will be the 'main' view
|
195
193
|
main_q.push([1, "if_free_view", embeds[i][j]+1]);
|
196
194
|
|
195
|
+
//Call dealloc on the controller
|
196
|
+
tel_deref(embeds[i][j]).cte.__dealloc__(embeds[i][j]);
|
197
|
+
|
197
198
|
<% if @debug %>
|
198
199
|
var vp = embeds[i][j]+1;
|
199
200
|
//First locate spot this view belongs to in reverse hash
|
@@ -228,7 +229,7 @@ module Flok
|
|
228
229
|
}]);
|
229
230
|
}
|
230
231
|
out.puts res
|
231
|
-
#Request(
|
232
|
+
#Request(service_instance_name, ename, info)
|
232
233
|
elsif l =~ /Request/
|
233
234
|
l.strip!
|
234
235
|
l.gsub!(/Request\(/, "")
|
@@ -237,11 +238,13 @@ module Flok
|
|
237
238
|
o = l.split(",").map{|e| e.strip}
|
238
239
|
|
239
240
|
name = o.shift.gsub(/"/, "")
|
241
|
+
ename = o.shift.gsub(/"/, "")
|
240
242
|
info = o.shift.gsub(/"/, "")
|
241
|
-
|
243
|
+
|
244
|
+
raise "You tried to Request the service #{name.inspect}, but you haven't added that to your 'services' for this controller (#{@controller.name.inspect})" unless @controller._services.include? name
|
242
245
|
|
243
246
|
out << %{
|
244
|
-
|
247
|
+
#{name}_on_#{ename}(__base__, #{info});
|
245
248
|
}
|
246
249
|
else
|
247
250
|
out.puts l
|
@@ -265,12 +268,13 @@ module Flok
|
|
265
268
|
end
|
266
269
|
|
267
270
|
class UserCompilerController
|
268
|
-
attr_accessor :name, :spots, :macros
|
271
|
+
attr_accessor :name, :spots, :macros, :_services
|
269
272
|
def initialize name, ctx, &block
|
270
273
|
@name = name
|
271
274
|
@ctx = ctx
|
272
275
|
@spots = ['main']
|
273
276
|
@macros = {}
|
277
|
+
@_services = []
|
274
278
|
|
275
279
|
self.instance_eval(&block)
|
276
280
|
end
|
@@ -285,6 +289,10 @@ module Flok
|
|
285
289
|
@spots += spots
|
286
290
|
end
|
287
291
|
|
292
|
+
def services *instance_names
|
293
|
+
@_services = instance_names.map{|e| e.to_s}
|
294
|
+
end
|
295
|
+
|
288
296
|
#Pass through action
|
289
297
|
def action name, &block
|
290
298
|
@ctx.action self, name, &block
|
@@ -1,6 +1,16 @@
|
|
1
1
|
ctable = {
|
2
2
|
<% @controllers.each do |c| %>
|
3
3
|
<%= c.name %>: {
|
4
|
+
__init__: function(__base__) {
|
5
|
+
<% c._services.each do |s| %>
|
6
|
+
<%= s %>_on_connect(__base__);
|
7
|
+
<% end %>
|
8
|
+
},
|
9
|
+
__dealloc__: function(__base__) {
|
10
|
+
<% c._services.each do |s| %>
|
11
|
+
<%= s %>_on_disconnect(__base__);
|
12
|
+
<% end %>
|
13
|
+
},
|
4
14
|
name: '<%= c.name %>',
|
5
15
|
root_view: '<%= c.name %>',
|
6
16
|
spots: <%= c.spots.to_json %>,
|
data/lib/flok/version.rb
CHANGED