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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +1 -0
  3. data/app/drivers/chrome/build_context.rb +1 -1
  4. data/app/drivers/chrome/config.yml +10 -0
  5. data/app/drivers/chrome/pipe.rb +24 -1
  6. data/app/drivers/chrome/src/persist.js +29 -0
  7. data/app/drivers/chrome/src/sockio.js +3 -1
  8. data/app/drivers/chrome/src/vendor/store2.js +3 -0
  9. data/app/kern/callout.js +55 -0
  10. data/app/kern/controller.js +3 -0
  11. data/app/kern/crc32.js +22 -0
  12. data/app/kern/dispatch.js +16 -0
  13. data/app/kern/mod/event.js +3 -0
  14. data/app/kern/mod/persist.js +1 -0
  15. data/app/kern/mod/timer.js +5 -0
  16. data/app/kern/pagers/mem_pager.js +2 -0
  17. data/app/kern/pagers/sockio_pager.js +66 -0
  18. data/app/kern/pagers/spec0.js +35 -0
  19. data/app/kern/pagers/spec1.js +24 -0
  20. data/app/kern/pagers/spec2.js +31 -0
  21. data/app/kern/services/test.rb +7 -0
  22. data/app/kern/services/vm.rb +141 -0
  23. data/app/kern/spec_helper.js +5 -0
  24. data/bin/flok +27 -5
  25. data/docs/callout.md +8 -0
  26. data/docs/client_api.md +1 -1
  27. data/docs/compilation.md +14 -8
  28. data/docs/controllers.md +2 -1
  29. data/docs/datatypes.md +3 -1
  30. data/docs/environmentals.md +6 -0
  31. data/docs/interactive.md +6 -1
  32. data/docs/kernel_api.md +3 -0
  33. data/docs/mod/event.md +5 -1
  34. data/docs/mod/persist.md +14 -31
  35. data/docs/mod/timer.md +4 -2
  36. data/docs/project.md +16 -5
  37. data/docs/scheduling.md +1 -0
  38. data/docs/services.md +141 -56
  39. data/docs/services/vm.md +128 -0
  40. data/docs/services/vm/pagers.md +46 -0
  41. data/lib/flok/build.rb +11 -16
  42. data/lib/flok/platform.rb +29 -6
  43. data/lib/flok/project_template/app/scripts/script.js +3 -0
  44. data/lib/flok/project_template/app/services/service.rb +1 -0
  45. data/lib/flok/project_template/config/config.yml +1 -0
  46. data/lib/flok/project_template/config/platforms/chrome/config.yml +1 -0
  47. data/lib/flok/project_template/config/services.rb +1 -0
  48. data/lib/flok/service_compiler_templates/services.js.erb +78 -9
  49. data/lib/flok/services_compiler.rb +117 -20
  50. data/lib/flok/user_compiler.rb +14 -6
  51. data/lib/flok/user_compiler_templates/ctable.js.erb +10 -0
  52. data/lib/flok/version.rb +1 -1
  53. data/spec/env/etc.rb +1 -1
  54. data/spec/env/global.rb +2 -0
  55. data/spec/env/iface.rb +20 -4
  56. data/spec/env/kern.rb +8 -3
  57. data/spec/etc/cli_spec.rb +319 -165
  58. data/spec/etc/lib/assets/config.yml +3 -0
  59. data/spec/etc/lib/platform_spec.rb +14 -10
  60. data/spec/etc/lib/project_spec.rb +22 -0
  61. data/spec/etc/service_compiler/config0.rb +1 -0
  62. data/spec/etc/service_compiler/config1.rb +1 -0
  63. data/spec/etc/service_compiler/config2.rb +3 -0
  64. data/spec/etc/service_compiler/service0.rb +22 -6
  65. data/spec/etc/service_compiler/service1.rb +26 -0
  66. data/spec/etc/service_compiler/service_bad_type.rb +20 -0
  67. data/spec/etc/services_compiler_spec.rb +35 -16
  68. data/spec/etc/user_compiler/data.js +2 -0
  69. data/spec/etc/user_compiler_spec.rb +7 -1
  70. data/spec/iface/driver/persist_spec.rb +106 -0
  71. data/spec/iface/driver/pipe_spec.rb +5 -0
  72. data/spec/iface/kern/ping_spec.rb +4 -3
  73. data/spec/kern/assets/blank.rb +0 -0
  74. data/spec/kern/assets/service0.rb +24 -0
  75. data/spec/kern/assets/service1.rb +22 -0
  76. data/spec/kern/assets/service2.rb +27 -0
  77. data/spec/kern/assets/service_config0.rb +2 -0
  78. data/spec/kern/assets/service_config1.rb +2 -0
  79. data/spec/kern/assets/service_controller0.rb +13 -0
  80. data/spec/kern/assets/service_controller1.rb +32 -0
  81. data/spec/kern/assets/service_controller2.rb +38 -0
  82. data/spec/kern/assets/service_controller3.rb +38 -0
  83. data/spec/kern/assets/vm/config0.rb +2 -0
  84. data/spec/kern/assets/vm/config1.rb +12 -0
  85. data/spec/kern/assets/vm/config2.rb +12 -0
  86. data/spec/kern/assets/vm/config3.rb +12 -0
  87. data/spec/kern/assets/vm/controller0.rb +8 -0
  88. data/spec/kern/assets/vm/controller1.rb +18 -0
  89. data/spec/kern/assets/vm/controller2.rb +18 -0
  90. data/spec/kern/assets/vm/controller3.rb +20 -0
  91. data/spec/kern/assets/vm/controller4.rb +22 -0
  92. data/spec/kern/assets/vm/controller5.rb +22 -0
  93. data/spec/kern/assets/vm/controller6.rb +21 -0
  94. data/spec/kern/assets/vm/service0.rb +24 -0
  95. data/spec/kern/assets/vm/service_controller0.rb +7 -0
  96. data/spec/kern/callout_spec.rb +153 -0
  97. data/spec/kern/functions_spec.rb +29 -0
  98. data/spec/kern/service_controller_spec.rb +213 -0
  99. data/spec/kern/vm_service_spec.rb +195 -0
  100. metadata +98 -12
  101. data/app/kern/services/rest.rb +0 -310
  102. data/app/kern/services/timer.rb +0 -30
  103. data/docs/services/timer.md +0 -21
  104. data/spec/kern/assets/rest_service.rb +0 -20
  105. data/spec/kern/assets/timer_service.rb +0 -19
  106. 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 platform, environment
15
+ def self.mods environment
16
16
  #Create array that looks like a javascript array with single quotes
17
- mods = self.config_yml(platform, environment)['mods']
17
+ mods = self.config_yml(environment)['mods']
18
18
  end
19
19
 
20
- #Get all config.yml information for a platform
21
- def self.config_yml platform, environment
22
- driver_config = YAML.load_file("./app/drivers/#{platform}/config.yml")
23
- raise "No config.yml found in your 'platform: #{platform}' driver" unless driver_config
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,3 @@
1
+ //You shouldn't have many scripts in here, but any javascript files in ./app/scripts/*.js could be
2
+ //used if you need access to (small amounts) of static data, etc. These files are merged with the final
3
+ //kernel binary.
@@ -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
- //Start of <%= s.name %> on_init
4
- <%= s.get_on_init %>
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
- //Start of <%= s.name %> on_request
9
- function service_<%= s.name %>_req(info, ep, ename) {
10
- <%= s.get_on_request %>
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
- def self.compile rb_src
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 ServicesCompilerContext
28
- attr_accessor :services
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
- @services << Service.new(name, &block)
83
+ @_services[name] = block
40
84
  end
41
85
  end
42
86
 
43
87
  class Service
44
- attr_accessor :name
45
- def initialize name, &block
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
- @block = block
91
+ @options = options
92
+
93
+ #These are the 'on' handlers
94
+ @event_handlers = []
48
95
 
49
- self.instance_eval(&block)
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 on_init str
61
- @on_init = macro(str)
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 on_request str
65
- @on_request = macro(str)
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
@@ -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(service_name, payload, event_name_cb)
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
- event_name = o.shift
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
- service_#{name}_req(#{info}, __base__, #{event_name});
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
@@ -1,3 +1,3 @@
1
1
  module Flok
2
- VERSION = "0.0.36"
2
+ VERSION = "0.0.38"
3
3
  end