Skip to content

Commit 843848e

Browse files
committed
fix(Account): Use async lock for loading accounts
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
1 parent b7cba58 commit 843848e

File tree

2 files changed

+81
-35
lines changed

2 files changed

+81
-35
lines changed

src/lib/Account.ts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ AdapterFactory.register('fake', async() => (await import('./adapters/Fake')).def
3838
const LOCK_TIMEOUT = 1000 * 60 * 60 * 2
3939

4040
const dataLock = new AsyncLock()
41+
const accountLock = new AsyncLock()
4142

4243
export default class Account {
4344
static cache = {}
@@ -56,13 +57,15 @@ export default class Account {
5657
}
5758

5859
static async get(id:string):Promise<Account> {
59-
if (this.cache[id]) {
60-
await this.cache[id].updateFromStorage()
61-
return this.cache[id]
62-
}
63-
const account = await (await this.getAccountClass()).get(id)
64-
this.cache[id] = account
65-
return account
60+
return accountLock.acquire(id, async() => {
61+
if (this.cache[id]) {
62+
await this.cache[id].updateFromStorage()
63+
return this.cache[id]
64+
}
65+
const account = await (await this.getAccountClass()).get(id)
66+
this.cache[id] = account
67+
return account
68+
})
6669
}
6770

6871
static async create(data: IAccountData):Promise<Account> {

src/lib/native/NativeAccount.ts

Lines changed: 71 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default class NativeAccount extends Account {
2929
return new NativeAccount(id, storage, await AdapterFactory.factory(data), tree)
3030
}
3131

32-
static async create(data: IAccountData):Promise<Account> {
32+
static async create(data: IAccountData): Promise<Account> {
3333
const id = '' + Date.now() + Math.random()
3434
const adapter = await AdapterFactory.factory(data)
3535
const storage = new NativeAccountStorage(id)
@@ -44,7 +44,7 @@ export default class NativeAccount extends Account {
4444
return new NativeAccount(id, storage, adapter, tree)
4545
}
4646

47-
async init():Promise<void> {
47+
async init(): Promise<void> {
4848
console.log('initializing account ' + this.id)
4949
await this.storage.initMappings()
5050
await this.storage.initCache()
@@ -53,80 +53,123 @@ export default class NativeAccount extends Account {
5353
this.localTree = nativeTree
5454
}
5555

56-
async isInitialized():Promise<boolean> {
56+
async isInitialized(): Promise<boolean> {
5757
try {
58-
return Boolean(NativeAccountStorage.getEntry(`bookmarks[${this.storage.accountId}].mappings`))
58+
return Boolean(
59+
NativeAccountStorage.getEntry(
60+
`bookmarks[${this.storage.accountId}].mappings`
61+
)
62+
)
5963
} catch (e) {
6064
console.log('Apparently not initialized, because:', e)
6165
return false
6266
}
6367
}
6468

65-
async updateFromStorage():Promise<void> {
69+
async updateFromStorage(): Promise<void> {
6670
// empty
6771
}
6872

69-
static async stringifyError(er:any):Promise<string> {
73+
static async stringifyError(er: any): Promise<string> {
7074
if (er instanceof UnknownFolderItemOrderError) {
71-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.item])
75+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
76+
er.item,
77+
])
7278
}
7379
if (er instanceof MissingItemOrderError) {
74-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.item])
80+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
81+
er.item,
82+
])
7583
}
7684
if (er instanceof HttpError) {
77-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.status, er.method, er.statusMessage])
85+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
86+
er.status,
87+
er.method,
88+
er.statusMessage,
89+
])
7890
}
7991
if (er instanceof ParseResponseError) {
80-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0')) + '\n' + er.response
92+
return (
93+
i18n.getMessage('Error' + String(er.code).padStart(3, '0')) +
94+
'\n' +
95+
er.response
96+
)
8197
}
8298
if (er instanceof InconsistentBookmarksExistenceError) {
83-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.folder, er.bookmark])
99+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
100+
er.folder,
101+
er.bookmark,
102+
])
84103
}
85104
if (er instanceof LockFileError) {
86-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.status, er.lockFile])
105+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
106+
er.status,
107+
er.lockFile,
108+
])
87109
}
88110
if (er instanceof ServersideDeletionFailsafeError) {
89-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.percent])
111+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
112+
er.percent,
113+
])
90114
}
91115
if (er instanceof ServersideAdditionFailsafeError) {
92-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.percent])
116+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
117+
er.percent,
118+
])
93119
}
94120
if (er instanceof ClientsideDeletionFailsafeError) {
95-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.percent])
121+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
122+
er.percent,
123+
])
96124
}
97125
if (er instanceof ClientsideAdditionFailsafeError) {
98-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.percent])
126+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
127+
er.percent,
128+
])
99129
}
100130
if (er instanceof CreateBookmarkError) {
101-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.bookmark.inspect()])
131+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
132+
er.bookmark.inspect(),
133+
])
102134
}
103135
if (er instanceof UpdateBookmarkError) {
104-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.bookmark.inspect()])
136+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
137+
er.bookmark.inspect(),
138+
])
105139
}
106140
if (er instanceof GitPushError) {
107-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.errorMessage])
141+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
142+
er.errorMessage,
143+
])
108144
}
109145
if (er instanceof UnexpectedFolderPathError) {
110-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.originalPath, er.newPath])
146+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
147+
er.originalPath,
148+
er.newPath,
149+
])
111150
}
112151
if (er instanceof InvalidUrlError) {
113-
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [er.url])
152+
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'), [
153+
er.url,
154+
])
114155
}
115156
if (er instanceof FloccusError) {
116157
return i18n.getMessage('Error' + String(er.code).padStart(3, '0'))
117158
}
118159
if (er.list) {
119-
return (await Promise.all(er.list
120-
.map((e) => {
121-
Logger.log(e)
122-
return this.stringifyError(e)
123-
})))
124-
.join('\n')
160+
return (
161+
await Promise.all(
162+
er.list.map((e) => {
163+
Logger.log(e)
164+
return this.stringifyError(e)
165+
})
166+
)
167+
).join('\n')
125168
}
126169
return er.message
127170
}
128171

129-
static async getAllAccounts():Promise<Account[]> {
172+
static async getAllAccounts(): Promise<Account[]> {
130173
return Promise.all(
131174
(await NativeAccountStorage.getAllAccounts()).map((accountId) =>
132175
Account.get(accountId)

0 commit comments

Comments
 (0)