Skip to content

Commit

Permalink
Change CacheMode enum value names
Browse files Browse the repository at this point in the history
Change CacheMode.Cache to CacheMode.ReadAndWrite, and CacheMode.Bypass
to CacheMode.WriteOnly.

All three values use the cache, so having one value be called 'Cache'
and another 'Bypass' might lead to the wrong idea of what these fields
actually do in the future, since we now have the new CacheMode.ReadOnly
mode.

Co-authored-by: BijinDev <BijinDev@users.noreply.github.com>
  • Loading branch information
2 people authored and charlag committed Dec 5, 2024
1 parent 2110277 commit f4e889f
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/common/api/main/LoginController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ export class LoginController {
return this.customizations != null ? this.customizations.indexOf(feature) !== -1 : false
}

async loadCustomizations(cacheMode: CacheMode = CacheMode.Cache): Promise<void> {
async loadCustomizations(cacheMode: CacheMode = CacheMode.ReadAndWrite): Promise<void> {
if (this.getUserController().isInternalUser()) {
const customer = await this.getUserController().loadCustomer(cacheMode)
this.customizations = customer.customizations.map((f) => f.feature)
Expand Down
2 changes: 1 addition & 1 deletion src/common/api/main/UserController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ export class UserController {
return isInternalUser(this.user)
}

loadCustomer(cacheMode: CacheMode = CacheMode.Cache): Promise<Customer> {
loadCustomer(cacheMode: CacheMode = CacheMode.ReadAndWrite): Promise<Customer> {
return this.entityClient.load(CustomerTypeRef, assertNotNull(this.user.customer), { cacheMode })
}

Expand Down
2 changes: 1 addition & 1 deletion src/common/api/worker/rest/DefaultEntityRestCache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -747,7 +747,7 @@ export class DefaultEntityRestCache implements EntityRestCache {

try {
// loadMultiple is only called to cache the elements and check which ones return errors
const returnedInstances = await this._loadMultiple(typeRef, instanceListId, idsInCacheRange, undefined, { cacheMode: CacheMode.Bypass })
const returnedInstances = await this._loadMultiple(typeRef, instanceListId, idsInCacheRange, undefined, { cacheMode: CacheMode.WriteOnly })
//We do not want to pass updates that caused an error
if (returnedInstances.length !== idsInCacheRange.length) {
const returnedIds = returnedInstances.map((instance) => getElementId(instance))
Expand Down
24 changes: 13 additions & 11 deletions src/common/api/worker/rest/EntityRestClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,27 +54,29 @@ export interface EntityRestClientUpdateOptions {
* Use {@link getCacheModeBehavior} to programmatically check the behavior of the cache mode.
*/
export const enum CacheMode {
/** Prefer cached value if it's there or fall back to network. */
Cache,
/** Prefer cached value if it's there, or fall back to network and write it to cache. */
ReadAndWrite,

/**
* Prefer the value from network, do not fetch from cache. The entity will still be cached upon loading.
* Always retrieve from the network, but still save to cache.
*
* NOTE: This cannot be used for ranged requests.
* NOTE: This cannot be used with ranged requests.
*/
Bypass,
/** Prefer cached value, but in case of a cache miss, retrieve the value from network but don't write it to cache. */
WriteOnly,

/** Prefer cached value, but in case of a cache miss, retrieve the value from network without writing it to cache. */
ReadOnly,
}

/**
* Get the behavior of the cache mode for the options
* @param cacheMode cache mode to check, or if `undefined`, check the default cache mode ({@link CacheMode.Cache})
* @param cacheMode cache mode to check, or if `undefined`, check the default cache mode ({@link CacheMode.ReadAndWrite})
*/
export function getCacheModeBehavior(cacheMode: CacheMode | undefined): { readsFromCache: boolean; writesToCache: boolean } {
switch (cacheMode ?? CacheMode.Cache) {
case CacheMode.Cache:
switch (cacheMode ?? CacheMode.ReadAndWrite) {
case CacheMode.ReadAndWrite:
return { readsFromCache: true, writesToCache: true }
case CacheMode.Bypass:
case CacheMode.WriteOnly:
return { readsFromCache: false, writesToCache: true }
case CacheMode.ReadOnly:
return { readsFromCache: true, writesToCache: false }
Expand All @@ -86,7 +88,7 @@ export interface EntityRestClientLoadOptions {
extraHeaders?: Dict
/** Use the key provided by this to decrypt the existing ownerEncSessionKey instead of trying to resolve the owner key based on the ownerGroup. */
ownerKeyProvider?: OwnerKeyProvider
/** Defaults to {@link CacheMode.Cache }*/
/** Defaults to {@link CacheMode.ReadAndWrite }*/
cacheMode?: CacheMode
}

Expand Down
4 changes: 2 additions & 2 deletions src/mail-app/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ import("./translations/en.js")

// We might have outdated Customer features, force reload the customer to make sure the customizations are up-to-date
if (isOfflineStorageAvailable()) {
await mailLocator.logins.loadCustomizations(CacheMode.Bypass)
await mailLocator.logins.loadCustomizations(CacheMode.WriteOnly)
m.redraw()
}

Expand All @@ -151,7 +151,7 @@ import("./translations/en.js")
const reloadTutanotaProperties = await mailLocator.entityClient.loadRoot(
TutanotaPropertiesTypeRef,
mailLocator.logins.getUserController().user.userGroup.group,
{ cacheMode: CacheMode.Bypass },
{ cacheMode: CacheMode.WriteOnly },
)

if (!reloadTutanotaProperties.defaultLabelCreated) {
Expand Down
2 changes: 1 addition & 1 deletion src/mail-app/mail/view/MailViewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ export class MailViewModel {

let mail: Mail | null
try {
mail = await this.entityClient.load(MailTypeRef, [listId, mailId], { cacheMode: CacheMode.Bypass })
mail = await this.entityClient.load(MailTypeRef, [listId, mailId], { cacheMode: CacheMode.WriteOnly })
} catch (e) {
if (isOfflineError(e)) {
return
Expand Down
28 changes: 16 additions & 12 deletions test/tests/api/worker/rest/EntityRestCacheTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1729,22 +1729,22 @@ export function testEntityRestCache(name: string, getStorage: (userId: Id) => Pr
when(client.load(ContactTypeRef, contactId, anything())).thenResolve(contactOnTheServer)
const cache = new DefaultEntityRestCache(client, storage)

const cacheBypassed1 = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.Bypass })
const cacheBypassed1 = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.WriteOnly })
o(cacheBypassed1).deepEquals(contactOnTheServer)
// Fresh cache; should be loaded remotely and cached
verify(client.load(ContactTypeRef, contactId, anything()), { times: 1 })

const cacheBypassed2 = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.Bypass })
const cacheBypassed2 = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.WriteOnly })
o(cacheBypassed2).deepEquals(contactOnTheServer)
// Since we're bypassing it, it should still be loaded remotely (but still cached)
verify(client.load(ContactTypeRef, contactId, anything()), { times: 2 })

const cached = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.Cache })
const cached = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.ReadAndWrite })
o(cached).deepEquals(contactOnTheServer)
// We aren't bypassing it with Cache, so it should just use the cache
verify(client.load(ContactTypeRef, contactId, anything()), { times: 2 })

const cacheBypassed3 = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.Bypass })
const cacheBypassed3 = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.WriteOnly })
o(cacheBypassed3).deepEquals(contactOnTheServer)
// Bypassing again; should be loaded remotely
verify(client.load(ContactTypeRef, contactId, anything()), { times: 3 })
Expand Down Expand Up @@ -1773,18 +1773,22 @@ export function testEntityRestCache(name: string, getStorage: (userId: Id) => Pr

const cache = new DefaultEntityRestCache(client, storage)

const cacheBypassed1 = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, { cacheMode: CacheMode.Bypass })
const cacheBypassed1 = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, {
cacheMode: CacheMode.WriteOnly,
})
o(cacheBypassed1).deepEquals([contactAOnTheServer])
// Fresh cache; should be loaded remotely and cached
verify(client.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, anything()), { times: 1 })

const cacheBypassed2 = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, { cacheMode: CacheMode.Bypass })
const cacheBypassed2 = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, {
cacheMode: CacheMode.WriteOnly,
})
o(cacheBypassed2).deepEquals([contactAOnTheServer])
// Still bypassing
verify(client.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, anything()), { times: 2 })

const cached = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId), elementIdPart(contactBId)], undefined, {
cacheMode: CacheMode.Cache,
cacheMode: CacheMode.ReadAndWrite,
})
o(true).equals(cached.some((a) => deepEqual(a, contactAOnTheServer)))
o(true).equals(cached.some((b) => deepEqual(b, contactBOnTheServer)))
Expand All @@ -1793,7 +1797,7 @@ export function testEntityRestCache(name: string, getStorage: (userId: Id) => Pr
verify(client.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactBId)], undefined, anything()), { times: 1 })

const cacheBypassed3 = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId), elementIdPart(contactBId)], undefined, {
cacheMode: CacheMode.Bypass,
cacheMode: CacheMode.WriteOnly,
})
o(cacheBypassed3).deepEquals([contactAOnTheServer, contactBOnTheServer])
// Bypassed again
Expand Down Expand Up @@ -1825,7 +1829,7 @@ export function testEntityRestCache(name: string, getStorage: (userId: Id) => Pr
// It wasn't cached before, so it should be loaded remotely again
verify(client.load(ContactTypeRef, contactId, anything()), { times: 2 })

const cached = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.Cache })
const cached = await cache.load(ContactTypeRef, contactId, { cacheMode: CacheMode.ReadAndWrite })
o(cached).deepEquals(contactOnTheServer)
// Again, it wasn't cached before, so it should be loaded remotely again
verify(client.load(ContactTypeRef, contactId, anything()), { times: 3 })
Expand Down Expand Up @@ -1862,7 +1866,7 @@ export function testEntityRestCache(name: string, getStorage: (userId: Id) => Pr
// Fresh cache; should be loaded remotely and cached
verify(client.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, anything()), { times: 1 })

const cached = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, { cacheMode: CacheMode.Cache })
const cached = await cache.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, { cacheMode: CacheMode.ReadAndWrite })
o(cached).deepEquals([contactAOnTheServer])
// Wasn't written earlier; should be written now
verify(client.loadMultiple(ContactTypeRef, listId, [elementIdPart(contactAId)], undefined, anything()), { times: 2 })
Expand Down Expand Up @@ -1899,7 +1903,7 @@ export function testEntityRestCache(name: string, getStorage: (userId: Id) => Pr
// Fresh cache; should be loaded remotely and cached
verify(client.loadRange(ContactTypeRef, listId, createId("0"), 2, false, anything()), { times: 1 })

const cached = await cache.loadRange(ContactTypeRef, listId, createId("0"), 2, false, { cacheMode: CacheMode.Cache })
const cached = await cache.loadRange(ContactTypeRef, listId, createId("0"), 2, false, { cacheMode: CacheMode.ReadAndWrite })
o(cached).deepEquals([contactAOnTheServer, contactBOnTheServer])
// Wasn't saved before
verify(client.loadRange(ContactTypeRef, listId, createId("0"), 2, false, anything()), { times: 2 })
Expand Down Expand Up @@ -1936,7 +1940,7 @@ export function testEntityRestCache(name: string, getStorage: (userId: Id) => Pr
// Fresh cache
verify(client.loadRange(ContactTypeRef, listId, createId("1"), 2, false, anything()), { times: 1 })

const cached = await cache.loadRange(ContactTypeRef, listId, createId("1"), 2, false, { cacheMode: CacheMode.Cache })
const cached = await cache.loadRange(ContactTypeRef, listId, createId("1"), 2, false, { cacheMode: CacheMode.ReadAndWrite })
o(cached).deepEquals([contactBOnTheServer])
// Was saved before now
verify(client.loadRange(ContactTypeRef, listId, createId("1"), 2, false, anything()), { times: 2 })
Expand Down

0 comments on commit f4e889f

Please sign in to comment.