flok 0.0.79 → 0.0.80

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: aca1d7de35bb76f6ca3adf9142e6ba509161a5de
4
- data.tar.gz: 07984726091817ae868f9a864ad38108510f26e5
3
+ metadata.gz: 0211bf5635601e2e799ddd564e3612c8a02e1354
4
+ data.tar.gz: 45aa0d364ed30d8a2d01e0ca2d4cb2abcd2ab61b
5
5
  SHA512:
6
- metadata.gz: 5eec59b970ba96dda10d87394323839c35ed7dba250be6c250d03c289c4e1ee7f0a2f909cd09c9da1c2137d2d6da8cfbd1e4c1d8ff4afa4d18f1a00ba9541252
7
- data.tar.gz: 57f42e576fe8cb437f5d01df8e07dda29df8093d248abb90d3aedfaa7284b52904a9881f6feb47903720df2a247f7e75610fdbfd6908dc496d3186dea7f910a4
6
+ metadata.gz: f47cfbb76f1f5aa170fb8c38963c9df5a2d0179ef617d90c4f7981b733097cf26e6cc4c26c9a74881c1806c40a73a6935d0063ca489c7102630e767e63f59cdd
7
+ data.tar.gz: 2ab9e84d9daeccf7f11877a4443e8f36a4fcd3ede44cf0cc0ee7ee5a3413c946e9b20d694ee36c131633d8a3c568cc720d798064ca2a4817c441c44f0cb03d63
@@ -6,6 +6,7 @@
6
6
  pg_spec<%= i %>_unwatchlist = [];
7
7
  pg_spec<%= i %>_init_params = {ns: ns, options: options};
8
8
  pg_spec<%= i %>_ns = ns;
9
+ pg_spec<%= i %>_sync_requests = [];
9
10
  }
10
11
 
11
12
  function pg_spec<%= i %>_watch(id, page) {
@@ -21,5 +22,9 @@
21
22
  vm_cache_write(pg_spec<%= i %>_ns, page);
22
23
  vm_transaction_end();
23
24
  }
25
+
26
+ function pg_spec<%= i %>_sync(page_id) {
27
+ pg_spec<%= i %>_sync_requests.push(page_id);
28
+ }
24
29
  <% end %>
25
30
  <% end %>
@@ -1,5 +1,7 @@
1
1
  service :vm do
2
2
  global %{
3
+ //Some of the shared datatypes
4
+ ////////////////////////////////////////////////////////////////////////////////////////////
3
5
  //Cache contains a blank hash for each namespace
4
6
  vm_cache = {
5
7
  <% @options[:pagers].each do |p| %>
@@ -13,8 +15,6 @@ service :vm do
13
15
  <% end %>
14
16
  };
15
17
 
16
- //See 'Datatypes & Structures' in ./docs/services/vm.md
17
- ////////////////////////////////////////////////////////////////////////////////////////////
18
18
  vm_bp_to_nmap = {};
19
19
  vm_pager_waiting_read = {
20
20
  <% @options[:pagers].each do |p| %>
@@ -29,6 +29,7 @@ service :vm do
29
29
  <%= p[:namespace] %>: {},
30
30
  <% end %>
31
31
  };
32
+
32
33
  ////////////////////////////////////////////////////////////////////////////////////////////
33
34
 
34
35
  //Cache
@@ -505,6 +506,58 @@ service :vm do
505
506
  }
506
507
  }
507
508
  ///////////////////////////////////////////////////////////////////////////
509
+
510
+ //vm unsynced
511
+ ///////////////////////////////////////////////////////////////////////////
512
+ //Unsynced page ids to integer vm_unsynced[bp][page_id] = '0' or '1'
513
+ //where 0 is freshly added and ignored on the first pass of the daemon
514
+ vm_unsynced = {
515
+ <% @options[:pagers].each do |p| %>
516
+ <%= p[:namespace] %>: {},
517
+ <% end %>
518
+ };
519
+
520
+ function vm_pg_mark_needs_sync(ns, page_id) {
521
+ //Add to list
522
+ vm_unsynced[ns][page_id] = 0;
523
+
524
+ //Notify pager immediately (daemon will not notify pager on first tick to avoid calling pager's sync to soon)
525
+ <% @options[:pagers].each do |p| %>
526
+ <% @options[:pagers].each_with_index do |p, i| %>
527
+ <% if i == 0 %>
528
+ if ("<%= p[:namespace] %>" === ns) {
529
+ <%= p[:name] %>_sync(page_id);
530
+ }
531
+ <% else %>
532
+ else if ("<%= p[:namespace] %>" === ns) {
533
+ <%= p[:name] %>_sync(page_id);
534
+ }
535
+ <% end %>
536
+ <% end %>
537
+ <% end %>
538
+ }
539
+
540
+ function vm_pg_unmark_needs_sync(ns, page_id) {
541
+ delete vm_unsynced[ns][page_id];
542
+ }
543
+
544
+ function vm_pg_sync_wakeup() {
545
+ //Iterate through all the unsynced entries an increment any entries that are 0 to 1
546
+ <% @options[:pagers].each do |p| %>
547
+ //Get all page ids in a namespace
548
+ var page_ids = Object.keys(vm_unsynced.<%= p[:namespace] %>);
549
+
550
+ for (var i = 0; i < page_ids.length; ++i) {
551
+ if (vm_unsynced.<%= p[:namespace] %>[page_ids[i]] === 0) {
552
+ vm_unsynced.<%= p[:namespace] %>[page_ids[i]] = 1;
553
+ } else {
554
+ //Notify pager
555
+ <%= p[:name] %>_sync(page_ids[i]);
556
+ }
557
+ }
558
+ <% end %>
559
+ }
560
+ ///////////////////////////////////////////////////////////////////////////
508
561
  }
509
562
 
510
563
  on_wakeup %{
@@ -711,5 +764,6 @@ service :vm do
711
764
 
712
765
  every 20.seconds, %{
713
766
  vm_pageout();
767
+ vm_pg_sync_wakeup();
714
768
  }
715
769
  end
data/docs/services/vm.md CHANGED
@@ -143,11 +143,23 @@ requested. This is because a cached page will be returned by the call stack whil
143
143
  ##Cache
144
144
  See below with `vm_cache_write` for how to write to the cache. Each pager can choose whether or not to cache; some pagers may cache only reads while others will cache writes. Failure to write to the cache at all will cause `watch` to never trigger. Some pagers may use a trick where writes are allowed, and go directly to the cache but nowhere else. This is to allow things like *pending* transactions where you can locally fake data until a server response is received which will both wipe the fake write and insert the new one. Cache writes will trigger `watch`; if you write to cache with `vm_cache_write` with a page that has the same `_hash` as a page that already exists in cache, no `watch` events will be triggered. Additionally, calling `vm_cache_write` with a non-modified page will result in no performance penalty. `vm_cache_write` notifies controllers asynchronously and is not effected by the `watch` flag on controllers.
145
145
 
146
- ###Pageout & Cache Synchronization
147
- Cache will periodically be synchronized to disk via the `pageout` service. When flok reloads itself, and the `vm` service gets a `watch` or `watch_sync` request, the `vm` service will attempt to read from the `vm_cache` first and then read the page from disk (write that disk read to cache). The only difference between `watch_sync` and `watch` is that `watch_sync` will synchronously pull from disk and panic if there is no cache available for the page). (Both `watch` and `watch_sync` will always call the pager's after the cache read as well.)
146
+ ###Pageout, Cache Synchronization, and Pager Synchronization
147
+ ####Pageout Daemon
148
+ Cache will periodically be synchronized to disk via the `pageout` service. When flok reloads itself, and the `vm` service gets a `watch` the `vm` service will attempt to read from the `vm_cache` first and then read the page from disk (write that disk read to cache).
148
149
 
149
150
  Pageout is embodied in the function named `vm_pageout()`. This will asynchronously write `vm_dirty` to disk and clear `vm_dirty` once the write has been commited. `vm_pageout()` is called every minute by the interval timer in this service.
150
151
 
152
+ ####Pager Synchronization Daemon
153
+ When pagers get a write request, many pagers (as in all of them atm) mark the pages via `vm_pg_mark_needs_sync` which first calls the pagers `sync`
154
+ routine immediately and writes to the `vm_unsynced` hash. The hash is used like `vm_unsynced[ns][page_id]` which yields an integer value. The integer
155
+ value is either `0` or `1`. When `vm_pg_mark_needs_sync` is first called, the value is set to `0`. When the pager synchronization daemon
156
+ goes over the list in `vm_unsynced`; the daemon checks the integer field. If the integer is `0`, then the daemon only increments the integer. If the
157
+ integer is `1`, then the daemon notifies the pager with the `sync` action. The reason this is done is to avoid calling a pagers `sync` function too
158
+ soon as it is immediately called the first time when the pager calls `vm_pg_mark_needs_sync` on the page (usually at the end of the `write` action
159
+ for the pager). The pager de-registers the page via `vm_pg_unmark_needs_sync`.
160
+
161
+ The pager synchronization daemon is embodied in the function called `vm_pg_sync_wakeup`
162
+
151
163
  ###Datatypes & Structures (Opaque, do not directly modify)
152
164
  * `vm_cache` - The main area for storing the cache. Stored in `vm_cache[ns][key]`. Contains all namespaces by default with blank hashes.
153
165
  * `vm_dirty` - Pages recently written to cache go on the dirty list so that they may be written when the pageout handler runs. Dictionary contains map for `vm_dirty[ns][page._id] => page` for all dirty pages. Pages are removed from the dictionary when they are written in the pageout. Contains all namespaces by default with blank hashes.
@@ -159,6 +171,11 @@ Pageout is embodied in the function named `vm_pageout()`. This will asynchronous
159
171
  during a sync call for disk reads or the synchronous `read_sync` request. The format for each element in the array is `{"page_id": [bp1, bp2], ...}`
160
172
  * `vm_pager_waiting_read` - A hash that maps `[ns][page_id]` into a hash that represents a the page that was trying to be written.
161
173
  needed to be read before notifying the pager. Multiple write attempts on the same page before the disk response will undefined behavior.
174
+ * `vm_unsynced_*`
175
+ * `vm_unsynced` - A hash that maps `vm_unsynced_fresh[ns][page_id]` to an integer that is either `0` or `1`. the vm sync daemon reads over this
176
+ queue and `0` means that it was just requested via `vm_pg_mark_needs_sync` and needs to be incremented to `1`. `1` means that the vm sync
177
+ daemon must contact the pager for the `sync` action. This will happend until the pager calls `vm_pg_unmark_needs_sync` which will remove it
178
+ from this hash
162
179
 
163
180
  ##Helper Methods
164
181
 
@@ -196,9 +213,14 @@ Pageout is embodied in the function named `vm_pageout()`. This will asynchronous
196
213
  `__changes_id` of the page matches `changes_id`. If the page is based (implying the base page has changes and the page has changes as all base
197
214
  pages have changes), then if the `changes_id` matches the **base** `__changes_id` , the `__base` is removed from the page. If `changes_id`
198
215
  does not match in either of the cases, then nothing happends. This may happend if a synchronization errousouly comes in.
199
- ###Non functional
216
+ ###Non functional (functional as is in lambda calculus, or lisp (no **global** state changes but may modify parameters)
200
217
  ####Pager specific
201
218
  * `vm_cache_write(ns, page)` - Save a page to cache memory. This will not recalculate the page hash. The page will be stored in `vm_cache[ns][id]` by.
219
+ * `vm_pg_mark_needs_sync(ns, page_id)` - Marks that a page **in memory** is needing to be synced to the pager. This does a few things:
220
+ * The page_id is added to the `vm_unsynced` with the value of 0; see above in `Datatypes & Structures` for details. i.e.
221
+ `vm_unsynced[$PAGER_NS][page_id] = 0`
222
+ * the pager's routine of `sync` is called immediately. The page must exist in cache at this point.
223
+ * `vm_pg_unmark_needs_sync(ns, page_id)` - Removes the page from the pending synchronization queue `delete vm_unsynced[$PAGER_NS][page_id]`)
202
224
 
203
225
  ### <a name='user_page_modification_helpers'></a>User page modification helpers (Controller Macros)
204
226
  You should never directly edit a page in user land; if you do; the pager has no way of knowing that you made modifications. Additionally, if you have multiple controllers watching a page, and it is modified in one controller, those other controllers
@@ -11,6 +11,9 @@ If you haven't already, read [VM Service](../vm.md) for context on pagers.
11
11
  * `$NAME_unwatch(id)` - There are no controllers that are watching the page with a page that contains this in the `_id` field
12
12
  * `$NAME_write(page)` - You should write this page, e.g. to network, and/or write to `vm_cache_write`. Alternatively, you can write the page over the network and then let the response from that call `vm_cache_write` in what ever listening code you have.
13
13
  * `page` - A fully constructed page with correctly calculated `_hash` and _sigs on entries.
14
+ * `$NAME_sync(page_id)` - A page is requested to be synchronized. This was requested by the pager itself by `vm_pg_mark_needs_sync`. Usually,
15
+ in `write`, a pager will call `vm_pg_mark_needs_sync` which will then invoke `$NAME_sync(page_id)` immediately and on a scheduled interval
16
+ via the synchronization vm daemon until this pager removes the page from the unsynchronized queues via `vm_pg_unmark_needs_sync`.
14
17
 
15
18
  ##When are pagers invoked?
16
19
  Pagers handle all requests from controllers except for the following conditions:
@@ -28,10 +31,11 @@ The *default memory pager* does not do anything on `watch` or `unwatch`. It depe
28
31
 
29
32
  ####Spec pager | `pg_spec0`, `pg_spec1`
30
33
  This pager does the following when calls are made to it's functions, it's designed to assist with `vm` kernel specs.
31
- * `init` - Sets `pg_spec0_init_params` to `{ns: ns, options: options}`
32
- * `watch` - Appends `{id: id, hash: hash}` to `pg_spec0_watchlist`
33
- * `unwatch` - appends id to `pg_spec0_unwatchlist`
34
+ * `init` - Sets `pg_specN_init_params` to `{ns: ns, options: options}`
35
+ * `watch` - Appends `{id: id, hash: hash}` to `pg_specN_watchlist`
36
+ * `unwatch` - appends id to `pg_specN_unwatchlist`
34
37
  * `write` - Writes the given page to `vm_cache_write`
38
+ * `sync` - Appends given page_id to `pg_specN_sync_requests`
35
39
 
36
40
  These pagers only exists if the environment is in `DEBUG` mode (`@debug` is enabled).
37
41
 
data/docs/todo.md ADDED
@@ -0,0 +1,16 @@
1
+ #Todo
2
+
3
+ ###Known issues & Bugs
4
+
5
+ 0. A `every` event used in a controller's action will time correctly on the first action, but subsequent actions will be off by at most 3 ticks.
6
+ This is because we do not have any way (currently) to reset the timing queue in the controller as it reisters for all timing events at init. See
7
+ "Does not call intervals of other actions; and still works when switching back actions" in `spec/kern/controller_spec.rb`
8
+ 1. `vm_cache_write_sync_pending` in the `vm` service relies on page_ids, but this would cause a collision on two pages named the same thing. This
9
+ needs to integrate the namespace.
10
+ 2. The pager synchronization daemon and functions associated with marking paging as needing synchronization will attempt to sync at one time and not
11
+ store the data if there is a crash or exit before synchronization completes. Furethermore, too many unsynced pages will wreck havok as they wil be
12
+ dispatched at the same time via the synchronization daemon.
13
+
14
+ ###Ideas for improvement
15
+ 0. The `Raise` function should not actually signal the controller, it could just inline that
16
+ 1. The controller's `ctable` could be flattened.
@@ -494,7 +494,7 @@ module Flok
494
494
  end
495
495
 
496
496
  class UserCompilerAction
497
- attr_accessor :controller, :name, :ons, :every_handlers, :on_entry_has_goto
497
+ attr_accessor :controller, :name, :ons, :every_handlers
498
498
  include UserCompilerMacro
499
499
 
500
500
  def initialize controller, name, ctx, &block
@@ -504,7 +504,6 @@ module Flok
504
504
  @_on_entry_src = ""
505
505
  @ons = [] #Event handlers
506
506
  @every_handlers = []
507
- @on_entry_has_goto = false
508
507
 
509
508
  self.instance_eval(&block)
510
509
  end
@@ -512,8 +511,6 @@ module Flok
512
511
  def on_entry js_src
513
512
  #returns a string
514
513
  @_on_entry_src = _macro(js_src)
515
-
516
- @on_entry_has_goto = (js_src =~ /Goto/) != nil
517
514
  end
518
515
 
519
516
  def on_entry_src
@@ -585,8 +582,6 @@ module Flok
585
582
 
586
583
  def choose_action &block
587
584
  @ctx.action self, :choose_action, &block
588
-
589
- raise "choose_action must contain Goto" unless @ctx.actions.detect{|e| e.name == :choose_action}.on_entry_has_goto
590
585
  end
591
586
 
592
587
  #Names of spots
data/lib/flok/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Flok
2
- VERSION = "0.0.79"
2
+ VERSION = "0.0.80"
3
3
  end
@@ -2,7 +2,7 @@
2
2
  service_instance :vm, :vm, {
3
3
  :pagers => [
4
4
  {
5
- :name => "spec2",
5
+ :name => "pg_spec0",
6
6
  :namespace => "user",
7
7
  :options => {
8
8
  "hello" => "world"
@@ -0,0 +1,12 @@
1
+ #Simple service config that uses built-in spec service to create a instance called 'spec'
2
+ service_instance :vm, :vm, {
3
+ :pagers => [
4
+ {
5
+ :name => "pg_spec0",
6
+ :namespace => "spec",
7
+ :options => {
8
+ "hello" => "world"
9
+ }
10
+ }
11
+ ]
12
+ }
@@ -3,14 +3,7 @@ controller :my_controller do
3
3
 
4
4
  action :my_action do
5
5
  on_entry %{
6
- var entry = {
7
- hello: "world"
8
- }
9
-
10
- page = NewPage("array", "test");
11
- SetPageHead(page, "head");
12
- SetPageNext(page, "next");
13
- EntryInsert(page, 0, entry);
6
+ var page = vm_create_page("test");
14
7
 
15
8
  var info = {
16
9
  ns: "spec",
@@ -3,14 +3,7 @@ controller :my_controller do
3
3
 
4
4
  action :my_action do
5
5
  on_entry %{
6
- var entry = {
7
- hello: "world"
8
- }
9
-
10
- page = NewPage("array", "test");
11
- SetPageHead(page, "head");
12
- SetPageNext(page, "next");
13
- EntryInsert(page, 0, entry);
6
+ var page = vm_create_page("test");
14
7
 
15
8
  var watch_info = {
16
9
  ns: "spec",
@@ -979,18 +979,6 @@ RSpec.describe "kern:controller_spec" do
979
979
  @driver.mexpect("if_event", [Integer, "action", {"from" => nil, "to" => "index"}])
980
980
  end
981
981
 
982
- it "Not setting a Goto will result in an exception" do
983
- expect {
984
- ctx = flok_new_user File.read('./spec/kern/assets/choose_action_sync_no_goto.rb'), File.read("./spec/kern/assets/test_service/config0.rb")
985
- ctx.evald %{
986
- base = _embed("my_controller", 0, {}, null);
987
-
988
- //Drain queue
989
- int_dispatch([]);
990
- }
991
- }.to raise_exception
992
- end
993
-
994
982
  it "Does support using a macro that contains current_action" do
995
983
  ctx = flok_new_user File.read('./spec/kern/assets/current_action_nav.rb')
996
984
  dump = ctx.evald %{
@@ -39,21 +39,12 @@ RSpec.describe "kern:vm_service" do
39
39
 
40
40
  #Run the check
41
41
  res = ctx.eval %{
42
- //Manually construct a page
43
- page = {
44
- _head: "a",
45
- _next: "b",
46
- _type: "array",
47
- _id: "hello",
48
- entries: [
49
- {_id: "hello2", _sig: "nohteunth"},
50
- ]
51
- }
52
-
53
- vm_rehash_page(page);
42
+ var page = vm_create_page("test");
54
43
 
55
44
  //Save page
45
+ vm_transaction_begin();
56
46
  vm_cache_write("user", page);
47
+ vm_transaction_end();
57
48
  }
58
49
 
59
50
  vm_cache = JSON.parse(ctx.eval("JSON.stringify(vm_cache)"))
@@ -114,20 +105,12 @@ RSpec.describe "kern:vm_service" do
114
105
  //which receives a call to watch with the hash of this page so the
115
106
  //watch function can tell if the page has changed (e.g. if you are connecting)
116
107
  //to a remote server
117
- page = {
118
- _head: "a",
119
- _next: "b",
120
- _id: "my_key",
121
- _type: "array",
122
- entries: [
123
- {_id: "hello2", _sig: "nohteunth"},
124
- ]
125
- }
126
-
127
- vm_rehash_page(page);
108
+ var page = vm_create_page("test");
128
109
 
129
110
  //Save page for the spec pager
111
+ vm_transaction_begin();
130
112
  vm_cache_write("spec", page);
113
+ vm_transaction_end();
131
114
  }
132
115
 
133
116
  #This hash was calculated during vm_rehash_page
@@ -144,10 +127,7 @@ RSpec.describe "kern:vm_service" do
144
127
  pg_spec0_watchlist = JSON.parse(ctx.eval("JSON.stringify(pg_spec0_watchlist)"))
145
128
 
146
129
  #Expect options and ns to match in config4
147
- expect(pg_spec0_watchlist).to eq([{
148
- "id" => "my_key",
149
- "page" => page
150
- }])
130
+ expect(pg_spec0_watchlist[0]["id"]).to eq("my_key")
151
131
  end
152
132
 
153
133
  it "does not throw an exception if multiple watches are attempted" do
@@ -351,6 +331,8 @@ RSpec.describe "kern:vm_service" do
351
331
  int_dispatch([]);
352
332
  }
353
333
 
334
+ @driver.int "int_per_get_res", ["vm", "spec", "test", nil]
335
+
354
336
  #Expect the page to be written to cache
355
337
  vm_cache = JSON.parse(ctx.eval("JSON.stringify(vm_cache)"));
356
338
  vm_write_list = JSON.parse(ctx.eval("JSON.stringify(vm_write_list[0])"));
@@ -367,8 +349,17 @@ RSpec.describe "kern:vm_service" do
367
349
  int_dispatch([]);
368
350
  }
369
351
 
370
- read_res_params = JSON.parse(ctx.eval("JSON.stringify(read_res_params)"))
352
+ #Write will attempt to read disk first
353
+ @driver.int "int_per_get_res", ["vm", "spec", "test", nil]
354
+
355
+ #Read is asynchronous
356
+ ctx.eval %{
357
+ //Drain queue
358
+ int_dispatch([]);
359
+ }
360
+
371
361
  vm_write_list = JSON.parse(ctx.eval("JSON.stringify(vm_write_list[0])"));
362
+ read_res_params = JSON.parse(ctx.eval("JSON.stringify(read_res_params)"))
372
363
  expect(read_res_params).to eq(vm_write_list)
373
364
  end
374
365
 
@@ -0,0 +1,137 @@
1
+ #The vm service
2
+
3
+ Dir.chdir File.join File.dirname(__FILE__), '../../'
4
+ require './spec/env/kern.rb'
5
+ require './spec/lib/helpers.rb'
6
+ require './spec/lib/io_extensions.rb'
7
+ require './spec/lib/rspec_extensions.rb'
8
+ require 'zlib'
9
+
10
+ RSpec.describe "kern:vm_service" do
11
+ include Zlib
12
+ include_context "kern"
13
+
14
+ it "vm_pg_mark_needs_sync does call the pagers sync routine and adds an entry in the vm_unsynced table with a value of 0" do
15
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config5c.rb")
16
+ dump = ctx.evald %{
17
+ //Needed to initialize pagers
18
+ base = _embed("my_controller", 0, {}, null);
19
+
20
+ vm_pg_mark_needs_sync("spec", "test");
21
+
22
+ dump.vm_unsynced = vm_unsynced;
23
+ dump.pg_spec0_sync_requests = pg_spec0_sync_requests;
24
+ }
25
+
26
+ expect(dump["vm_unsynced"]).to eq({
27
+ "spec" => {
28
+ "test" => 0
29
+ }
30
+ })
31
+
32
+ expect(dump["pg_spec0_sync_requests"]).to eq(["test"])
33
+ end
34
+
35
+ it "vm_pg_unmark_needs_sync does remove the entry from the vm_unsynced table and does not fail if the entry does not exist" do
36
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config5c.rb")
37
+ dump = ctx.evald %{
38
+ //Needed to initialize pagers
39
+ base = _embed("my_controller", 0, {}, null);
40
+
41
+ vm_pg_mark_needs_sync("spec", "test");
42
+ vm_pg_unmark_needs_sync("spec", "test");
43
+ vm_pg_unmark_needs_sync("spec", "test_non_existant_key");
44
+
45
+ dump.vm_unsynced = vm_unsynced;
46
+ }
47
+
48
+ expect(dump["vm_unsynced"]).to eq({
49
+ "spec" => {
50
+ }
51
+ })
52
+ end
53
+
54
+ #Don't sync when it's 0 because the pager just added it and we don't want to sync to early. Wait til next pass
55
+ it "vm_pg_sync_wakeup does increment any entries that are currently 0 to the value of 1 and does not invoke pager's sync for those entries" do
56
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config5c.rb")
57
+ dump = ctx.evald %{
58
+ //Needed to initialize pagers
59
+ base = _embed("my_controller", 0, {}, null);
60
+
61
+ vm_pg_mark_needs_sync("spec", "test");
62
+ vm_pg_sync_wakeup();
63
+
64
+ dump.vm_unsynced = vm_unsynced;
65
+ dump.pg_spec0_sync_requests = pg_spec0_sync_requests;
66
+ }
67
+
68
+ expect(dump["vm_unsynced"]).to eq({
69
+ "spec" => {
70
+ "test" => 1
71
+ }
72
+ })
73
+
74
+ #Only expect one entry, wakeup should have skipped the first try
75
+ expect(dump["pg_spec0_sync_requests"]).to eq(["test"])
76
+ end
77
+
78
+ it "vm_pg_sync_wakeup does *not* increment any entries that are currently 1 and *does* invoke pager's sync for those entries" do
79
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config5c.rb")
80
+ dump = ctx.evald %{
81
+ //Needed to initialize pagers
82
+ base = _embed("my_controller", 0, {}, null);
83
+
84
+ vm_pg_mark_needs_sync("spec", "test");
85
+ vm_pg_sync_wakeup();
86
+ vm_pg_sync_wakeup();
87
+
88
+ dump.vm_unsynced = vm_unsynced;
89
+ dump.pg_spec0_sync_requests = pg_spec0_sync_requests;
90
+ }
91
+
92
+ expect(dump["vm_unsynced"]).to eq({
93
+ "spec" => {
94
+ "test" => 1
95
+ }
96
+ })
97
+
98
+ #This time, we expect two entries because the second vm_sync_wakeup should have triggered it.
99
+ expect(dump["pg_spec0_sync_requests"]).to eq(["test", "test"])
100
+ end
101
+
102
+ it "vm_pg_sync_wakeup is called every 20 seconds" do
103
+ ctx = flok_new_user File.read('./spec/kern/assets/vm/controller0.rb'), File.read("./spec/kern/assets/vm/config5c.rb")
104
+
105
+ #Mark page as needing sync
106
+ dump = ctx.evald %{
107
+ //Needed to initialize pagers
108
+ base = _embed("my_controller", 0, {}, null);
109
+
110
+ vm_pg_mark_needs_sync("spec", "test");
111
+ }
112
+
113
+ #Call the timer for 1 shot
114
+ (20*4).times do
115
+ @driver.int "int_timer", []
116
+ end
117
+
118
+ #First time, the vm_pg_sync_wakeup should not have triggered anything (vm_unsynced still set to 0)
119
+ expect(ctx.dump("pg_spec0_sync_requests")).to eq(["test"])
120
+
121
+ #Call the timer for 1 more shot
122
+ (20*4).times do
123
+ @driver.int "int_timer", []
124
+ end
125
+
126
+ #Second time, vm_pg_sync_wakeup should call pager's sync function
127
+ expect(ctx.dump("pg_spec0_sync_requests")).to eq(["test", "test"])
128
+
129
+ #Call the timer for 1 more shot
130
+ (20*4).times do
131
+ @driver.int "int_timer", []
132
+ end
133
+
134
+ #Third time, vm_pg_sync_wakeup should call pager's sync function
135
+ expect(ctx.dump("pg_spec0_sync_requests")).to eq(["test", "test", "test"])
136
+ end
137
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flok
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.79
4
+ version: 0.0.80
5
5
  platform: ruby
6
6
  authors:
7
7
  - seo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-02 00:00:00.000000000 Z
11
+ date: 2015-08-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: execjs
@@ -314,9 +314,6 @@ files:
314
314
  - app/kern/pagers/pg_net_sim.js
315
315
  - app/kern/pagers/pg_sockio.js
316
316
  - app/kern/pagers/pg_spec.js
317
- - app/kern/pagers/spec0.js
318
- - app/kern/pagers/spec1.js
319
- - app/kern/pagers/spec2.js
320
317
  - app/kern/services/rest.rb
321
318
  - app/kern/services/test.rb
322
319
  - app/kern/services/vm.rb
@@ -340,7 +337,6 @@ files:
340
337
  - docs/images/view_and_spot.png
341
338
  - docs/interactive.md
342
339
  - docs/kernel_api.md
343
- - docs/known_issues.md
344
340
  - docs/messaging.md
345
341
  - docs/mod/controller.md
346
342
  - docs/mod/debug.md
@@ -364,6 +360,7 @@ files:
364
360
  - docs/services/vm/diff.md
365
361
  - docs/services/vm/pagers.md
366
362
  - docs/testing.md
363
+ - docs/todo.md
367
364
  - flok.gemspec
368
365
  - lib/flok.rb
369
366
  - lib/flok/build.rb
@@ -1208,6 +1205,7 @@ files:
1208
1205
  - spec/kern/assets/vm/config4.rb
1209
1206
  - spec/kern/assets/vm/config5.rb
1210
1207
  - spec/kern/assets/vm/config5b.rb
1208
+ - spec/kern/assets/vm/config5c.rb
1211
1209
  - spec/kern/assets/vm/config6.rb
1212
1210
  - spec/kern/assets/vm/controller0.rb
1213
1211
  - spec/kern/assets/vm/controller0_diff.rb
@@ -1306,6 +1304,7 @@ files:
1306
1304
  - spec/kern/vm_service_mem_pagers_spec.rb
1307
1305
  - spec/kern/vm_service_net_sim_pager_spec.rb
1308
1306
  - spec/kern/vm_service_spec.rb
1307
+ - spec/kern/vm_service_unsynced_spec.rb
1309
1308
  - spec/kern/vm_sockio_pager_spec.rb
1310
1309
  - spec/kern/vm_transaction_spec.rb
1311
1310
  - spec/lib/helpers.rb
@@ -2156,6 +2155,7 @@ test_files:
2156
2155
  - spec/kern/assets/vm/config4.rb
2157
2156
  - spec/kern/assets/vm/config5.rb
2158
2157
  - spec/kern/assets/vm/config5b.rb
2158
+ - spec/kern/assets/vm/config5c.rb
2159
2159
  - spec/kern/assets/vm/config6.rb
2160
2160
  - spec/kern/assets/vm/controller0.rb
2161
2161
  - spec/kern/assets/vm/controller0_diff.rb
@@ -2254,6 +2254,7 @@ test_files:
2254
2254
  - spec/kern/vm_service_mem_pagers_spec.rb
2255
2255
  - spec/kern/vm_service_net_sim_pager_spec.rb
2256
2256
  - spec/kern/vm_service_spec.rb
2257
+ - spec/kern/vm_service_unsynced_spec.rb
2257
2258
  - spec/kern/vm_sockio_pager_spec.rb
2258
2259
  - spec/kern/vm_transaction_spec.rb
2259
2260
  - spec/lib/helpers.rb
@@ -1,35 +0,0 @@
1
- <% if @debug %>
2
- spec0_data = {};
3
- spec0_read_count = 0;
4
-
5
- function spec0_init(options) {
6
- spec0_init_options = options;
7
- }
8
-
9
- function spec0_read_sync(ns, bp, key) {
10
- spec0_read_count += 1;
11
-
12
- var info = {
13
- key: key,
14
- value: spec0_data[key],
15
- }
16
- int_event(bp, "read_res", info);
17
- //vm_cache[ns][key] = spec0_data[key];
18
- }
19
-
20
- function spec0_read(ns, bp, key) {
21
- spec0_read_count += 1;
22
-
23
- var info = {
24
- key: key,
25
- value: spec0_data[key],
26
- }
27
-
28
- int_event(bp, "read_res", info);
29
- vm_cache_write(ns, key, spec0_data[key]);
30
- }
31
-
32
- function spec0_write(key, value) {
33
- spec0_data[key] = value;
34
- }
35
- <% end %>
@@ -1,24 +0,0 @@
1
- <% if @debug %>
2
- spec1_value = "a";
3
-
4
- function spec1_init(options) {
5
- spec1_init_options = options;
6
- }
7
-
8
- function spec1_read_sync(ns, bp, key) {
9
- throw "unsupported"
10
- }
11
-
12
- function spec1_read(ns, bp, key) {
13
- var info = {
14
- key: key,
15
- value: spec1_value,
16
- }
17
-
18
- int_event(bp, "read_res", info);
19
- vm_cache_write(ns, key, spec1_value);
20
-
21
- //Now change the value
22
- spec1_value = "b";
23
- }
24
- <% end %>
@@ -1,31 +0,0 @@
1
- <% if @debug %>
2
- spec2_value = "a";
3
-
4
- function spec2_init(options) {
5
- spec2_init_options = options;
6
- }
7
-
8
- function spec2_read_sync(ns, bp, key) {
9
- throw "unsupported"
10
- }
11
-
12
- function spec2_read(ns, bp, key) {
13
- var info = {
14
- key: key,
15
- value: spec2_value,
16
- }
17
-
18
- int_event(bp, "read_res", info);
19
- vm_cache_write(ns, key, spec2_value);
20
-
21
- //Now change the value
22
- spec2_value = "b";
23
- }
24
-
25
- function spec2_watch(ns, key) {
26
- }
27
-
28
- function spec2_spec_trigger() {
29
- vm_notify("user", "my_key");
30
- }
31
- <% end %>
data/docs/known_issues.md DELETED
@@ -1,7 +0,0 @@
1
- #Known issues & Bugs
2
-
3
- 0000. A `every` event used in a controller's action will time correctly on the first action, but subsequent actions will be off by at most 3 ticks.
4
- This is because we do not have any way (currently) to reset the timing queue in the controller as it reisters for all timing events at init. See
5
- "Does not call intervals of other actions; and still works when switching back actions" in `spec/kern/controller_spec.rb`
6
- 0002. `vm_cache_write_sync_pending` in the `vm` service relies on page_ids, but this would cause a collision on two pages named the same thing. This
7
- needs to integrate the namespace.