|
1 | 1 | import { keyPath, StatelyError, WithPutOptions } from '@stately-cloud/client'; |
2 | 2 | import { Loadout } from '../shapes/loadouts.js'; |
| 3 | +import { delay } from '../utils.js'; |
3 | 4 | import { client } from './client.js'; |
4 | 5 | import { LoadoutShare as StatelyLoadoutShare } from './generated/index.js'; |
5 | 6 | import { |
@@ -82,18 +83,30 @@ export async function addLoadoutSharesForMigration( |
82 | 83 | * Touch the last_accessed_at and visits fields to keep track of access. |
83 | 84 | */ |
84 | 85 | export async function recordAccess(shareId: string): Promise<void> { |
85 | | - // Hmm this is probably pretty expensive. Should I store the view count in a |
86 | | - // separate item? It'd also be nice to have an Update API. |
87 | | - await client.transaction(async (txn) => { |
88 | | - const loadoutShare = await txn.get('LoadoutShare', keyFor(shareId)); |
89 | | - if (!loadoutShare) { |
90 | | - throw new Error("somehow this loadout share doesn't exist"); |
91 | | - } |
| 86 | + for (let attempts = 0; attempts < 3; attempts++) { |
| 87 | + try { |
| 88 | + // Hmm this is probably pretty expensive. Should I store the view count in a |
| 89 | + // separate item? It'd also be nice to have an Update API. |
| 90 | + await client.transaction(async (txn) => { |
| 91 | + const loadoutShare = await txn.get('LoadoutShare', keyFor(shareId)); |
| 92 | + if (!loadoutShare) { |
| 93 | + throw new Error("somehow this loadout share doesn't exist"); |
| 94 | + } |
92 | 95 |
|
93 | | - loadoutShare.viewCount++; |
| 96 | + loadoutShare.viewCount++; |
94 | 97 |
|
95 | | - await txn.put(loadoutShare); |
96 | | - }); |
| 98 | + await txn.put(loadoutShare); |
| 99 | + }); |
| 100 | + return; |
| 101 | + } catch (e) { |
| 102 | + if (e instanceof StatelyError && e.statelyCode === 'ConcurrentModification') { |
| 103 | + // try again after a delay |
| 104 | + await delay(100 * Math.random() + 100); |
| 105 | + } else { |
| 106 | + throw e; |
| 107 | + } |
| 108 | + } |
| 109 | + } |
97 | 110 | } |
98 | 111 |
|
99 | 112 | export async function getLoadoutShareByShareId(shareId: string): Promise<Loadout | undefined> { |
|
0 commit comments