@agoric/vow 0.1.1-dev-442f07c.0 → 0.1.1-dev-69f8e4b.0

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.
package/README.md CHANGED
@@ -150,8 +150,8 @@ Here is an (oversimplified) algorithm that `watch` and `when` use to obtain a
150
150
  final result:
151
151
 
152
152
  ```js
153
- // Directly await the non-retriable original specimen.
154
- // This is non-retriable because we don't know how our caller obtained
153
+ // Directly await the non-retryable original specimen.
154
+ // This is non-retryable because we don't know how our caller obtained
155
155
  // it in the first place, since it is an application-specific detail
156
156
  // that may not be side-effect free.
157
157
  let result = await specimenP;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agoric/vow",
3
- "version": "0.1.1-dev-442f07c.0+442f07c",
3
+ "version": "0.1.1-dev-69f8e4b.0+69f8e4b",
4
4
  "description": "Remote (shortening and disconnection-tolerant) Promise-likes",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -19,8 +19,8 @@
19
19
  "lint:types": "tsc"
20
20
  },
21
21
  "dependencies": {
22
- "@agoric/base-zone": "0.1.1-dev-442f07c.0+442f07c",
23
- "@agoric/internal": "0.3.3-dev-442f07c.0+442f07c",
22
+ "@agoric/base-zone": "0.1.1-dev-69f8e4b.0+69f8e4b",
23
+ "@agoric/internal": "0.3.3-dev-69f8e4b.0+69f8e4b",
24
24
  "@endo/env-options": "^1.1.6",
25
25
  "@endo/errors": "^1.2.5",
26
26
  "@endo/eventual-send": "^1.2.5",
@@ -30,8 +30,8 @@
30
30
  },
31
31
  "devDependencies": {
32
32
  "@agoric/internal": "^0.3.2",
33
- "@agoric/swingset-vat": "0.32.3-dev-442f07c.0+442f07c",
34
- "@agoric/zone": "0.2.3-dev-442f07c.0+442f07c",
33
+ "@agoric/swingset-vat": "0.32.3-dev-69f8e4b.0+69f8e4b",
34
+ "@agoric/zone": "0.2.3-dev-69f8e4b.0+69f8e4b",
35
35
  "@endo/far": "^1.1.5",
36
36
  "@endo/init": "^1.1.4",
37
37
  "ava": "^5.3.0",
@@ -55,7 +55,7 @@
55
55
  "access": "public"
56
56
  },
57
57
  "typeCoverage": {
58
- "atLeast": 89.96
58
+ "atLeast": 91.85
59
59
  },
60
- "gitHead": "442f07c8f0af03281b52b90e90c27131eef6f331"
60
+ "gitHead": "69f8e4b5e04b66df5400716251e66fbce468c86e"
61
61
  }
@@ -0,0 +1,75 @@
1
+ export function prepareRetryableTools(outerZone: Zone, outerOptions: PreparationOptions): {
2
+ prepareRetryableFlowKit: (zone: Zone, tag: string, retryableFunc: RetryableFunc) => (activationArgs: any) => import("@endo/exo").GuardedKit<{
3
+ flow: {
4
+ /**
5
+ * Calls the retryable function, either for the initial run or when
6
+ * the result of the previous run fails with a retryable reason.
7
+ */
8
+ restart(): void;
9
+ getOutcome(): Vow<any>;
10
+ };
11
+ resultWatcher: {
12
+ onFulfilled(value: any, runId: any): void;
13
+ onRejected(reason: any, runId: any): void;
14
+ };
15
+ }>;
16
+ adminRetryableFlow: import("@endo/exo").Guarded<{
17
+ /**
18
+ * @param {Vow} outcomeVow
19
+ */
20
+ getFlowForOutcomeVow(outcomeVow: Vow): import("@endo/exo").Guarded<{
21
+ /**
22
+ * Calls the retryable function, either for the initial run or when
23
+ * the result of the previous run fails with a retryable reason.
24
+ */
25
+ restart(): void;
26
+ getOutcome(): Vow<any>;
27
+ }>;
28
+ }>;
29
+ retryable: import("./types.js").RetryableTool;
30
+ };
31
+ export type PreparationOptions = {
32
+ makeVowKit: () => VowKit<any>;
33
+ isRetryableReason: IsRetryableReason;
34
+ };
35
+ export type RetryableFunc = (...args: Passable[]) => Promise<any>;
36
+ export type RetryableTools = ReturnType<(outerZone: Zone, outerOptions: PreparationOptions) => {
37
+ prepareRetryableFlowKit: (zone: Zone, tag: string, retryableFunc: RetryableFunc) => (activationArgs: any) => import("@endo/exo").GuardedKit<{
38
+ flow: {
39
+ /**
40
+ * Calls the retryable function, either for the initial run or when
41
+ * the result of the previous run fails with a retryable reason.
42
+ */
43
+ restart(): void;
44
+ getOutcome(): Vow<any>;
45
+ };
46
+ resultWatcher: {
47
+ onFulfilled(value: any, runId: any): void;
48
+ onRejected(reason: any, runId: any): void;
49
+ };
50
+ }>;
51
+ adminRetryableFlow: import("@endo/exo").Guarded<{
52
+ /**
53
+ * @param {Vow} outcomeVow
54
+ */
55
+ getFlowForOutcomeVow(outcomeVow: Vow): import("@endo/exo").Guarded<{
56
+ /**
57
+ * Calls the retryable function, either for the initial run or when
58
+ * the result of the previous run fails with a retryable reason.
59
+ */
60
+ restart(): void;
61
+ getOutcome(): Vow<any>;
62
+ }>;
63
+ }>;
64
+ retryable: import("./types.js").RetryableTool;
65
+ }>;
66
+ export type AdminRetryableFlow = RetryableTools["adminRetryableFlow"];
67
+ export type MakeRetryableFlowKit = ReturnType<RetryableTools["prepareRetryableFlowKit"]>;
68
+ export type RetryableFlowKit = ReturnType<MakeRetryableFlowKit>;
69
+ export type RetryableFlow = RetryableFlowKit["flow"];
70
+ import type { Zone } from '@agoric/base-zone';
71
+ import type { Vow } from './types.js';
72
+ import type { VowKit } from './types.js';
73
+ import type { IsRetryableReason } from './types.js';
74
+ import type { Passable } from '@endo/pass-style';
75
+ //# sourceMappingURL=retryable.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retryable.d.ts","sourceRoot":"","sources":["retryable.js"],"names":[],"mappings":"AAwCO,iDAHI,IAAI,gBACJ,kBAAkB;oCAoBhB,IAAI,OACJ,MAAM,iBACN,aAAa;;YAsBhB;;;eAGG;;;;;;;;;;QAuGP;;WAEG;yCADQ,GAAG;YA3GV;;;eAGG;;;;;;EAqHZ;;gBA5La,MAAM,OAAO,GAAG,CAAC;uBACjB,iBAAiB;;4BAIlB,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,KAAK,OAAO,CAAC,GAAG,CAAC;6BA2LrC,UAAU,aAzKZ,IAAI,gBACJ,kBAAkB;oCAoBhB,IAAI,OACJ,MAAM,iBACN,aAAa;;YAsBhB;;;eAGG;;;;;;;;;;QAuGP;;WAEG;yCADQ,GAAG;YA3GV;;;eAGG;;;;;;EAyHiC;iCAIjC,cAAc,CAAC,oBAAoB,CAAC;mCAIpC,UAAU,CAAC,cAAc,CAAC,yBAAyB,CAAC,CAAC;+BAIrD,UAAU,CAAC,oBAAoB,CAAC;4BAIhC,gBAAgB,CAAC,MAAM,CAAC;0BAvNd,mBAAmB;yBACiB,YAAY;4BAAZ,YAAY;uCAAZ,YAAY;8BAC/B,kBAAkB"}
@@ -0,0 +1,224 @@
1
+ import { Fail } from '@endo/errors';
2
+ import { M } from '@endo/patterns';
3
+ import { PromiseWatcherI } from '@agoric/base-zone';
4
+ import { makeAsVow, toPassableCap, VowShape } from './vow-utils.js';
5
+
6
+ /**
7
+ * @import {MapStore, WeakMapStore} from '@agoric/store'
8
+ * @import {Zone} from '@agoric/base-zone'
9
+ * @import {Vow, VowKit, IsRetryableReason, VowTools} from './types.js'
10
+ * @import {Passable, PassableCap} from '@endo/pass-style'
11
+ */
12
+
13
+ /**
14
+ * @typedef {object} PreparationOptions
15
+ * @property {() => VowKit<any>} makeVowKit
16
+ * @property {IsRetryableReason} isRetryableReason
17
+ */
18
+
19
+ /**
20
+ * @typedef {(...args: Passable[]) => Promise<any>} RetryableFunc
21
+ */
22
+
23
+ const { defineProperties } = Object;
24
+
25
+ const RetryableFlowIKit = harden({
26
+ flow: M.interface('Flow', {
27
+ restart: M.call().returns(),
28
+ getOutcome: M.call().returns(VowShape),
29
+ }),
30
+ resultWatcher: PromiseWatcherI,
31
+ });
32
+
33
+ const AdminRetryableFlowI = M.interface('RetryableFlowAdmin', {
34
+ getFlowForOutcomeVow: M.call(VowShape).returns(M.opt(M.remotable('flow'))),
35
+ });
36
+
37
+ /**
38
+ * @param {Zone} outerZone
39
+ * @param {PreparationOptions} outerOptions
40
+ */
41
+ export const prepareRetryableTools = (outerZone, outerOptions) => {
42
+ const { makeVowKit, isRetryableReason } = outerOptions;
43
+
44
+ const asVow = makeAsVow(makeVowKit);
45
+
46
+ /**
47
+ * So we can give out wrapper functions easily and recover flow objects
48
+ * for their activations later.
49
+ */
50
+ const flowForOutcomeVowKey =
51
+ /** @type {MapStore<PassableCap, RetryableFlow>} */ (
52
+ outerZone.mapStore('retryableFlowForOutcomeVow', {
53
+ keyShape: M.remotable('toPassableCap'),
54
+ valueShape: M.remotable('flow'), // isDone === false
55
+ })
56
+ );
57
+
58
+ /**
59
+ * @param {Zone} zone
60
+ * @param {string} tag
61
+ * @param {RetryableFunc} retryableFunc
62
+ */
63
+ const prepareRetryableFlowKit = (zone, tag, retryableFunc) => {
64
+ typeof retryableFunc === 'function' ||
65
+ Fail`retryableFunc must be a callable function ${retryableFunc}`;
66
+
67
+ const internalMakeRetryableFlowKit = zone.exoClassKit(
68
+ tag,
69
+ RetryableFlowIKit,
70
+ activationArgs => {
71
+ harden(activationArgs);
72
+
73
+ return {
74
+ activationArgs, // restarting the retryable function uses the original args
75
+ outcomeKit: makeVowKit(), // outcome of activation as vow
76
+ lastRetryReason: undefined,
77
+ runs: 0n,
78
+ isDone: false, // persistently done
79
+ };
80
+ },
81
+ {
82
+ flow: {
83
+ /**
84
+ * Calls the retryable function, either for the initial run or when
85
+ * the result of the previous run fails with a retryable reason.
86
+ */
87
+ restart() {
88
+ const { state, facets } = this;
89
+ const { activationArgs, isDone } = state;
90
+ const { flow, resultWatcher } = facets;
91
+
92
+ !isDone ||
93
+ // separate line so I can set a breakpoint
94
+ Fail`Cannot restart a done retryable flow ${flow}`;
95
+
96
+ const runId = state.runs + 1n;
97
+ state.runs = runId;
98
+
99
+ let resultP;
100
+ try {
101
+ resultP = Promise.resolve(retryableFunc(...activationArgs));
102
+ } catch (err) {
103
+ resultP = Promise.reject(err);
104
+ }
105
+
106
+ outerZone.watchPromise(harden(resultP), resultWatcher, runId);
107
+ },
108
+ getOutcome() {
109
+ const { state } = this;
110
+ const { outcomeKit } = state;
111
+ return outcomeKit.vow;
112
+ },
113
+ },
114
+ resultWatcher: {
115
+ onFulfilled(value, runId) {
116
+ const { state } = this;
117
+ const { runs, outcomeKit } = state;
118
+ if (runId !== runs) return;
119
+ !state.isDone ||
120
+ Fail`Cannot resolve a done retryable flow ${this.facets.flow}`;
121
+ outcomeKit.resolver.resolve(value);
122
+ flowForOutcomeVowKey.delete(toPassableCap(outcomeKit.vow));
123
+ state.isDone = true;
124
+ },
125
+ onRejected(reason, runId) {
126
+ const { state } = this;
127
+ const { runs, outcomeKit } = state;
128
+ if (runId !== runs) return;
129
+ !state.isDone ||
130
+ Fail`Cannot reject a done retryable flow ${this.facets.flow}`;
131
+ const retryReason = isRetryableReason(
132
+ reason,
133
+ state.lastRetryReason,
134
+ );
135
+ if (retryReason) {
136
+ state.lastRetryReason = retryReason;
137
+ this.facets.flow.restart();
138
+ } else {
139
+ outcomeKit.resolver.reject(reason);
140
+ flowForOutcomeVowKey.delete(toPassableCap(outcomeKit.vow));
141
+ state.isDone = true;
142
+ }
143
+ },
144
+ },
145
+ },
146
+ );
147
+ const makeRetryableFlowKit = activationArgs => {
148
+ const retryableKit = internalMakeRetryableFlowKit(activationArgs);
149
+ const { flow } = retryableKit;
150
+
151
+ const vow = flow.getOutcome();
152
+ flowForOutcomeVowKey.init(toPassableCap(vow), flow);
153
+ flow.restart();
154
+ return retryableKit;
155
+ };
156
+ return harden(makeRetryableFlowKit);
157
+ };
158
+
159
+ /**
160
+ * @type {VowTools['retryable']}
161
+ */
162
+ const retryable = (zone, tag, retryableFunc) => {
163
+ const makeRetryableKit = prepareRetryableFlowKit(zone, tag, retryableFunc);
164
+ const wrapperFuncName = `${tag}_retryable`;
165
+
166
+ const wrapperFunc = {
167
+ /** @param {any[]} args */
168
+ [wrapperFuncName](...args) {
169
+ // Make sure any error results in a rejected vow
170
+ return asVow(() => {
171
+ zone.isStorable(harden(args)) ||
172
+ Fail`retryable arguments must be storable ${args}`;
173
+ const { flow } = makeRetryableKit(args);
174
+ return flow.getOutcome();
175
+ });
176
+ },
177
+ }[wrapperFuncName];
178
+ defineProperties(wrapperFunc, {
179
+ length: { value: retryableFunc.length },
180
+ });
181
+ // @ts-expect-error inferred generic func
182
+ return harden(wrapperFunc);
183
+ };
184
+
185
+ const adminRetryableFlow = outerZone.exo(
186
+ 'AdminRetryableFlow',
187
+ AdminRetryableFlowI,
188
+ {
189
+ /**
190
+ * @param {Vow} outcomeVow
191
+ */
192
+ getFlowForOutcomeVow(outcomeVow) {
193
+ return flowForOutcomeVowKey.get(toPassableCap(outcomeVow));
194
+ },
195
+ },
196
+ );
197
+
198
+ return harden({
199
+ prepareRetryableFlowKit,
200
+ adminRetryableFlow,
201
+ retryable,
202
+ });
203
+ };
204
+ harden(prepareRetryableTools);
205
+
206
+ /**
207
+ * @typedef {ReturnType<prepareRetryableTools>} RetryableTools
208
+ */
209
+
210
+ /**
211
+ * @typedef {RetryableTools['adminRetryableFlow']} AdminRetryableFlow
212
+ */
213
+
214
+ /**
215
+ * @typedef {ReturnType<RetryableTools['prepareRetryableFlowKit']>} MakeRetryableFlowKit
216
+ */
217
+
218
+ /**
219
+ * @typedef {ReturnType<MakeRetryableFlowKit>} RetryableFlowKit
220
+ */
221
+
222
+ /**
223
+ * @typedef {RetryableFlowKit['flow']} RetryableFlow
224
+ */
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["tools.js"],"names":[],"mappings":"AAsBO,2CALI,IAAI;;gBAGF,QAAQ,CA+EpB;0BA3FsB,mBAAmB;uCAE4B,YAAY;8BAAZ,YAAY"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["tools.js"],"names":[],"mappings":"AAuBO,2CALI,IAAI;;gBAGF,QAAQ,CAiEpB;0BA7EsB,mBAAmB;uCAE4B,YAAY;8BAAZ,YAAY"}
package/src/tools.js CHANGED
@@ -3,6 +3,7 @@ import { makeAsVow } from './vow-utils.js';
3
3
  import { prepareVowKit } from './vow.js';
4
4
  import { prepareWatchUtils } from './watch-utils.js';
5
5
  import { prepareWatch } from './watch.js';
6
+ import { prepareRetryableTools } from './retryable.js';
6
7
  import { makeWhen } from './when.js';
7
8
 
8
9
  /**
@@ -35,25 +36,10 @@ export const prepareBasicVowTools = (zone, powers = {}) => {
35
36
  const watchUtils = makeWatchUtils();
36
37
  const asVow = makeAsVow(makeVowKit);
37
38
 
38
- // FIXME in https://github.com/Agoric/agoric-sdk/pull/9785
39
- /**
40
- * @alpha Not yet implemented
41
- *
42
- * Create a function that retries the given function if the underlying
43
- * functions rejects due to upgrade disconnection.
44
- *
45
- * @template {(...args: any[]) => Promise<any>} F
46
- * @param {Zone} fnZone - the zone for the named function
47
- * @param {string} name
48
- * @param {F} fn
49
- * @returns {F extends (...args: infer Args) => Promise<infer R> ? (...args: Args) => Vow<R> : never}
50
- */
51
- const retriable =
52
- (fnZone, name, fn) =>
53
- // @ts-expect-error cast
54
- (...args) => {
55
- return watch(fn(...args));
56
- };
39
+ const { retryable } = prepareRetryableTools(zone, {
40
+ makeVowKit,
41
+ isRetryableReason,
42
+ });
57
43
 
58
44
  /**
59
45
  * Vow-tolerant implementation of Promise.all that takes an iterable of vows
@@ -95,7 +81,8 @@ export const prepareBasicVowTools = (zone, powers = {}) => {
95
81
  allSettled,
96
82
  asVow,
97
83
  asPromise,
98
- retriable,
84
+ retryable,
85
+ retriable: retryable, // For temporary backwards compat with alpha implementation
99
86
  });
100
87
  };
101
88
  harden(prepareBasicVowTools);
package/src/types.d.ts CHANGED
@@ -58,6 +58,20 @@ export type Watcher<T = any, TResult1 = T, TResult2 = never, C extends any[] = a
58
58
  * Converts a vow or promise to a promise, ensuring proper handling of ephemeral promises.
59
59
  */
60
60
  export type AsPromiseFunction<T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]> = (specimenP: ERef<T | Vow<T>>, watcher?: Watcher<T, TResult1, TResult2, C> | undefined, watcherArgs?: C | undefined) => Promise<TResult1 | TResult2>;
61
+ export interface RetryableTool {
62
+ /**
63
+ * Create a function that retries the given function if the underlying
64
+ * async function rejects due to an upgrade disconnection. The return value
65
+ * of the created function is a vow that settles to the final retry result.
66
+ *
67
+ * The retried function should be idempotent.
68
+ *
69
+ * @param fnZone the zone for the named function
70
+ * @param name base name to use in the zone
71
+ * @param fn the retried function
72
+ */
73
+ <F extends (...args: any[]) => Promise<any>>(fnZone: Zone, name: string, fn: F): F extends (...args: infer Args) => Promise<infer R> ? (...args: Args) => Vow<R> : never;
74
+ }
61
75
  export type VowTools = {
62
76
  /**
63
77
  * Vow-tolerant implementation of Promise.all that takes an iterable of vows
@@ -93,7 +107,11 @@ export type VowTools = {
93
107
  */
94
108
  asVow: <T extends unknown>(fn: (...args: any[]) => Vow<Awaited<T>> | Awaited<T> | PromiseVow<T>) => Vow<Awaited<T>>;
95
109
  makeVowKit: <T>() => VowKit<T>;
96
- retriable: <F extends (...args: any[]) => Promise<any>>(fnZone: Zone, name: string, fn: F) => F extends (...args: infer Args) => Promise<infer R> ? (...args: Args) => Vow<R> : never;
110
+ retryable: RetryableTool;
111
+ /**
112
+ * @deprecated use `retryable`
113
+ */
114
+ retriable: RetryableTool;
97
115
  watch: <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(specimenP: EVow<T>, watcher?: Watcher<T, TResult1, TResult2, C> | undefined, ...watcherArgs: C) => Vow<Exclude<TResult1, void> | Exclude<TResult2, void> extends never ? TResult1 : Exclude<TResult1, void> | Exclude<TResult2, void>>;
98
116
  /**
99
117
  * Shorten `specimenP` until we achieve a final result.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["types.ts"],"names":[],"mappings":"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"}
package/src/types.ts CHANGED
@@ -100,6 +100,27 @@ export type AsPromiseFunction<
100
100
  watcherArgs?: C | undefined,
101
101
  ) => Promise<TResult1 | TResult2>;
102
102
 
103
+ export interface RetryableTool {
104
+ /**
105
+ * Create a function that retries the given function if the underlying
106
+ * async function rejects due to an upgrade disconnection. The return value
107
+ * of the created function is a vow that settles to the final retry result.
108
+ *
109
+ * The retried function should be idempotent.
110
+ *
111
+ * @param fnZone the zone for the named function
112
+ * @param name base name to use in the zone
113
+ * @param fn the retried function
114
+ */
115
+ <F extends (...args: any[]) => Promise<any>>(
116
+ fnZone: Zone,
117
+ name: string,
118
+ fn: F,
119
+ ): F extends (...args: infer Args) => Promise<infer R>
120
+ ? (...args: Args) => Vow<R>
121
+ : never;
122
+ }
123
+
103
124
  export type VowTools = {
104
125
  /**
105
126
  * Vow-tolerant implementation of Promise.all that takes an iterable of vows
@@ -142,13 +163,11 @@ export type VowTools = {
142
163
  fn: (...args: any[]) => Vow<Awaited<T>> | Awaited<T> | PromiseVow<T>,
143
164
  ) => Vow<Awaited<T>>;
144
165
  makeVowKit: <T>() => VowKit<T>;
145
- retriable: <F extends (...args: any[]) => Promise<any>>(
146
- fnZone: Zone,
147
- name: string,
148
- fn: F,
149
- ) => F extends (...args: infer Args) => Promise<infer R>
150
- ? (...args: Args) => Vow<R>
151
- : never;
166
+ retryable: RetryableTool;
167
+ /**
168
+ * @deprecated use `retryable`
169
+ */
170
+ retriable: RetryableTool;
152
171
  watch: <T = any, TResult1 = T, TResult2 = never, C extends any[] = any[]>(
153
172
  specimenP: EVow<T>,
154
173
  watcher?: Watcher<T, TResult1, TResult2, C> | undefined,
package/src/vow-utils.js CHANGED
@@ -29,7 +29,7 @@ harden(isVow);
29
29
  /**
30
30
  * A vow is a passable tagged as 'Vow'. Its payload is a record with
31
31
  * API-versioned remotables. payload.vowV0 is the API for the `watch` and
32
- * `when` operators to use for retriable shortening of the vow chain.
32
+ * `when` operators to use for retryable shortening of the vow chain.
33
33
  *
34
34
  * If the specimen is a Vow, return its payload, otherwise undefined.
35
35
  *
package/vat.js CHANGED
@@ -5,7 +5,10 @@
5
5
 
6
6
  /* global globalThis */
7
7
  // @ts-check
8
- import { isUpgradeDisconnection } from '@agoric/internal/src/upgrade-api.js';
8
+ import {
9
+ isUpgradeDisconnection,
10
+ isAbandonedError,
11
+ } from '@agoric/internal/src/upgrade-api.js';
9
12
  import { makeHeapZone } from '@agoric/base-zone/heap.js';
10
13
 
11
14
  import { prepareBasicVowTools } from './src/tools.js';
@@ -15,11 +18,16 @@ import makeE from './src/E.js';
15
18
  const isRetryableReason = (reason, priorRetryValue) => {
16
19
  if (
17
20
  isUpgradeDisconnection(reason) &&
18
- (!priorRetryValue ||
21
+ (!isUpgradeDisconnection(priorRetryValue) ||
19
22
  reason.incarnationNumber > priorRetryValue.incarnationNumber)
20
23
  ) {
21
24
  return reason;
22
25
  }
26
+ // For abandoned errors there is no way to differentiate errors from
27
+ // consecutive upgrades
28
+ if (isAbandonedError(reason) && !isAbandonedError(priorRetryValue)) {
29
+ return reason;
30
+ }
23
31
  return undefined;
24
32
  };
25
33