hakuban 0.6.1 → 0.6.2

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.
@@ -1539,17 +1539,43 @@ Queue = class Queue {
1539
1539
 
1540
1540
  };
1541
1541
 
1542
+ var ObjectManagerBuilder = class ObjectManagerBuilder {
1543
+ constructor(contract, managed_object_class) {
1544
+ this.contract = contract;
1545
+ this.managed_object_class = managed_object_class;
1546
+ this._on_exception_policy = "retry";
1547
+ this._retry_backoff = [0.01, 0.1, 1.0, 10.0];
1548
+ this._terminate_on_deactivation = false;
1549
+ }
1550
+
1551
+ on_exception(policy) {
1552
+ this._on_exception_policy = policy;
1553
+ return this;
1554
+ }
1555
+
1556
+ //terminate_on_deactivation: ()->
1557
+ // @terminate_on_deactivation = true
1558
+ // @
1559
+ retry_backoff(times) {
1560
+ this._retry_backoff = times;
1561
+ return this;
1562
+ }
1563
+
1564
+ with_async(block) {
1565
+ return new ObjectManager(this.contract, this.managed_object_class, block, this._retry_backoff, this._terminate_on_deactivation, this._on_exception_policy);
1566
+ }
1567
+
1568
+ };
1569
+
1542
1570
  var ObjectManager = class ObjectManager {
1543
- constructor(contract, object_class, block1) {
1571
+ constructor(contract, object_class, block, retry_backoff, terminate_on_deactivation, on_exception_policy) {
1544
1572
  var event_loop_stop_requested;
1545
1573
  this.objects = this.objects.bind(this);
1546
1574
  this.object = this.object.bind(this);
1547
1575
  this.drop = this.drop.bind(this);
1548
1576
  this.contract = contract;
1549
- this.object_class = object_class;
1550
- this.block = block1;
1551
- this._objects = {};
1552
- this.running_handlers = {};
1577
+ this._existing_objects = {};
1578
+ this._active_objects = {};
1553
1579
  this.event_queue = new Queue();
1554
1580
  //TODO: make one loop out of following two
1555
1581
  event_loop_stop_requested = new Promise((event_loop_stop) => {
@@ -1569,79 +1595,109 @@ var ObjectManager = class ObjectManager {
1569
1595
  return resolve();
1570
1596
  });
1571
1597
  this.async_loop_stopped = new Promise(async(resolve, reject) => {
1572
- var _key, event, key, object, ref, ref1;
1598
+ var base, base1, descriptor_for_lambda, error, event, heal_multiplier, i, interval_since_last_exception, key, len, name, name1, object, ref, ref1;
1573
1599
  while ((event = (await this.event_queue.shift())) != null) {
1574
1600
  switch (event.action) {
1575
1601
  case "Insert":
1576
- if (this._objects[event.descriptor.hash()] != null) {
1577
- throw "Double insert";
1578
- }
1579
- this._objects[event.descriptor.hash()] = new this.object_class(this.contract, event.descriptor);
1580
- if (this.block != null) {
1581
- this.event_queue.push({
1582
- action: "HandlerStart",
1583
- descriptor: event.descriptor
1584
- });
1585
- }
1586
- break;
1587
1602
  case "Change":
1588
- if (this._objects[event.descriptor.hash()] == null) {
1589
- throw "Uh, oh, object missing :(";
1590
- }
1591
- this._objects[event.descriptor.hash()].do_change("change");
1592
- break;
1593
1603
  case "Remove":
1594
- if (this._objects[event.descriptor.hash()] == null) {
1595
- throw "Trying to remove non-existing object. Sad.";
1604
+ case "Stopped":
1605
+ case "Timer":
1606
+ object = (base = this._existing_objects)[name = event.descriptor.hash()] || (base[name] = new object_class(this.contract, event.descriptor));
1607
+ if (!object.running && (object.block_result != null)) {
1608
+ error = (await object.block_result);
1609
+ object.block_result = null;
1610
+ if (object.last_exception_at != null) {
1611
+ interval_since_last_exception = Date.now() - object.last_exception_at;
1612
+ heal_multiplier = 10;
1613
+ object.current_delay_index -= Math.floor(interval_since_last_exception / (retry_backoff[retry_backoff.length - 1] * 1000.0 * heal_multiplier));
1614
+ if (object.current_delay_index < 0) {
1615
+ object.current_delay_index = 0;
1616
+ }
1617
+ }
1618
+ if (error != null) {
1619
+ switch (on_exception_policy) {
1620
+ case "throw":
1621
+ case "raise":
1622
+ throw error.exception;
1623
+ case "retry":
1624
+ object.last_exception_at = Date.now();
1625
+ object.earliest_next_run = Date.now() + retry_backoff[object.current_delay_index] * 1000.0;
1626
+ //wrapped to avoid weird capture effects of coffee
1627
+ (function(lambda_sleep_time, lambda_descriptor, lambda_event_queue) {
1628
+ return setTimeout((() => {
1629
+ return lambda_event_queue.push({
1630
+ action: "Timer",
1631
+ descriptor: lambda_descriptor
1632
+ });
1633
+ }), lambda_sleep_time);
1634
+ })(object.earliest_next_run - Date.now(), event.descriptor, this.event_queue);
1635
+ if (object.current_delay_index < retry_backoff.length - 1) {
1636
+ object.current_delay_index += 1;
1637
+ }
1638
+ }
1639
+ }
1596
1640
  }
1597
- this._objects[event.descriptor.hash()].do_change("remove");
1598
- delete this._objects[event.descriptor.hash()];
1599
- break;
1600
- case "HandlerStart":
1601
- if (((object = this._objects[event.descriptor.hash()]) != null) && !object.handler_already_run && (this.running_handlers[event.descriptor.hash()] == null)) {
1602
- //wrapped to avoid weird capture effects
1603
- this.running_handlers[event.descriptor.hash()] = (function(descriptor, object, block, event_queue) {
1604
- return new Promise(async function(handler_resolve, handler_reject) {
1605
- await object.run(block);
1606
- event_queue.push({
1607
- action: "HandlerFinished",
1608
- descriptor: descriptor
1641
+ //when "ignore_failing_descriptor"
1642
+ //when "drop_contract"
1643
+ if (object.check_active()) {
1644
+ if ((block != null) && !object.running && ((object.earliest_next_run == null) || Date.now() >= object.earliest_next_run)) {
1645
+ descriptor_for_lambda = event.descriptor;
1646
+ object.running = true;
1647
+ //wrapped to avoid weird capture effects of coffee
1648
+ object.block_result = (function(descriptor, object, block, event_queue) {
1649
+ return new Promise(async(resolve, reject) => {
1650
+ try {
1651
+ await object.run(block);
1652
+ return resolve(void 0);
1653
+ } catch (error1) {
1654
+ error = error1;
1655
+ console.error("Exception in hakuban manager lambda:", error);
1656
+ return resolve(error);
1657
+ } finally {
1658
+ object.running = false;
1659
+ event_queue.push({
1660
+ action: "Stopped",
1661
+ descriptor: descriptor_for_lambda
1662
+ });
1663
+ }
1609
1664
  });
1610
- return handler_resolve();
1611
- });
1612
- })(event.descriptor, object, this.block, this.event_queue);
1613
- }
1614
- break;
1615
- case "HandlerFinished":
1616
- if (this.running_handlers[event.descriptor.hash()] == null) {
1617
- throw "Handler finished but it was not running. That sucks.";
1618
- }
1619
- delete this.running_handlers[event.descriptor.hash()];
1620
- if (this._objects[event.descriptor.hash()] != null) {
1621
- this.event_queue.push({
1622
- action: "HandlerStart",
1623
- descriptor: event.descriptor
1624
- });
1665
+ })(event.descriptor, object, block, this.event_queue);
1666
+ }
1667
+ (base1 = this._active_objects)[name1 = event.descriptor.hash()] || (base1[name1] = object);
1668
+ object.change();
1669
+ } else {
1670
+ delete this._active_objects[event.descriptor.hash()];
1671
+ if (object.running) {
1672
+ object.stop();
1673
+ } else {
1674
+ delete this._existing_objects[event.descriptor.hash()];
1675
+ }
1625
1676
  }
1626
1677
  break;
1627
1678
  case "Drop":
1628
1679
  this.event_loop_stop();
1629
1680
  await this.event_loop_stopped;
1630
- ref = this._objects;
1631
- for (_key in ref) {
1632
- object = ref[_key];
1633
- object.do_change("remove");
1681
+ ref = {...this._existing_objects};
1682
+ for (key in ref) {
1683
+ object = ref[key];
1684
+ if (object.running) {
1685
+ object.stop();
1686
+ } else {
1687
+ delete this._existing_objects[key];
1688
+ }
1634
1689
  }
1635
- while (Object.keys(this.running_handlers).length > 0) {
1690
+ while (Object.keys(this._existing_objects).length > 0) {
1636
1691
  event = (await this.event_queue.shift());
1637
- if (event.action === "HandlerFinished") {
1638
- delete this.running_handlers[event.descriptor.hash()];
1692
+ if (event.action === "Stopped") {
1693
+ delete this._existing_objects[event.descriptor.hash()];
1639
1694
  }
1640
1695
  }
1641
1696
  this.event_queue.clear();
1642
- ref1 = this._objects;
1643
- for (key in ref1) {
1644
- delete this._objects[key];
1697
+ ref1 = Object.keys(this._active_objects);
1698
+ for (i = 0, len = ref1.length; i < len; i++) {
1699
+ key = ref1[i];
1700
+ delete this._active_objects[key];
1645
1701
  }
1646
1702
  this.contract.drop();
1647
1703
  this.contract = null;
@@ -1657,11 +1713,11 @@ var ObjectManager = class ObjectManager {
1657
1713
  }
1658
1714
 
1659
1715
  objects() {
1660
- return Object.values(this._objects);
1716
+ return Object.values(this._active_objects);
1661
1717
  }
1662
1718
 
1663
1719
  object() {
1664
- return Object.values(this._objects)[0];
1720
+ return Object.values(this._active_objects)[0];
1665
1721
  }
1666
1722
 
1667
1723
  async drop() {
@@ -1680,15 +1736,15 @@ var ManagedObject = class ManagedObject {
1680
1736
  this.run = this.run.bind(this);
1681
1737
  this.next_event = this.next_event.bind(this);
1682
1738
  this.next_change = this.next_change.bind(this);
1683
- this.do_change = this.do_change.bind(this);
1739
+ this.change = this.change.bind(this);
1740
+ this.stop = this.stop.bind(this);
1684
1741
  this.contract = contract;
1685
1742
  this.descriptor = descriptor1;
1686
1743
  this._changes = new Queue();
1687
- this.handler_already_run = false;
1744
+ this.current_delay_index = 0;
1688
1745
  }
1689
1746
 
1690
1747
  async run(handler) {
1691
- this.handler_already_run = true;
1692
1748
  return (await handler(this));
1693
1749
  }
1694
1750
 
@@ -1701,14 +1757,18 @@ var ManagedObject = class ManagedObject {
1701
1757
  switch ((await this._changes.shift())) {
1702
1758
  case "change":
1703
1759
  return true;
1704
- case "remove":
1760
+ case "stop":
1705
1761
  return false;
1706
1762
  }
1707
1763
  }
1708
1764
  }
1709
1765
 
1710
- do_change(change) {
1711
- return this._changes.push(change);
1766
+ change() {
1767
+ return this._changes.push("change");
1768
+ }
1769
+
1770
+ stop() {
1771
+ return this._changes.push("stop");
1712
1772
  }
1713
1773
 
1714
1774
  };
@@ -1983,7 +2043,7 @@ ObjectObserve = class ObjectObserve {
1983
2043
  this.drop = this.drop.bind(this);
1984
2044
  this.object_state = this.object_state.bind(this);
1985
2045
  this.events = this.events.bind(this);
1986
- this.async = this.async.bind(this);
2046
+ this.manage = this.manage.bind(this);
1987
2047
  this.local_node = local_node;
1988
2048
  this.descriptor = descriptor1;
1989
2049
  this.deserializer = deserializer;
@@ -2028,9 +2088,9 @@ ObjectObserve = class ObjectObserve {
2028
2088
  return new ObjectDescriptorEvents(hakuban_object_observe_events_get(this.pointer));
2029
2089
  }
2030
2090
 
2031
- async(lambda) {
2032
- var ObservedObject;
2033
- ObservedObject = class ObservedObject extends ManagedObject {
2091
+ manage() {
2092
+ var ManagedObject$1;
2093
+ ManagedObject$1 = class ManagedObject$1 extends ManagedObject {
2034
2094
  state() {
2035
2095
  var ref;
2036
2096
  return (ref = this.contract) != null ? ref.object_state() : void 0;
@@ -2041,8 +2101,12 @@ ObjectObserve = class ObjectObserve {
2041
2101
  return (ref = this.contract) != null ? (ref1 = ref.object_state()) != null ? ref1.data : void 0 : void 0;
2042
2102
  }
2043
2103
 
2104
+ check_active() {
2105
+ return !!this.state();
2106
+ }
2107
+
2044
2108
  };
2045
- return new ObjectManager(this, ObservedObject, lambda);
2109
+ return new ObjectManagerBuilder(this, ManagedObject$1);
2046
2110
  }
2047
2111
 
2048
2112
  };
@@ -2060,7 +2124,7 @@ ObjectExpose = class ObjectExpose {
2060
2124
  this.assigned = this.assigned.bind(this);
2061
2125
  this.desynchronize = this.desynchronize.bind(this);
2062
2126
  this.events = this.events.bind(this);
2063
- this.async = this.async.bind(this);
2127
+ this.manage = this.manage.bind(this);
2064
2128
  this.local_node = local_node;
2065
2129
  this.descriptor = descriptor1;
2066
2130
  this.serializer = serializer;
@@ -2107,9 +2171,9 @@ ObjectExpose = class ObjectExpose {
2107
2171
  return new ObjectDescriptorEvents(hakuban_object_expose_events_get(this.pointer));
2108
2172
  }
2109
2173
 
2110
- async(lambda) {
2111
- var ExposedObject;
2112
- ExposedObject = class ExposedObject extends ManagedObject {
2174
+ manage() {
2175
+ var ManagedObject$1;
2176
+ ManagedObject$1 = class ManagedObject$1 extends ManagedObject {
2113
2177
  constructor(contract, descriptor) {
2114
2178
  super(contract, descriptor);
2115
2179
  this.run = this.run.bind(this);
@@ -2123,45 +2187,49 @@ ObjectExpose = class ObjectExpose {
2123
2187
 
2124
2188
  async run(handler) {
2125
2189
  var ref;
2126
- boundMethodCheck(this, ExposedObject);
2190
+ boundMethodCheck(this, ManagedObject$1);
2127
2191
  await super.run(handler);
2128
2192
  return (ref = this.contract) != null ? ref.desynchronize(this._assignment) : void 0;
2129
2193
  }
2130
2194
 
2131
2195
  do_change(change) {
2132
2196
  var ref;
2133
- boundMethodCheck(this, ExposedObject);
2197
+ boundMethodCheck(this, ManagedObject$1);
2134
2198
  this._assignment = (ref = this.contract) != null ? ref.assignment() : void 0;
2135
2199
  return super.do_change(change);
2136
2200
  }
2137
2201
 
2138
2202
  assignment() {
2139
2203
  var ref;
2140
- boundMethodCheck(this, ExposedObject);
2204
+ boundMethodCheck(this, ManagedObject$1);
2141
2205
  return (ref = this.contract) != null ? ref.assignment() : void 0;
2142
2206
  }
2143
2207
 
2144
2208
  assigned() {
2145
2209
  var ref;
2146
- boundMethodCheck(this, ExposedObject);
2210
+ boundMethodCheck(this, ManagedObject$1);
2147
2211
  return (ref = this.contract) != null ? ref.assigned() : void 0;
2148
2212
  }
2149
2213
 
2150
2214
  set_state(version, cooked_data, data_type = []) {
2151
2215
  var ref;
2152
- boundMethodCheck(this, ExposedObject);
2216
+ boundMethodCheck(this, ManagedObject$1);
2153
2217
  return (ref = this.contract) != null ? ref.set_object_state(version, cooked_data, data_type, this._assignment) : void 0;
2154
2218
  }
2155
2219
 
2156
2220
  set_data(data) {
2157
2221
  var timestamp;
2158
- boundMethodCheck(this, ExposedObject);
2222
+ boundMethodCheck(this, ManagedObject$1);
2159
2223
  timestamp = new Date().getTime();
2160
2224
  return this.set_state([1, Math.floor(timestamp / 1000), timestamp - Math.floor(timestamp / 1000) * 1000, 0], data);
2161
2225
  }
2162
2226
 
2227
+ check_active() {
2228
+ return this.assigned();
2229
+ }
2230
+
2163
2231
  };
2164
- return new ObjectManager(this, ExposedObject, lambda);
2232
+ return new ObjectManagerBuilder(this, ManagedObject$1);
2165
2233
  }
2166
2234
 
2167
2235
  };
@@ -2176,7 +2244,6 @@ TagObserve = class TagObserve {
2176
2244
  this.drop = this.drop.bind(this);
2177
2245
  this.object_descriptors = this.object_descriptors.bind(this);
2178
2246
  this.object_state = this.object_state.bind(this);
2179
- this.async = this.async.bind(this);
2180
2247
  this.local_node = local_node;
2181
2248
  this.descriptor = descriptor1;
2182
2249
  this.deserializer = deserializer;
@@ -2232,9 +2299,9 @@ TagObserve = class TagObserve {
2232
2299
  return new ObjectDescriptorEvents(hakuban_tag_observe_events_get(this.pointer));
2233
2300
  }
2234
2301
 
2235
- async(lambda) {
2236
- var ObservedObject;
2237
- ObservedObject = class ObservedObject extends ManagedObject {
2302
+ manage() {
2303
+ var ManagedObject$1;
2304
+ ManagedObject$1 = class ManagedObject$1 extends ManagedObject {
2238
2305
  state() {
2239
2306
  var ref;
2240
2307
  return (ref = this.contract) != null ? ref.object_state(this.descriptor) : void 0;
@@ -2245,8 +2312,12 @@ TagObserve = class TagObserve {
2245
2312
  return (ref = this.contract) != null ? (ref1 = ref.object_state(this.descriptor)) != null ? ref1.data : void 0 : void 0;
2246
2313
  }
2247
2314
 
2315
+ check_active() {
2316
+ return !!this.state();
2317
+ }
2318
+
2248
2319
  };
2249
- return new ObjectManager(this, ObservedObject, lambda);
2320
+ return new ObjectManagerBuilder(this, ManagedObject$1);
2250
2321
  }
2251
2322
 
2252
2323
  };
@@ -2265,7 +2336,7 @@ TagExpose = class TagExpose {
2265
2336
  this.assigned = this.assigned.bind(this);
2266
2337
  this.desynchronize = this.desynchronize.bind(this);
2267
2338
  this.events = this.events.bind(this);
2268
- this.async = this.async.bind(this);
2339
+ this.manage = this.manage.bind(this);
2269
2340
  this.local_node = local_node;
2270
2341
  this.descriptor = descriptor1;
2271
2342
  this.serializer = serializer;
@@ -2329,9 +2400,9 @@ TagExpose = class TagExpose {
2329
2400
  return new ObjectDescriptorEvents(hakuban_tag_expose_events_get(this.pointer));
2330
2401
  }
2331
2402
 
2332
- async(lambda) {
2333
- var ExposedObject;
2334
- ExposedObject = class ExposedObject extends ManagedObject {
2403
+ manage() {
2404
+ var ManagedObject$1;
2405
+ ManagedObject$1 = class ManagedObject$1 extends ManagedObject {
2335
2406
  constructor(contract, descriptor) {
2336
2407
  super(contract, descriptor);
2337
2408
  this.run = this.run.bind(this);
@@ -2345,45 +2416,49 @@ TagExpose = class TagExpose {
2345
2416
 
2346
2417
  async run(handler) {
2347
2418
  var ref;
2348
- boundMethodCheck(this, ExposedObject);
2419
+ boundMethodCheck(this, ManagedObject$1);
2349
2420
  await super.run(handler);
2350
2421
  return (ref = this.contract) != null ? ref.desynchronize(this.descriptor, this._assignment) : void 0;
2351
2422
  }
2352
2423
 
2353
2424
  do_change(change) {
2354
2425
  var ref;
2355
- boundMethodCheck(this, ExposedObject);
2426
+ boundMethodCheck(this, ManagedObject$1);
2356
2427
  this._assignment = (ref = this.contract) != null ? ref.assignment(this.descriptor) : void 0;
2357
2428
  return super.do_change(change);
2358
2429
  }
2359
2430
 
2360
2431
  assignment() {
2361
2432
  var ref;
2362
- boundMethodCheck(this, ExposedObject);
2433
+ boundMethodCheck(this, ManagedObject$1);
2363
2434
  return (ref = this.contract) != null ? ref.assignment(this.descriptor) : void 0;
2364
2435
  }
2365
2436
 
2366
2437
  assigned() {
2367
2438
  var ref;
2368
- boundMethodCheck(this, ExposedObject);
2439
+ boundMethodCheck(this, ManagedObject$1);
2369
2440
  return (ref = this.contract) != null ? ref.assigned(this.descriptor) : void 0;
2370
2441
  }
2371
2442
 
2372
2443
  set_state(version, cooked_data, data_type = []) {
2373
2444
  var ref;
2374
- boundMethodCheck(this, ExposedObject);
2445
+ boundMethodCheck(this, ManagedObject$1);
2375
2446
  return (ref = this.contract) != null ? ref.set_object_state(this.descriptor, version, cooked_data, data_type, this._assignment) : void 0;
2376
2447
  }
2377
2448
 
2378
2449
  set_data(data) {
2379
2450
  var timestamp;
2380
- boundMethodCheck(this, ExposedObject);
2451
+ boundMethodCheck(this, ManagedObject$1);
2381
2452
  timestamp = new Date().getTime();
2382
2453
  return this.set_state([1, Math.floor(timestamp / 1000), timestamp - Math.floor(timestamp / 1000) * 1000, 0], data);
2383
2454
  }
2384
2455
 
2456
+ check_active() {
2457
+ return this.assigned();
2458
+ }
2459
+
2385
2460
  };
2386
- return new ObjectManager(this, ExposedObject, lambda);
2461
+ return new ObjectManagerBuilder(this, ManagedObject$1);
2387
2462
  }
2388
2463
 
2389
2464
  };